From d6da8fcbb807476260c32b1a9645e0067baf0c42 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 12 Jun 2024 12:20:31 +0200 Subject: [PATCH 1/4] QskArcNode is a container node --- src/nodes/QskArcNode.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/nodes/QskArcNode.h b/src/nodes/QskArcNode.h index c4fa330a..b641533e 100644 --- a/src/nodes/QskArcNode.h +++ b/src/nodes/QskArcNode.h @@ -6,18 +6,14 @@ #ifndef QSK_ARC_NODE_H #define QSK_ARC_NODE_H -#include "QskShapeNode.h" +#include "QskGlobal.h" +#include class QskArcMetrics; class QskGradient; class QskShadowMetrics; -/* - For the moment a QPainterPath/QskShapeNode. - But we can do better by creatig vertex lists manually - like what is done by the box renderer. TODO ... - */ -class QSK_EXPORT QskArcNode : public QskShapeNode +class QSK_EXPORT QskArcNode : public QSGNode { public: QskArcNode(); From 8775976f0b1ac0853a0838cc3f0f9f5e135b0b8a Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 12 Jun 2024 12:39:32 +0200 Subject: [PATCH 2/4] internally using a boolean instead of the sizemode enum --- src/common/QskArcMetrics.cpp | 18 +++++++++++------- src/common/QskArcMetrics.h | 15 ++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/common/QskArcMetrics.cpp b/src/common/QskArcMetrics.cpp index a7981827..596c0bff 100644 --- a/src/common/QskArcMetrics.cpp +++ b/src/common/QskArcMetrics.cpp @@ -48,7 +48,7 @@ void QskArcMetrics::setSpanAngle( qreal spanAngle ) noexcept void QskArcMetrics::setSizeMode( Qt::SizeMode sizeMode ) noexcept { - m_sizeMode = sizeMode; + m_relativeSize = ( sizeMode == Qt::RelativeSize ); } bool QskArcMetrics::isClosed() const @@ -79,7 +79,7 @@ bool QskArcMetrics::containsAngle( qreal angle ) const QskArcMetrics QskArcMetrics::interpolated( const QskArcMetrics& to, qreal ratio ) const noexcept { - if ( ( *this == to ) || ( m_sizeMode != to.m_sizeMode ) ) + if ( ( *this == to ) || ( m_relativeSize != to.m_relativeSize ) ) return to; const qreal thickness = qskInterpolated( m_thickness, to.m_thickness, ratio ); @@ -87,7 +87,7 @@ QskArcMetrics QskArcMetrics::interpolated( const qreal s1 = qskInterpolated( m_startAngle, to.m_startAngle, ratio ); const qreal s2 = qskInterpolated( endAngle(), to.endAngle(), ratio ); - return QskArcMetrics( s1, s2 - s1, thickness, m_sizeMode ); + return QskArcMetrics( s1, s2 - s1, thickness, sizeMode() ); } QVariant QskArcMetrics::interpolate( @@ -97,6 +97,11 @@ QVariant QskArcMetrics::interpolate( return QVariant::fromValue( from.interpolated( to, progress ) ); } +QskArcMetrics QskArcMetrics::toAbsolute( const QSizeF& size ) const noexcept +{ + return toAbsolute( 0.5 * size.width(), 0.5 * size.height() ); +} + QskArcMetrics QskArcMetrics::toAbsolute( qreal radiusX, qreal radiusY ) const noexcept { if ( radiusX < 0.0 ) @@ -110,7 +115,7 @@ QskArcMetrics QskArcMetrics::toAbsolute( qreal radiusX, qreal radiusY ) const no QskArcMetrics QskArcMetrics::toAbsolute( qreal radius ) const noexcept { - if ( m_sizeMode != Qt::RelativeSize ) + if ( !m_relativeSize ) return *this; const qreal t = qskEffectiveThickness( radius, m_thickness ); @@ -122,7 +127,7 @@ QPainterPath QskArcMetrics::painterPath( const QRectF& ellipseRect ) const const auto sz = qMin( ellipseRect.width(), ellipseRect.height() ); qreal t = m_thickness; - if ( m_sizeMode == Qt::RelativeSize ) + if ( m_relativeSize ) t = qskEffectiveThickness( 0.5 * sz, t ); if ( t <= 0.0 || qFuzzyIsNull( m_spanAngle ) ) @@ -212,8 +217,7 @@ QskHashValue QskArcMetrics::hash( QskHashValue seed ) const noexcept hash = qHash( m_startAngle, hash ); hash = qHash( m_spanAngle, hash ); - const int mode = m_sizeMode; - return qHashBits( &mode, sizeof( mode ), hash ); + return qHash( m_relativeSize, hash ); } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/common/QskArcMetrics.h b/src/common/QskArcMetrics.h index fe80ed46..5424d35d 100644 --- a/src/common/QskArcMetrics.h +++ b/src/common/QskArcMetrics.h @@ -58,6 +58,7 @@ class QSK_EXPORT QskArcMetrics QskArcMetrics interpolated( const QskArcMetrics&, qreal value ) const noexcept; + QskArcMetrics toAbsolute( const QSizeF& ) const noexcept; QskArcMetrics toAbsolute( qreal radiusX, qreal radiusY ) const noexcept; QskArcMetrics toAbsolute( qreal radius ) const noexcept; @@ -76,7 +77,8 @@ class QSK_EXPORT QskArcMetrics qreal m_spanAngle = 0.0; qreal m_thickness = 0.0; - Qt::SizeMode m_sizeMode = Qt::AbsoluteSize; + + bool m_relativeSize = false; }; inline constexpr QskArcMetrics::QskArcMetrics( @@ -85,23 +87,22 @@ inline constexpr QskArcMetrics::QskArcMetrics( { } -inline constexpr QskArcMetrics::QskArcMetrics( - qreal startAngle, qreal spanAngle, +inline constexpr QskArcMetrics::QskArcMetrics( qreal startAngle, qreal spanAngle, qreal thickness, Qt::SizeMode sizeMode ) noexcept : m_startAngle( startAngle ) , m_spanAngle( spanAngle ) , m_thickness( thickness ) - , m_sizeMode( sizeMode ) + , m_relativeSize( sizeMode == Qt::RelativeSize ) { } inline bool QskArcMetrics::operator==( const QskArcMetrics& other ) const noexcept { - return ( qskFuzzyCompare( m_thickness, other.m_thickness ) + return qskFuzzyCompare( m_thickness, other.m_thickness ) && qskFuzzyCompare( m_startAngle, other.m_startAngle ) && qskFuzzyCompare( m_spanAngle, other.m_spanAngle ) - && m_sizeMode == other.m_sizeMode ); + && ( m_relativeSize == other.m_relativeSize ); } inline bool QskArcMetrics::operator!=( @@ -142,7 +143,7 @@ inline constexpr qreal QskArcMetrics::angleAtRatio( qreal ratio ) const noexcept inline constexpr Qt::SizeMode QskArcMetrics::sizeMode() const noexcept { - return m_sizeMode; + return m_relativeSize ? Qt::RelativeSize : Qt::AbsoluteSize; } #ifndef QT_NO_DEBUG_STREAM From 69098643fff5ac8221253eb5347150977b01d899 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 12 Jun 2024 12:40:11 +0200 Subject: [PATCH 3/4] code moved to QskArcMetrics --- src/nodes/QskArcNode.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/nodes/QskArcNode.cpp b/src/nodes/QskArcNode.cpp index 737bb164..187cd53e 100644 --- a/src/nodes/QskArcNode.cpp +++ b/src/nodes/QskArcNode.cpp @@ -43,20 +43,6 @@ static inline QskGradient qskEffectiveGradient( return gradient; } -static inline QskArcMetrics qskEffectiveMetrics( - const QskArcMetrics& metrics, const QRectF& rect ) -{ - if ( metrics.sizeMode() == Qt::RelativeSize ) - { - const auto rx = 0.5 * rect.width(); - const auto ry = 0.5 * rect.height(); - - return metrics.toAbsolute( rx, ry ); - } - - return metrics; -} - static inline QRectF qskEffectiveRect( const QRectF& rect, const qreal borderWidth ) { @@ -98,7 +84,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics const qreal borderWidth, const QColor& borderColor, const QskGradient& fillGradient, const QColor& shadowColor, const QskShadowMetrics& shadowMetrics ) { - const auto metricsArc = qskEffectiveMetrics( arcMetrics, rect ); + const auto metricsArc = arcMetrics.toAbsolute( rect.size() ); const auto gradient = qskEffectiveGradient( fillGradient, metricsArc ); auto shadowNode = static_cast< QskArcShadowNode* >( @@ -111,7 +97,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics QskSGNode::findChildNode( this, BorderRole ) ); const auto arcRect = qskEffectiveRect( rect, borderWidth ); - if ( arcRect.isEmpty() ) + if ( metricsArc.isNull() || arcRect.isEmpty() ) { delete shadowNode; delete fillNode; @@ -119,7 +105,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics return; } - const auto isFillNodeVisible = gradient.isVisible() && !metricsArc.isNull(); + const auto isFillNodeVisible = gradient.isVisible(); const auto isStrokeNodeVisible = ( borderWidth > 0.0 ) && ( borderColor.alpha() > 0 ); const auto isShadowNodeVisible = isFillNodeVisible && shadowColor.isValid() && ( shadowColor.alpha() > 0.0 ); From 194edf88661a63213ec39a463cc3574f23093e9f Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 12 Jun 2024 12:40:33 +0200 Subject: [PATCH 4/4] code reorganized --- playground/shadows/ArcPage.cpp | 42 ++++++++++++++++-------------- playground/shadows/ShadowedArc.cpp | 10 +++---- playground/shadows/ShadowedArc.h | 5 ++-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/playground/shadows/ArcPage.cpp b/playground/shadows/ArcPage.cpp index 3ed5c5e4..b4d020e1 100644 --- a/playground/shadows/ArcPage.cpp +++ b/playground/shadows/ArcPage.cpp @@ -73,32 +73,36 @@ namespace } } }; + + class Arc : public ShadowedArc + { + public: + Arc() + { + setStartAngle( 45.0 ); + setSpanAngle( 270.0 ); + setThickness( 10.0 ); + + setFillGradient( Qt::darkRed ); + + setBorderWidth( 0 ); + setBorderColor( Qt::darkYellow ); + + setShadowColor( Qt::black ); + setSpreadRadius( 0.0 ); + setBlurRadius( 4.0 ); + setOffsetX( 2.0 ); + setOffsetY( 2.0 ); + } + }; } ArcPage::ArcPage( QQuickItem* parent ) : QskLinearBox( Qt::Vertical, parent ) { - auto arc = new ShadowedArc(); + auto arc = new Arc(); arc->setMargins( 40 ); // some extra space for testing the offsets - { - // initial settings - arc->setStartAngle( 45.0 ); - arc->setSpanAngle( 270.0 ); - arc->setThickness( 10.0 ); - - arc->setFillColor( Qt::darkRed ); - - arc->setBorderWidth( 0 ); - arc->setBorderColor( Qt::darkYellow ); - - arc->setShadowColor( Qt::black ); - arc->setSpreadRadius( 0.0 ); - arc->setBlurRadius( 4.0 ); - arc->setOffsetX( 2.0 ); - arc->setOffsetY( 2.0 ); - } - auto panel = new ControlPanel( arc ); panel->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed ); diff --git a/playground/shadows/ShadowedArc.cpp b/playground/shadows/ShadowedArc.cpp index bb209f3f..6f7ff077 100644 --- a/playground/shadows/ShadowedArc.cpp +++ b/playground/shadows/ShadowedArc.cpp @@ -101,7 +101,7 @@ ShadowedArc::ShadowedArc( QQuickItem* parent ) setArcMetrics( { 0.0, 360.0, 1.0, Qt::RelativeSize } ); - setFillColor( Qt::darkRed ); + setFillGradient( Qt::darkRed ); setBorderWidth( 0 ); setBorderColor( Qt::gray ); @@ -216,14 +216,14 @@ qreal ShadowedArc::blurRadius() const return shadowMetrics().blurRadius(); } -void ShadowedArc::setFillColor( const QColor& color ) +void ShadowedArc::setFillGradient( const QskGradient& gradient ) { - setColor( Arc, color ); + setGradientHint( Arc, gradient ); } -QColor ShadowedArc::fillColor() const +QskGradient ShadowedArc::fillGradient() const { - return color( Arc ); + return gradientHint( Arc ); } void ShadowedArc::setShadowColor( const QColor& color ) diff --git a/playground/shadows/ShadowedArc.h b/playground/shadows/ShadowedArc.h index c8f486d3..2f683e26 100644 --- a/playground/shadows/ShadowedArc.h +++ b/playground/shadows/ShadowedArc.h @@ -9,6 +9,7 @@ class QskShadowMetrics; class QskArcMetrics; +class QskGradient; class ShadowedArc : public QskControl { @@ -35,7 +36,7 @@ class ShadowedArc : public QskControl qreal blurRadius() const; QColor borderColor() const; - QColor fillColor() const; + QskGradient fillGradient() const; QColor shadowColor() const; public Q_SLOTS: @@ -52,7 +53,7 @@ class ShadowedArc : public QskControl void setBlurRadius( qreal ); void setBorderColor( const QColor& ); - void setFillColor( const QColor& ); + void setFillGradient( const QskGradient& ); void setShadowColor( const QColor& ); private: