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 ); setGradient( Q::Groove, Qt::white );
setMetric( Q::Groove | Size, 10 ); setMetric( Q::Groove | Size, 10 );
setGradient( Q::ValueFill, pal.accentColor ); setGradient( Q::Bar, pal.accentColor );
} }
void QskMaterialSkin::initFocusIndicatorHints() void QskMaterialSkin::initFocusIndicatorHints()

View File

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

View File

@ -11,7 +11,7 @@
#include "QskAspect.h" #include "QskAspect.h"
QSK_SUBCONTROL( QskProgressBar, Groove ) QSK_SUBCONTROL( QskProgressBar, Groove )
QSK_SUBCONTROL( QskProgressBar, ValueFill ) QSK_SUBCONTROL( QskProgressBar, Bar )
class QskProgressBar::PrivateData class QskProgressBar::PrivateData
{ {
@ -90,14 +90,30 @@ QskAspect::Placement QskProgressBar::effectivePlacement() const
return static_cast< QskAspect::Placement >( m_data->orientation ); 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 ) void QskProgressBar::setThickness( qreal thickness )

View File

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

View File

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

View File

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