QskProgressBar improved

This commit is contained in:
Uwe Rathmann 2020-08-03 08:02:13 +02:00
parent cb359328b4
commit 95d3c6e37b
6 changed files with 67 additions and 38 deletions

View File

@ -246,7 +246,7 @@ void QskMaterialSkin::initProgressBarHints()
setGradient( Q::Groove, Qt::white );
setMetric( Q::Groove | Size, 10 );
setGradient( Q::ValueFill, pal.accentColor );
setGradient( Q::Bar, pal.accentColor );
}
void QskMaterialSkin::initFocusIndicatorHints()

View File

@ -392,7 +392,7 @@ void QskSquiekSkin::initProgressBarHints()
setGradient( Q::Groove, Qt::white );
setMetric( Q::Groove | Size, 10 );
setGradient( Q::ValueFill, pal.highlighted );
setGradient( Q::Bar, pal.highlighted );
}
void QskSquiekSkin::initFocusIndicatorHints()

View File

@ -11,7 +11,7 @@
#include "QskAspect.h"
QSK_SUBCONTROL( QskProgressBar, Groove )
QSK_SUBCONTROL( QskProgressBar, ValueFill )
QSK_SUBCONTROL( QskProgressBar, Bar )
class QskProgressBar::PrivateData
{
@ -90,14 +90,30 @@ QskAspect::Placement QskProgressBar::effectivePlacement() const
return static_cast< QskAspect::Placement >( m_data->orientation );
}
void QskProgressBar::setFillGradient( const QskGradient& gradient )
void QskProgressBar::setBarGradient( const QskGradient& gradient )
{
setGradientHint( QskProgressBar::ValueFill, gradient );
// An API where we set the stops only would be more accurate TODO ...
auto g = gradient;
g.setOrientation( Qt::Horizontal );
setGradientHint( QskProgressBar::Bar | QskAspect::Horizontal, g );
g.setOrientation( Qt::Vertical );
setGradientHint( QskProgressBar::Bar | QskAspect::Vertical, g );
}
QskGradient QskProgressBar::fillGradient() const
void QskProgressBar::resetBarGradient()
{
return gradientHint( QskProgressBar::ValueFill );
using namespace QskAspect;
const auto aspect = QskProgressBar::Bar | Color;
if ( resetHint( aspect | Vertical ) || resetHint( aspect | Horizontal ) )
update();
}
QskGradient QskProgressBar::barGradient() const
{
return gradientHint( QskProgressBar::Bar );
}
void QskProgressBar::setThickness( qreal thickness )

View File

@ -27,7 +27,7 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
using Inherited = QskBoundedControl;
public:
QSK_SUBCONTROLS( Groove, ValueFill )
QSK_SUBCONTROLS( Groove, Bar )
QskProgressBar( Qt::Orientation, QQuickItem* parent = nullptr );
QskProgressBar( Qt::Orientation, qreal min, qreal max, QQuickItem* parent = nullptr );
@ -42,8 +42,9 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
QskAspect::Placement effectivePlacement() const override;
void setFillGradient( const QskGradient& );
QskGradient fillGradient() const;
void setBarGradient( const QskGradient & );
void resetBarGradient();
QskGradient barGradient() const;
void setThickness( qreal );
qreal thickness() const;

View File

