From 95d3c6e37bb91ac5ac2726b7b7b8d155bdd0cf5a Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 3 Aug 2020 08:02:13 +0200 Subject: [PATCH] QskProgressBar improved --- skins/material/QskMaterialSkin.cpp | 2 +- skins/squiek/QskSquiekSkin.cpp | 2 +- src/controls/QskProgressBar.cpp | 26 ++++++++--- src/controls/QskProgressBar.h | 7 +-- src/controls/QskProgressBarSkinlet.cpp | 62 +++++++++++++++----------- src/controls/QskProgressBarSkinlet.h | 6 +-- 6 files changed, 67 insertions(+), 38 deletions(-) diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 4f83d50e..02452e10 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -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() diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index d160bd1e..ca764615 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -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() diff --git a/src/controls/QskProgressBar.cpp b/src/controls/QskProgressBar.cpp index aeb8d04e..638bf5e6 100644 --- a/src/controls/QskProgressBar.cpp +++ b/src/controls/QskProgressBar.cpp @@ -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 ) diff --git a/src/controls/QskProgressBar.h b/src/controls/QskProgressBar.h index 2f9a2414..5df98e58 100644 --- a/src/controls/QskProgressBar.h +++ b/src/controls/QskProgressBar.h @@ -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; diff --git a/src/controls/QskProgressBarSkinlet.cpp b/src/controls/QskProgressBarSkinlet.cpp index e2cb5c86..3d87ee03 100644 --- a/src/controls/QskProgressBarSkinlet.cpp +++ b/src/controls/QskProgressBarSkinlet.cpp @@ -5,13 +5,34 @@ #include "QskProgressBarSkinlet.h" #include "QskProgressBar.h" +#include "QskIntervalF.h" #include +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; diff --git a/src/controls/QskProgressBarSkinlet.h b/src/controls/QskProgressBarSkinlet.h index c8fbd837..c1cb760b 100644 --- a/src/controls/QskProgressBarSkinlet.h +++ b/src/controls/QskProgressBarSkinlet.h @@ -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