From d18017ca90b93c8c366ad6b755699bc40c42ad62 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 29 Nov 2024 13:55:30 +0100 Subject: [PATCH] QskProgressRing fixed + M3 updates --- designsystems/material3/QskMaterial3Skin.cpp | 8 +- src/controls/QskProgressRingSkinlet.cpp | 89 ++++++++++++++------ src/controls/QskProgressRingSkinlet.h | 2 - 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/designsystems/material3/QskMaterial3Skin.cpp b/designsystems/material3/QskMaterial3Skin.cpp index db9e355a..db3306f1 100644 --- a/designsystems/material3/QskMaterial3Skin.cpp +++ b/designsystems/material3/QskMaterial3Skin.cpp @@ -511,9 +511,15 @@ void Editor::setupProgressRing() { using Q = QskProgressRing; + setArcMetrics( Q::Groove, 90, -360, 4_dp ); + setGradient( Q::Groove, m_pal.surfaceContainerHighest ); + setGradient( Q::Groove | Q::Disabled, m_pal.onSurface12 ); + + setSpacing( Q::Fill, 10 ); setStrutSize( Q::Fill, { 48_dp, 48_dp } ); - setGradient( Q::Fill, m_pal.primary ); setArcMetrics( Q::Fill, 90, -360, 4_dp ); + setGradient( Q::Fill, m_pal.primary ); + setGradient( Q::Fill | Q::Disabled, m_pal.onSurface38 ); } void Editor::setupRadioBox() diff --git a/src/controls/QskProgressRingSkinlet.cpp b/src/controls/QskProgressRingSkinlet.cpp index 167cb861..bb8f8d25 100644 --- a/src/controls/QskProgressRingSkinlet.cpp +++ b/src/controls/QskProgressRingSkinlet.cpp @@ -10,6 +10,36 @@ using Q = QskProgressRing; +static QskIntervalF qskFillInterval( const QskProgressIndicator* indicator ) +{ + qreal pos1, pos2; + + if ( indicator->isIndeterminate() ) + { + pos1 = indicator->positionHint( QskProgressIndicator::Fill ); + pos2 = 2 * pos1; + } + else + { + pos1 = indicator->valueAsRatio( indicator->origin() ); + pos2 = indicator->valueAsRatio( indicator->value() ); + } + + if ( pos1 > pos2 ) + std::swap( pos1, pos2 ); + + return QskIntervalF( pos1, pos2 ); +} + +static inline QPair< qreal, qreal > qskFillAngles( + const QskArcMetrics& metrics, const QskIntervalF& intv ) +{ + const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle(); + const auto endAngle = metrics.startAngle() + intv.upperBound() * metrics.spanAngle(); + + return { startAngle, endAngle }; +} + QskProgressRingSkinlet::QskProgressRingSkinlet( QskSkin* skin ) : Inherited( skin ) { @@ -32,6 +62,34 @@ QRectF QskProgressRingSkinlet::subControlRect( QSGNode* QskProgressRingSkinlet::updateGrooveNode( const QskProgressIndicator* indicator, QSGNode* node ) const { + const auto ring = static_cast< const Q* >( indicator ); + + const auto spacing = ring->spacingHint( Q::Fill ); // degrees + + if( spacing > 0.0 ) + { + const auto fillMetrics = ring->arcMetricsHint( Q::Fill ); + if ( fillMetrics.isClosed() ) + { + const auto fillAngles = qskFillAngles( fillMetrics, qskFillInterval( ring ) ); + + qreal startAngle, endAngle; + if ( fillAngles.second > fillAngles.first ) + { + startAngle = fillAngles.second + spacing; + endAngle = fillAngles.first + 360.0 - spacing; + } + else + { + startAngle = fillAngles.second - spacing; + endAngle = fillAngles.first - 360.0 + spacing; + } + + return updateArcNode( ring, node, + startAngle, endAngle - startAngle, Q::Groove ); + } + } + return updateArcNode( indicator, node, Q::Groove ); } @@ -54,7 +112,7 @@ QSGNode* QskProgressRingSkinlet::updateFillNode( if ( !gradient.isVisible() ) return nullptr; - const auto intv = fillInterval( ring ); + const auto intv = qskFillInterval( ring ); if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) { @@ -67,10 +125,10 @@ QSGNode* QskProgressRingSkinlet::updateFillNode( gradient.reverse(); } - const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle(); - const auto spanAngle = intv.upperBound() * metrics.spanAngle(); + const auto angles = qskFillAngles( metrics, intv ); - return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl ); + return updateArcNode( ring, node, rect, gradient, + angles.first, angles.second - angles.first, subControl ); } QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable, @@ -88,32 +146,11 @@ QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable, if ( constraint.width() >= 0.0 ) hint.setHeight( constraint.width() / aspectRatio ); - else + else hint.setWidth( constraint.height() * aspectRatio ); } return hint; } -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 c5dc815b..d7171deb 100644 --- a/src/controls/QskProgressRingSkinlet.h +++ b/src/controls/QskProgressRingSkinlet.h @@ -29,8 +29,6 @@ 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