@ -5,13 +5,34 @@
#include "QskProgressBarSkinlet.h"
#include "QskProgressBar.h"
#include "QskIntervalF.h"
#include <cmath>
static inline QskIntervalF qskBarInterval( const QskProgressBar* bar )
{
auto pos1 = bar->valueAsRatio( bar->origin() );
auto pos2 = bar->valueAsRatio( bar->value() );
if( bar->orientation() == Qt::Horizontal )
{
if ( bar->layoutMirroring() )
{
pos1 = 1.0 - pos1;
pos2 = 1.0 - pos2;
}
}
if ( pos1 > pos2 )
std::swap( pos1, pos2 );
return QskIntervalF( pos1, pos2 );
}
QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin )
: QskSkinlet( skin )
{
setNodeRoles( { GrooveRole, ValueFillRole } );
setNodeRoles( { GrooveRole, BarRole } );
}
QskProgressBarSkinlet::~QskProgressBarSkinlet()
@ -43,10 +64,10 @@ QRectF QskProgressBarSkinlet::subControlRect(
return rect;
}
if( subControl == QskProgressBar::ValueFill )
if( subControl == QskProgressBar::Bar )
{
const auto bar = static_cast< const QskProgressBar* >( skinnable );
return fillRect( bar );
return barRect( bar );
}
return Inherited::subControlRect( skinnable, contentsRect, subControl );
@ -62,20 +83,20 @@ QSGNode* QskProgressBarSkinlet::updateSubNode(
return updateBoxNode( skinnable, node, QskProgressBar::Groove );
}
case ValueFillRole:
case BarRole:
{
const auto bar = static_cast< const QskProgressBar* >( skinnable );
return updateFillNode( bar, node );
return updateBarNode( bar, node );
}
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
QSGNode* QskProgressBarSkinlet::updateFillNode(
QSGNode* QskProgressBarSkinlet::updateBarNode(
const QskProgressBar* bar, QSGNode* node ) const
{
const auto subControl = QskProgressBar::ValueFill;
const auto subControl = QskProgressBar::Bar;
const auto rect = bar->subControlRect( subControl );
if ( rect.isEmpty() )
@ -89,45 +110,36 @@ QSGNode* QskProgressBarSkinlet::updateFillNode(
if ( !gradient.isMonochrome() )
{
qreal pos1 = bar->valueAsRatio( bar->origin() );
qreal pos2 = bar->valueAsRatio( bar->value() );
const auto intv = qskBarInterval( bar );
gradient = gradient.extracted( intv.lowerBound(), intv.upperBound() );
if ( pos2 < pos1 )
std::swap( pos1, pos2 );
gradient = gradient.extracted( pos1, pos2 );
if ( bar->orientation() == Qt::Vertical )
if ( bar->orientation() == Qt::Vertical || bar->layoutMirroring() )
gradient.reverse();
}
return updateBoxNode( bar, node, rect, gradient, subControl );
}
QRectF QskProgressBarSkinlet::fillRect( const QskProgressBar* bar ) const
QRectF QskProgressBarSkinlet::barRect( const QskProgressBar* bar ) const
{
auto rect = bar->subControlRect( QskProgressBar::Groove );
rect = bar->innerBox( QskProgressBar::Groove, rect );
auto pos1 = bar->valueAsRatio( bar->origin() );
auto pos2 = bar->valueAsRatio( bar->value() );
if ( pos1 > pos2 )
std::swap( pos1, pos2 );
const auto intv = qskBarInterval( bar );
if( bar->orientation() == Qt::Horizontal )
{
const auto w = rect.width();
rect.setRight( rect.left() + pos2 * w );
rect.setLeft( rect.left() + pos1 * w );
rect.setRight( rect.left() + intv.upperBound() * w );
rect.setLeft( rect.left() + intv.lowerBound() * w );
}
else
{
const auto h = rect.height();
rect.setTop( rect.bottom() - h * pos2 );
rect.setBottom( rect.bottom() - h * pos1 );
rect.setTop( rect.bottom() - h * intv.upperBound() );
rect.setBottom( rect.bottom() - h * intv.lowerBound() );
}
return rect;

View File

@ -20,7 +20,7 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet
enum NodeRole
{
GrooveRole,
ValueFillRole,
BarRole,
RoleCount,
};
@ -36,8 +36,8 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet
quint8 nodeRole, QSGNode* ) const override;
private:
QSGNode* updateFillNode( const QskProgressBar*, QSGNode* ) const;
QRectF fillRect( const QskProgressBar* ) const;
QSGNode* updateBarNode( const QskProgressBar*, QSGNode* ) const;
QRectF barRect( const QskProgressBar* ) const;
};
#endif