From 1258c175348c395747876381e9bf8762dce4b97d Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 24 Oct 2024 10:16:51 +0200 Subject: [PATCH] several fixes concerning box shadows --- src/controls/QskSkinlet.cpp | 22 +++++----------------- src/nodes/QskBoxNode.cpp | 25 +++++++++++++------------ src/nodes/QskBoxRectangleNode.cpp | 14 +++++++++----- src/nodes/QskBoxShadowNode.cpp | 4 +++- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index e9a90d9e..3a258445 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -196,26 +196,14 @@ static inline QSGNode* qskUpdateBoxNode( const QskBoxBorderColors& borderColors, const QskGradient& gradient, const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) { - if ( rect.isEmpty() ) + if ( rect.isEmpty() || !qskIsBoxVisible( borderMetrics, borderColors, gradient ) ) return nullptr; - const auto size = rect.size(); + auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); + boxNode->updateNode( rect, shape, borderMetrics, + borderColors, gradient, shadowMetrics, shadowColor ); - const auto absoluteMetrics = borderMetrics.toAbsolute( size ); - - if ( qskIsBoxVisible( absoluteMetrics, borderColors, gradient ) ) - { - const auto absoluteShape = shape.toAbsolute( size ); - const auto absoluteShadowMetrics = shadowMetrics.toAbsolute( size ); - - auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); - boxNode->updateNode( rect, absoluteShape, absoluteMetrics, - borderColors, gradient, absoluteShadowMetrics, shadowColor ); - - return boxNode; - } - - return nullptr; + return boxNode; } static inline QSGNode* qskUpdateArcNode( diff --git a/src/nodes/QskBoxNode.cpp b/src/nodes/QskBoxNode.cpp index e0b82300..78d21d59 100644 --- a/src/nodes/QskBoxNode.cpp +++ b/src/nodes/QskBoxNode.cpp @@ -13,6 +13,7 @@ #include "QskShadowMetrics.h" #include "QskBoxBorderMetrics.h" #include "QskBoxBorderColors.h" +#include "QskBoxShapeMetrics.h" #include "QskRgbValue.h" namespace @@ -60,7 +61,7 @@ QskBoxNode::~QskBoxNode() } void QskBoxNode::updateNode( const QRectF& rect, - const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics, + const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors, const QskGradient& gradient, const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) { @@ -75,25 +76,24 @@ void QskBoxNode::updateNode( const QRectF& rect, { const auto hasFilling = gradient.isVisible(); const auto hasBorder = !borderMetrics.isNull() && borderColors.isVisible(); - - const auto hasShadow = hasFilling && !shadowMetrics.isNull() - && QskRgb::isVisible( shadowColor ); + const auto hasShadow = !shadowMetrics.isNull() && QskRgb::isVisible( shadowColor ); if ( hasShadow ) { - const auto shadowRect = shadowMetrics.shadowRect( rect ); - const auto blurRadius = shadowMetrics.blurRadius(); + const auto shadow = shadowMetrics.toAbsolute( rect.size() ); + const auto shadowRect = shadow.shadowRect( rect ); - if ( blurRadius <= 0.0 ) + if ( shadow.blurRadius() <= 0.0 ) { // QskBoxRectangleNode allows scene graph batching shadowFillNode = qskNode< QskBoxRectangleNode >( this, ShadowFillRole ); - shadowFillNode->updateFilling( shadowRect, shape, shadowColor ); + shadowFillNode->updateFilling( shadowRect, shapeMetrics, shadowColor ); } else { shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole ); - shadowNode->setShadowData( shadowRect, shape, blurRadius, shadowColor ); + shadowNode->setShadowData( shadowRect, + shapeMetrics, shadow.blurRadius(), shadowColor ); } } @@ -112,12 +112,13 @@ void QskBoxNode::updateNode( const QRectF& rect, if ( fillNode ) { - rectNode->updateBorder( rect, shape, borderMetrics, borderColors ); - fillNode->updateFilling( rect, shape, borderMetrics, gradient ); + rectNode->updateBorder( rect, shapeMetrics, borderMetrics, borderColors ); + fillNode->updateFilling( rect, shapeMetrics, borderMetrics, gradient ); } else { - rectNode->updateBox( rect, shape, borderMetrics, borderColors, gradient ); + rectNode->updateBox( rect, shapeMetrics, + borderMetrics, borderColors, gradient ); } } } diff --git a/src/nodes/QskBoxRectangleNode.cpp b/src/nodes/QskBoxRectangleNode.cpp index 461e558b..62fcb8c5 100644 --- a/src/nodes/QskBoxRectangleNode.cpp +++ b/src/nodes/QskBoxRectangleNode.cpp @@ -12,7 +12,7 @@ #include "QskGradientDirection.h" #include "QskFillNodePrivate.h" -static inline bool qskHasBorder( +static inline bool qskHasBorder( const QskBoxBorderMetrics& metrics, const QskBoxBorderColors& colors ) { return !metrics.isNull() && colors.isVisible(); @@ -142,7 +142,7 @@ void QskBoxRectangleNode::updateFilling( const QRectF& rect, } void QskBoxRectangleNode::updateBorder( const QRectF& rect, - const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics, + const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors ) { Q_D( QskBoxRectangleNode ); @@ -153,6 +153,8 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect, return; } + const auto shape = shapeMetrics.toAbsolute( rect.size() ); + const bool coloredGeometry = hasHint( PreferColoredGeometry ) || !borderColors.isMonochrome(); @@ -189,7 +191,7 @@ void QskBoxRectangleNode::updateBorder( const QRectF& rect, } void QskBoxRectangleNode::updateBox( const QRectF& rect, - const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics, + const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors, const QskGradient& gradient ) { Q_D( QskBoxRectangleNode ); @@ -205,6 +207,8 @@ void QskBoxRectangleNode::updateBox( const QRectF& rect, if ( hasFill && hasBorder ) { + const auto shape = shapeMetrics.toAbsolute( rect.size() ); + const bool isDirty = d->updateMetrics( rect, shape, borderMetrics ) || d->updateColors( borderColors, gradient ) || !isGeometryColored(); @@ -232,11 +236,11 @@ void QskBoxRectangleNode::updateBox( const QRectF& rect, } else if ( hasFill ) { - updateFilling( rect, shape, borderMetrics, gradient ); + updateFilling( rect, shapeMetrics, borderMetrics, gradient ); } else if ( hasBorder ) { - updateBorder( rect, shape, borderMetrics, borderColors ); + updateBorder( rect, shapeMetrics, borderMetrics, borderColors ); } else { diff --git a/src/nodes/QskBoxShadowNode.cpp b/src/nodes/QskBoxShadowNode.cpp index cfb0099e..50b42229 100644 --- a/src/nodes/QskBoxShadowNode.cpp +++ b/src/nodes/QskBoxShadowNode.cpp @@ -269,7 +269,7 @@ QskBoxShadowNode::~QskBoxShadowNode() } void QskBoxShadowNode::setShadowData( - const QRectF& rect, const QskBoxShapeMetrics& shape, + const QRectF& rect, const QskBoxShapeMetrics& shapeMetrics, qreal blurRadius, const QColor& color ) { Q_D( QskBoxShadowNode ); @@ -299,6 +299,8 @@ void QskBoxShadowNode::setShadowData( } { + const auto shape = shapeMetrics.toAbsolute( rect.size() ); + const float t = std::min( d->rect.width(), d->rect.height() ); const float r1 = shape.radius( Qt::BottomRightCorner ).width();