From 86942d4226952fe0b582c81148bd355033b4b13a Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 4 Sep 2024 17:08:40 +0200 Subject: [PATCH] code duplication eliminated --- examples/iotdashboard/CircularProgressBar.h | 6 +- .../CircularProgressBarSkinlet.cpp | 29 +------ .../iotdashboard/CircularProgressBarSkinlet.h | 19 +---- examples/iotdashboard/Skin.cpp | 11 ++- src/controls/QskProgressBarSkinlet.cpp | 15 ++-- src/controls/QskProgressRingSkinlet.cpp | 82 +++++++++---------- src/controls/QskProgressRingSkinlet.h | 4 +- 7 files changed, 63 insertions(+), 103 deletions(-) diff --git a/examples/iotdashboard/CircularProgressBar.h b/examples/iotdashboard/CircularProgressBar.h index 67359722..810a18e5 100644 --- a/examples/iotdashboard/CircularProgressBar.h +++ b/examples/iotdashboard/CircularProgressBar.h @@ -5,13 +5,13 @@ #pragma once -#include +#include -class CircularProgressBar : public QskProgressIndicator +class CircularProgressBar : public QskProgressRing { Q_OBJECT - using Inherited = QskProgressIndicator; + using Inherited = QskProgressRing; public: CircularProgressBar( qreal min, qreal max, QQuickItem* parent = nullptr ); diff --git a/examples/iotdashboard/CircularProgressBarSkinlet.cpp b/examples/iotdashboard/CircularProgressBarSkinlet.cpp index 8b9f7a5c..4f8eafe0 100644 --- a/examples/iotdashboard/CircularProgressBarSkinlet.cpp +++ b/examples/iotdashboard/CircularProgressBarSkinlet.cpp @@ -4,12 +4,11 @@ *****************************************************************************/ #include "CircularProgressBarSkinlet.h" -#include "CircularProgressBar.h" +#include CircularProgressBarSkinlet::CircularProgressBarSkinlet( QskSkin* skin ) - : QskSkinlet( skin ) + : Inherited( skin ) { - setNodeRoles( { GrooveRole, BarRole } ); } CircularProgressBarSkinlet::~CircularProgressBarSkinlet() @@ -22,28 +21,4 @@ QRectF CircularProgressBarSkinlet::subControlRect( return contentsRect; } -QSGNode* CircularProgressBarSkinlet::updateSubNode( - const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const -{ - switch( nodeRole ) - { - case GrooveRole: - { - return updateArcNode( skinnable, node, CircularProgressBar::Groove ); - } - case BarRole: - { - const auto bar = static_cast< const CircularProgressBar* >( skinnable ); - - const qreal startAngle = 90.0; - const qreal spanAngle = 360.0 * bar->valueAsRatio(); - - return updateArcNode( skinnable, node, startAngle, -spanAngle, - CircularProgressBar::Fill ); - } - } - - return Inherited::updateSubNode( skinnable, nodeRole, node ); -} - #include "moc_CircularProgressBarSkinlet.cpp" diff --git a/examples/iotdashboard/CircularProgressBarSkinlet.h b/examples/iotdashboard/CircularProgressBarSkinlet.h index 9075fbb3..92434b85 100644 --- a/examples/iotdashboard/CircularProgressBarSkinlet.h +++ b/examples/iotdashboard/CircularProgressBarSkinlet.h @@ -5,32 +5,19 @@ #pragma once -#include +#include -class CircularProgressBar; - -class CircularProgressBarSkinlet : public QskSkinlet +class CircularProgressBarSkinlet : public QskProgressRingSkinlet { Q_GADGET - using Inherited = QskSkinlet; + using Inherited = QskProgressRingSkinlet; public: - enum NodeRole - { - GrooveRole, - BarRole, - - RoleCount, - }; Q_INVOKABLE CircularProgressBarSkinlet( QskSkin* = nullptr ); ~CircularProgressBarSkinlet() override; QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; - - protected: - QSGNode* updateSubNode( const QskSkinnable*, - quint8 nodeRole, QSGNode* ) const override; }; diff --git a/examples/iotdashboard/Skin.cpp b/examples/iotdashboard/Skin.cpp index 2495d744..b6f8cd8f 100644 --- a/examples/iotdashboard/Skin.cpp +++ b/examples/iotdashboard/Skin.cpp @@ -121,17 +121,16 @@ void Skin::initHints() ed.setColor( TopBarItem::Item3 | QskAspect::TextColor, 0xfff99055 ); ed.setColor( TopBarItem::Item4 | QskAspect::TextColor, 0xff6776ff ); - // arcs are counterclockwise, so specify the 2nd color first: - ed.setGradient( TopBarItem::Item1, 0xffff3122, 0xffff5c00 ); - ed.setGradient( TopBarItem::Item2, 0xff6100ff, 0xff6776ff ); - ed.setGradient( TopBarItem::Item3, 0xffff3122, 0xffffce50 ); - ed.setGradient( TopBarItem::Item4, 0xff6100ff, 0xff6776ff ); + ed.setGradient( TopBarItem::Item1, 0xffff5c00, 0xffff3122 ); + ed.setGradient( TopBarItem::Item2, 0xff6776ff, 0xff6100ff ); + ed.setGradient( TopBarItem::Item3, 0xffffce50, 0xffff3122 ); + ed.setGradient( TopBarItem::Item4, 0xff6776ff, 0xff6100ff ); // the bar gradient is defined through the top bar items above ed.setArcMetrics( CircularProgressBar::Groove, 90, -360, 8.53 ); // the span angle will be set in the progress bar, we just give a dummy // value here: - ed.setArcMetrics( CircularProgressBar::Fill, 90, -180, 8.53 ); + ed.setArcMetrics( CircularProgressBar::Fill, 90, -360, 8.53 ); ed.setFontRole( TimeTitleLabel::Text, { QskFontRole::Caption, QskFontRole::High } ); diff --git a/src/controls/QskProgressBarSkinlet.cpp b/src/controls/QskProgressBarSkinlet.cpp index 74fe9e69..225fb44c 100644 --- a/src/controls/QskProgressBarSkinlet.cpp +++ b/src/controls/QskProgressBarSkinlet.cpp @@ -15,13 +15,13 @@ using Q = QskProgressBar; namespace { - QskIntervalF qskFillInterval( const Q* bar ) + QskIntervalF qskFillInterval( const QskProgressIndicator* indicator ) { qreal pos1, pos2; - if ( bar->isIndeterminate() ) + if ( indicator->isIndeterminate() ) { - const auto pos = bar->positionHint( QskProgressIndicator::Fill ); + const auto pos = indicator->positionHint( QskProgressIndicator::Fill ); static const QEasingCurve curve( QEasingCurve::InOutCubic ); @@ -32,10 +32,11 @@ namespace } else { - pos1 = bar->valueAsRatio( bar->origin() ); - pos2 = bar->valueAsRatio( bar->value() ); + pos1 = indicator->valueAsRatio( indicator->origin() ); + pos2 = indicator->valueAsRatio( indicator->value() ); } + auto bar = static_cast< const QskProgressBar* >( indicator ); if( bar->orientation() == Qt::Horizontal ) { if ( bar->layoutMirroring() ) @@ -107,11 +108,11 @@ QSGNode* QskProgressBarSkinlet::updateFillNode( const auto subControl = Q::Fill; - const auto rect = bar->subControlRect( subControl ); + const auto rect = indicator->subControlRect( subControl ); if ( rect.isEmpty() ) return nullptr; - auto gradient = bar->gradientHint( subControl ); + auto gradient = indicator->gradientHint( subControl ); if ( !gradient.isVisible() ) return nullptr; diff --git a/src/controls/QskProgressRingSkinlet.cpp b/src/controls/QskProgressRingSkinlet.cpp index 86e90329..ce611eef 100644 --- a/src/controls/QskProgressRingSkinlet.cpp +++ b/src/controls/QskProgressRingSkinlet.cpp @@ -10,31 +10,6 @@ using Q = QskProgressRing; -namespace -{ - QskIntervalF qskFillInterval( const Q* ring ) - { - qreal pos1, pos2; - - if ( ring->isIndeterminate() ) - { - const auto pos = ring->positionHint( QskProgressIndicator::Fill ); - - pos1 = pos2 = pos; - } - else - { - pos1 = ring->valueAsRatio( ring->origin() ); - pos2 = ring->valueAsRatio( ring->value() ); - } - - if ( pos1 > pos2 ) - std::swap( pos1, pos2 ); - - return QskIntervalF( pos1, pos2 ); - } -} - QskProgressRingSkinlet::QskProgressRingSkinlet( QskSkin* skin ) : Inherited( skin ) { @@ -48,21 +23,17 @@ QRectF QskProgressRingSkinlet::subControlRect( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const { - const auto ring = static_cast< const Q* >( skinnable ); - if( subControl == Q::Groove || subControl == Q::Fill ) { - auto rect = contentsRect; + const auto ring = static_cast< const Q* >( skinnable ); + const auto size = ring->strutSizeHint( Q::Fill ); + auto rect = contentsRect; if( ring->layoutMirroring() ) - { rect.setLeft( rect.right() - size.width() ); - } else - { rect.setWidth( size.width() ); - } rect.setTop( rect.top() + 0.5 * ( rect.height() - size.height() ) ); rect.setHeight( size.height() ); @@ -90,22 +61,29 @@ QSGNode* QskProgressRingSkinlet::updateFillNode( if ( rect.isEmpty() ) return nullptr; + const auto metrics = ring->arcMetricsHint( subControl ); + if ( metrics.isNull() ) + return nullptr; + auto gradient = ring->gradientHint( subControl ); if ( !gradient.isVisible() ) return nullptr; + const auto intv = fillInterval( ring ); + if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) { - const auto center = rect.center(); - const auto arcMetrics = ring->arcMetricsHint( Q::Fill ); - gradient.setConicDirection( center.x(), center.y(), arcMetrics.startAngle(), arcMetrics.spanAngle() ); + const auto stops = qskExtractedGradientStops( gradient.stops(), + intv.lowerBound(), intv.upperBound() ); + + gradient.setStops( stops ); + + if ( metrics.spanAngle() < 0.0 ) + gradient.reverse(); } - const auto interval = qskFillInterval( ring ); - const auto arcMetrics = ring->arcMetricsHint( subControl ); - - const auto startAngle = arcMetrics.startAngle() + interval.lowerBound() * arcMetrics.spanAngle(); - const auto spanAngle = interval.upperBound() * arcMetrics.spanAngle(); + const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle(); + const auto spanAngle = intv.upperBound() * metrics.spanAngle(); return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl ); } @@ -116,10 +94,28 @@ QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable, if ( which != Qt::PreferredSize ) return QSizeF(); - const auto ring = static_cast< const Q* >( skinnable ); + return skinnable->strutSizeHint( Q::Fill ); +} - const auto r = ring->strutSizeHint( Q::Fill ); - return r; +QskIntervalF QskProgressRingSkinlet::fillInterval( + const QskProgressIndicator* indicator ) const +{ + qreal pos1, pos2; + + if ( indicator->isIndeterminate() ) + { + pos1 = pos2 = indicator->positionHint( QskProgressIndicator::Fill ); + } + else + { + pos1 = indicator->valueAsRatio( indicator->origin() ); + pos2 = indicator->valueAsRatio( indicator->value() ); + } + + if ( pos1 > pos2 ) + std::swap( pos1, pos2 ); + + return QskIntervalF( pos1, pos2 ); } #include "moc_QskProgressRingSkinlet.cpp" diff --git a/src/controls/QskProgressRingSkinlet.h b/src/controls/QskProgressRingSkinlet.h index 767930b1..c5dc815b 100644 --- a/src/controls/QskProgressRingSkinlet.h +++ b/src/controls/QskProgressRingSkinlet.h @@ -8,7 +8,7 @@ #include "QskProgressIndicatorSkinlet.h" -class QskProgressRing; +class QskIntervalF; class QSK_EXPORT QskProgressRingSkinlet : public QskProgressIndicatorSkinlet { @@ -29,6 +29,8 @@ class QSK_EXPORT QskProgressRingSkinlet : public QskProgressIndicatorSkinlet protected: QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const override; QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const override; + + QskIntervalF fillInterval( const QskProgressIndicator* ) const; }; #endif