diff --git a/src/common/QskShadowMetrics.cpp b/src/common/QskShadowMetrics.cpp index b5331dc9..9f8e3878 100644 --- a/src/common/QskShadowMetrics.cpp +++ b/src/common/QskShadowMetrics.cpp @@ -95,7 +95,8 @@ QskHashValue QskShadowMetrics::hash( QskHashValue seed ) const noexcept hash = qHash( m_offset.y(), seed ); hash = qHash( m_spreadRadius, hash ); hash = qHash( m_blurRadius, hash ); - hash = qHash( static_cast< int >( m_sizeMode ), hash ); + hash = qHash( m_sizeMode, hash ); + hash = qHash( m_shapeMode, hash ); return hash; } diff --git a/src/common/QskShadowMetrics.h b/src/common/QskShadowMetrics.h index bb85a117..711e4cef 100644 --- a/src/common/QskShadowMetrics.h +++ b/src/common/QskShadowMetrics.h @@ -23,8 +23,18 @@ class QSK_EXPORT QskShadowMetrics Q_PROPERTY( qreal blurRadius READ blurRadius WRITE setBlurRadius ) Q_PROPERTY( Qt::SizeMode sizeMode READ sizeMode WRITE setSizeMode ) + Q_PROPERTY( ShapeMode shapeMode READ shapeMode WRITE setShapeMode ) public: + enum ShapeMode + { + Aligned = 0, // The shape is related to some external definition + + Ellipse, + Rectangle + }; + Q_ENUM( ShapeMode ) + constexpr QskShadowMetrics( const QPointF& offset = QPointF() ) noexcept; constexpr QskShadowMetrics( qreal spreadRadius, qreal blurRadius ) noexcept; @@ -56,6 +66,9 @@ class QSK_EXPORT QskShadowMetrics void setSizeMode( Qt::SizeMode ) noexcept; constexpr Qt::SizeMode sizeMode() const noexcept; + void setShapeMode( ShapeMode ) noexcept; + constexpr ShapeMode shapeMode() const noexcept; + QskShadowMetrics interpolated( const QskShadowMetrics&, qreal value ) const noexcept; @@ -72,7 +85,8 @@ class QSK_EXPORT QskShadowMetrics QPointF m_offset; qreal m_spreadRadius = 0.0; qreal m_blurRadius = 0.0; - Qt::SizeMode m_sizeMode = Qt::AbsoluteSize; + quint8 m_sizeMode = Qt::AbsoluteSize; + quint8 m_shapeMode = QskShadowMetrics::Aligned; }; inline constexpr QskShadowMetrics::QskShadowMetrics( const QPointF& offset ) noexcept @@ -101,6 +115,7 @@ inline constexpr bool QskShadowMetrics::operator==( const QskShadowMetrics& other ) const noexcept { return ( m_sizeMode == other.m_sizeMode ) + && ( m_shapeMode == other.m_shapeMode ) && ( m_offset == other.m_offset ) && ( m_spreadRadius == other.m_spreadRadius ) && ( m_blurRadius == other.m_blurRadius ) @@ -145,7 +160,17 @@ inline void QskShadowMetrics::setSizeMode( Qt::SizeMode sizeMode ) noexcept inline constexpr Qt::SizeMode QskShadowMetrics::sizeMode() const noexcept { - return m_sizeMode; + return static_cast< Qt::SizeMode >( m_sizeMode ); +} + +inline void QskShadowMetrics::setShapeMode( ShapeMode shapeMode ) noexcept +{ + m_shapeMode = shapeMode; +} + +inline constexpr QskShadowMetrics::ShapeMode QskShadowMetrics::shapeMode() const noexcept +{ + return static_cast< ShapeMode >( m_shapeMode ); } inline void QskShadowMetrics::setOffsetX( qreal dx ) noexcept diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index 3a258445..7befc837 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -141,6 +141,12 @@ static inline QSGNode* qskUpdateGraphicNode( return graphicNode; } +static inline bool qskIsShadowVisible( const QskShadowMetrics& shadowMetrics, + const QColor& shadowColor ) +{ + return !shadowMetrics.isNull() && shadowColor.isValid() && ( shadowColor.alpha() > 0 ); +} + static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics, const QskBoxBorderColors& borderColors, const QskGradient& gradient ) { @@ -196,9 +202,15 @@ static inline QSGNode* qskUpdateBoxNode( const QskBoxBorderColors& borderColors, const QskGradient& gradient, const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) { - if ( rect.isEmpty() || !qskIsBoxVisible( borderMetrics, borderColors, gradient ) ) + if ( rect.isEmpty() ) return nullptr; + if ( !qskIsBoxVisible( borderMetrics, borderColors, gradient ) + && !qskIsShadowVisible( shadowMetrics, shadowColor ) ) + { + return nullptr; + } + auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); boxNode->updateNode( rect, shape, borderMetrics, borderColors, gradient, shadowMetrics, shadowColor ); diff --git a/src/nodes/QskBoxNode.cpp b/src/nodes/QskBoxNode.cpp index 78d21d59..22cc78c5 100644 --- a/src/nodes/QskBoxNode.cpp +++ b/src/nodes/QskBoxNode.cpp @@ -83,17 +83,30 @@ void QskBoxNode::updateNode( const QRectF& rect, const auto shadow = shadowMetrics.toAbsolute( rect.size() ); const auto shadowRect = shadow.shadowRect( rect ); + auto shadowShape = shapeMetrics; + + switch( static_cast< int >( shadow.shapeMode() ) ) + { + case QskShadowMetrics::Ellipse: + shadowShape.setRadius( 100.0, Qt::RelativeSize ); + break; + + case QskShadowMetrics::Rectangle: + shadowShape.setRadius( 0.0, Qt::AbsoluteSize ); + break; + } + if ( shadow.blurRadius() <= 0.0 ) { // QskBoxRectangleNode allows scene graph batching shadowFillNode = qskNode< QskBoxRectangleNode >( this, ShadowFillRole ); - shadowFillNode->updateFilling( shadowRect, shapeMetrics, shadowColor ); + shadowFillNode->updateFilling( shadowRect, shadowShape, shadowColor ); } else { shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole ); shadowNode->setShadowData( shadowRect, - shapeMetrics, shadow.blurRadius(), shadowColor ); + shadowShape, shadow.blurRadius(), shadowColor ); } }