diff --git a/designsystems/material3/QskMaterial3ProgressBarSkinlet.cpp b/designsystems/material3/QskMaterial3ProgressBarSkinlet.cpp index 81622505..dfd6ce24 100644 --- a/designsystems/material3/QskMaterial3ProgressBarSkinlet.cpp +++ b/designsystems/material3/QskMaterial3ProgressBarSkinlet.cpp @@ -5,9 +5,7 @@ #include "QskMaterial3ProgressBarSkinlet.h" #include -#include -#include -#include +#include #include #include #include @@ -65,11 +63,11 @@ QSGNode* QskMaterial3ProgressBarSkinlet::updateStopIndicatorNode( else rect.setBottom( rect.top() + rect.width() ); - const auto color = progressBar->gradientHint( Q::Fill ).endColor(); - const auto shape = progressBar->boxShapeHint( Q::Fill ); + QskBoxHints hints; + hints.shape = progressBar->boxShapeHint( Q::Fill ); + hints.gradient = progressBar->gradientHint( Q::Fill ).endColor(); - return updateBoxNode( progressBar, node, rect, shape, - QskBoxBorderMetrics(), QskBoxBorderColors(), color ); + return updateBoxNode( progressBar, node, rect, hints ); } QSGNode* QskMaterial3ProgressBarSkinlet::updateGrooveClipNode( diff --git a/examples/iotdashboard/StorageBarSkinlet.cpp b/examples/iotdashboard/StorageBarSkinlet.cpp index cfc2ceeb..3f6c68d5 100644 --- a/examples/iotdashboard/StorageBarSkinlet.cpp +++ b/examples/iotdashboard/StorageBarSkinlet.cpp @@ -14,8 +14,8 @@ StorageBarSkinlet::StorageBarSkinlet( QskSkin* skin ) setNodeRoles( { Pictures, Music, Videos, Documents, Others, Free } ); } -QRectF StorageBarSkinlet::subControlRect( const QskSkinnable* skinnable, const QRectF& contentsRect, - QskAspect::Subcontrol subControl ) const +QRectF StorageBarSkinlet::subControlRect( const QskSkinnable* skinnable, + const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const { const auto* const bar = static_cast< const S* >( skinnable ); @@ -70,35 +70,29 @@ QRectF StorageBarSkinlet::subControlRect( const QskSkinnable* skinnable, const Q return Inherited::subControlRect( skinnable, contentsRect, subControl ); } -namespace -{ - inline QSGNode* updateSegmentBoxNode( - const S* const skinnable, const QskAspect::Subcontrol& subcontrol, QSGNode* const node ) - { - return QskSkinlet::updateBoxNode( skinnable, node, skinnable->subControlRect( subcontrol ), - skinnable->gradientHint( subcontrol ), subcontrol ); - } -} - QSGNode* StorageBarSkinlet::updateSubNode( const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const { - const auto* const bar = static_cast< const S* >( skinnable ); - switch ( nodeRole ) { case Pictures: - return updateSegmentBoxNode( bar, S::Pictures, node ); + return updateBoxNode( skinnable, node, S::Pictures ); + case Music: - return updateSegmentBoxNode( bar, S::Music, node ); + return updateBoxNode( skinnable, node, S::Music ); + case Videos: - return updateSegmentBoxNode( bar, S::Videos, node ); + return updateBoxNode( skinnable, node, S::Videos ); + case Documents: - return updateSegmentBoxNode( bar, S::Documents, node ); + return updateBoxNode( skinnable, node, S::Documents ); + case Others: - return updateSegmentBoxNode( bar, S::Others, node ); + return updateBoxNode( skinnable, node, S::Others ); + case Free: - return updateSegmentBoxNode( bar, S::Free, node ); + return updateBoxNode( skinnable, node, S::Free ); + default: return Inherited::updateSubNode( skinnable, nodeRole, node ); } diff --git a/playground/plots/PlotCursorSkinlet.cpp b/playground/plots/PlotCursorSkinlet.cpp index 48095c24..1bd3857c 100644 --- a/playground/plots/PlotCursorSkinlet.cpp +++ b/playground/plots/PlotCursorSkinlet.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -143,8 +144,10 @@ QSGNode* PlotCursorSkinlet::updateSampleNode( const QskSkinnable* skinnable, if ( subControl == Q::LabelPanel ) { - const auto gradient = skinnable->gradientHint( aspect ); - return updateBoxNode( skinnable, node, rect, gradient, subControl ); + auto hints = skinnable->boxHints( subControl ); + hints.gradient = skinnable->gradientHint( aspect ); + + return updateBoxNode( skinnable, node, rect, hints ); } if ( subControl == Q::LabelText ) diff --git a/playground/shadows/ShadowedArc.cpp b/playground/shadows/ShadowedArc.cpp index e2185161..4739745e 100644 --- a/playground/shadows/ShadowedArc.cpp +++ b/playground/shadows/ShadowedArc.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -107,14 +107,7 @@ namespace return nullptr; auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); - - const auto metrics = arc->arcMetricsHint( Q::Arc ); - const auto fillGradient = arc->gradientHint( Q::Arc ); - - const auto borderColor = arc->color( Q::Arc | QskAspect::Border ); - const auto borderWidth = arc->metric( Q::Arc | QskAspect::Border ); - - arcNode->setArcData( rect, metrics, borderWidth, borderColor, fillGradient ); + arcNode->setArcData( rect, arc->arcHints( Q::Arc ) ); return arcNode; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c86f6783..2c69fa06 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ list(APPEND HEADERS common/QskArcMetrics.h + common/QskArcHints.h common/QskAspect.h common/QskBoxBorderColors.h common/QskBoxBorderMetrics.h @@ -41,6 +42,7 @@ list(APPEND HEADERS list(APPEND SOURCES common/QskArcMetrics.cpp + common/QskArcHints.cpp common/QskAspect.cpp common/QskBoxBorderColors.cpp common/QskBoxBorderMetrics.cpp diff --git a/src/common/QskArcHints.cpp b/src/common/QskArcHints.cpp new file mode 100644 index 00000000..9a135573 --- /dev/null +++ b/src/common/QskArcHints.cpp @@ -0,0 +1,69 @@ +/****************************************************************************** + * QSkinny - Copyright (C) The authors + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include "QskArcHints.h" +#include "QskRgbValue.h" + +static inline qreal qskInterpolated( qreal from, qreal to, qreal ratio ) +{ + return from + ( to - from ) * ratio; +} + +QskArcHints::QskArcHints() +{ +} + +QskArcHints::QskArcHints( const QskArcMetrics& metrics, qreal borderWidth, + const QColor& borderColor, const QskGradient& gradient ) + : metrics( metrics ) + , borderWidth( borderWidth ) + , borderColor( borderColor ) + , gradient( gradient ) +{ +} + +bool QskArcHints::isVisible() const +{ + if ( metrics.isNull() ) + return false; + + if ( borderWidth > 0.0 && borderColor.isValid() && borderColor.alpha() > 0 ) + return true; + + return gradient.isVisible(); +} + +QskArcHints QskArcHints::toAbsolute( const QSizeF& size ) const noexcept +{ + return QskArcHints( metrics.toAbsolute( size ), + borderWidth, borderColor, gradient ); +} + +QskArcHints QskArcHints::interpolated( + const QskArcHints& to, qreal value ) const noexcept +{ + return QskArcHints( + metrics.interpolated( to.metrics, value ), + qskInterpolated( borderWidth, to.borderWidth, value ), + QskRgb::interpolated( borderColor, to.borderColor, value ), + gradient.interpolated( to.gradient, value ) + ); +} + +#ifndef QT_NO_DEBUG_STREAM + +#include + +QDebug operator<<( QDebug debug, const QskArcHints& hints ) +{ + debug << hints.metrics << hints.borderWidth + << hints.borderColor << hints.gradient; + + return debug; +} + +#endif + +#include "moc_QskArcHints.cpp" diff --git a/src/common/QskArcHints.h b/src/common/QskArcHints.h new file mode 100644 index 00000000..7629c435 --- /dev/null +++ b/src/common/QskArcHints.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * QSkinny - Copyright (C) The authors + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#ifndef QSK_ARC_HINTS_H +#define QSK_ARC_HINTS_H + +#include "QskArcMetrics.h" +#include "QskGradient.h" +#include + +class QSK_EXPORT QskArcHints +{ + Q_GADGET + + Q_PROPERTY( QskArcMetrics metrics MEMBER metrics ) + Q_PROPERTY( qreal borderWidth MEMBER borderWidth ) + Q_PROPERTY( QColor borderColor MEMBER borderColor ) + + public: + QskArcHints(); + QskArcHints( const QskArcMetrics&, qreal borderWidth, + const QColor& borderColor, const QskGradient& ); + + QskArcHints toAbsolute( const QSizeF& ) const noexcept; + + QskArcHints interpolated( + const QskArcHints&, qreal value ) const noexcept; + + bool isVisible() const; + + QskArcMetrics metrics; + qreal borderWidth = 0.0; + + QColor borderColor; + QskGradient gradient; +}; + +#ifndef QT_NO_DEBUG_STREAM + +class QDebug; +QSK_EXPORT QDebug operator<<( QDebug, const QskArcHints& ); + +#endif + +#endif diff --git a/src/controls/QskMenuSkinlet.cpp b/src/controls/QskMenuSkinlet.cpp index 7ee5bf81..d8a5fd2e 100644 --- a/src/controls/QskMenuSkinlet.cpp +++ b/src/controls/QskMenuSkinlet.cpp @@ -9,6 +9,7 @@ #include "QskGraphic.h" #include "QskColorFilter.h" #include "QskTextOptions.h" +#include "QskBoxHints.h" #include "QskFunctions.h" #include "QskMargins.h" #include "QskFunctions.h" @@ -572,11 +573,13 @@ QSGNode* QskMenuSkinlet::updateSampleNode( const QskSkinnable* skinnable, if ( subControl == Q::Separator ) { - auto gradient = menu->gradientHint( subControl ); + auto hints = skinnable->boxHints( subControl ); + + auto& gradient = hints.gradient; if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) gradient.setLinearDirection( Qt::Vertical ); - return updateBoxNode( menu, node, rect, gradient, subControl ); + return updateBoxNode( menu, node, rect, hints ); } return nullptr; diff --git a/src/controls/QskPopupSkinlet.cpp b/src/controls/QskPopupSkinlet.cpp index 47f2fbef..eeca9992 100644 --- a/src/controls/QskPopupSkinlet.cpp +++ b/src/controls/QskPopupSkinlet.cpp @@ -6,6 +6,7 @@ #include "QskPopupSkinlet.h" #include "QskPopup.h" #include "QskRgbValue.h" +#include "QskBoxHints.h" static inline QRgb qskInterpolatedRgb( QRgb rgb, qreal factor ) { @@ -58,7 +59,9 @@ QSGNode* QskPopupSkinlet::updateOverlayNode( if ( rect.isEmpty() ) return nullptr; - auto gradient = popup->gradientHint( Q::Overlay ); + auto hints = popup->boxHints( Q::Overlay ); + + auto& gradient = hints.gradient; if ( gradient.isVisible() && factor != 1.0 ) { @@ -70,7 +73,7 @@ QSGNode* QskPopupSkinlet::updateOverlayNode( gradient.setStops( stops ); } - return updateBoxNode( popup, node, rect, gradient, QskPopup::Overlay ); + return updateBoxNode( popup, node, rect, hints ); } #include "moc_QskPopupSkinlet.cpp" diff --git a/src/controls/QskProgressBarSkinlet.cpp b/src/controls/QskProgressBarSkinlet.cpp index f3b99a37..a2095b0b 100644 --- a/src/controls/QskProgressBarSkinlet.cpp +++ b/src/controls/QskProgressBarSkinlet.cpp @@ -6,7 +6,7 @@ #include "QskProgressBarSkinlet.h" #include "QskProgressBar.h" #include "QskIntervalF.h" -#include "QskBoxBorderMetrics.h" +#include "QskBoxHints.h" #include #include @@ -50,41 +50,6 @@ static QskIntervalF qskFillInterval( const QskProgressIndicator* indicator ) return QskIntervalF( pos1, pos2 ); } -static QskGradient qskFillGradient( const QskProgressBar* progressBar ) -{ - auto gradient = progressBar->gradientHint( Q::Fill ); - - if ( gradient.isVisible() && !gradient.isMonochrome() - && ( gradient.type() == QskGradient::Stops ) ) - { - /* - When having stops only we use a linear gradient, - where the colors are increasing in direction of the - progress value. We interprete the gradient as a - definition for the 100% situation and have to adjust - the stops for smaller bars. - - For this situation it would be more convenient to - adjust the start/stop positions, but the box renderer is - not supporting this yet. TODO ... - */ - - const auto intv = qskFillInterval( progressBar ); - - const auto stops = qskExtractedGradientStops( - gradient.stops(), intv.lowerBound(), intv.upperBound() ); - - gradient.setStops( stops ); - - gradient.setLinearDirection( progressBar->orientation() ); - - if ( progressBar->orientation() == Qt::Vertical || progressBar->layoutMirroring() ) - gradient.reverse(); - } - - return gradient; -} - QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin ) : Inherited( skin ) { @@ -122,9 +87,40 @@ QSGNode* QskProgressBarSkinlet::updateFillNode( if ( rect.isEmpty() ) return nullptr; - const auto progressBar = static_cast< const Q* >( indicator ); - return updateBoxNode( indicator, node, rect, - qskFillGradient( progressBar ), Q::Fill ); + auto hints = indicator->boxHints( Q::Fill ); + + auto& gradient = hints.gradient; + + if ( gradient.isVisible() && !gradient.isMonochrome() + && ( gradient.type() == QskGradient::Stops ) ) + { + /* + When having stops only we use a linear gradient, + where the colors are increasing in direction of the + progress value. We interprete the gradient as a + definition for the 100% situation and have to adjust + the stops for smaller bars. + + For this situation it would be more convenient to + adjust the start/stop positions, but the box renderer is + not supporting this yet. TODO ... + */ + + const auto intv = qskFillInterval( indicator ); + + const auto stops = qskExtractedGradientStops( + gradient.stops(), intv.lowerBound(), intv.upperBound() ); + + gradient.setStops( stops ); + + const auto orientation = static_cast< const Q* >( indicator )->orientation(); + gradient.setLinearDirection( orientation ); + + if ( orientation == Qt::Vertical || indicator->layoutMirroring() ) + gradient.reverse(); + } + + return updateBoxNode( indicator, node, rect, hints ); } QRectF QskProgressBarSkinlet::grooveRect( diff --git a/src/controls/QskProgressRingSkinlet.cpp b/src/controls/QskProgressRingSkinlet.cpp index bb8f8d25..f599b3a8 100644 --- a/src/controls/QskProgressRingSkinlet.cpp +++ b/src/controls/QskProgressRingSkinlet.cpp @@ -4,7 +4,7 @@ *****************************************************************************/ #include "QskProgressRingSkinlet.h" -#include "QskArcMetrics.h" +#include "QskArcHints.h" #include "QskProgressRing.h" #include "QskIntervalF.h" @@ -85,8 +85,12 @@ QSGNode* QskProgressRingSkinlet::updateGrooveNode( endAngle = fillAngles.first - 360.0 + spacing; } - return updateArcNode( ring, node, - startAngle, endAngle - startAngle, Q::Groove ); + auto hints = indicator->arcHints( Q::Groove ); + hints.metrics.setStartAngle( startAngle ); + hints.metrics.setSpanAngle( endAngle - startAngle ); + + const auto rect = indicator->subControlRect( Q::Groove ); + return updateArcNode( ring, node, rect, hints ); } } @@ -104,16 +108,14 @@ 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() ) + auto hints = ring->arcHints( subControl ); + if ( !hints.isVisible() ) return nullptr; const auto intv = qskFillInterval( ring ); + auto& gradient = hints.gradient; + if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) { const auto stops = qskExtractedGradientStops( gradient.stops(), @@ -121,14 +123,15 @@ QSGNode* QskProgressRingSkinlet::updateFillNode( gradient.setStops( stops ); - if ( metrics.spanAngle() < 0.0 ) + if ( hints.metrics.spanAngle() < 0.0 ) gradient.reverse(); } - const auto angles = qskFillAngles( metrics, intv ); + const auto angles = qskFillAngles( hints.metrics, intv ); + hints.metrics.setStartAngle( angles.first ); + hints.metrics.setSpanAngle( angles.second - angles.first ); - return updateArcNode( ring, node, rect, gradient, - angles.first, angles.second - angles.first, subControl ); + return updateArcNode( ring, node, rect, hints ); } QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable, diff --git a/src/controls/QskSeparatorSkinlet.cpp b/src/controls/QskSeparatorSkinlet.cpp index a117f328..fcf12a34 100644 --- a/src/controls/QskSeparatorSkinlet.cpp +++ b/src/controls/QskSeparatorSkinlet.cpp @@ -6,6 +6,7 @@ #include "QskSeparatorSkinlet.h" #include "QskSeparator.h" +#include "QskBoxHints.h" #include "QskGradientDirection.h" #include "QskAspect.h" @@ -42,8 +43,12 @@ QSGNode* QskSeparatorSkinlet::updateSubNode( using Q = QskSeparator; const auto rect = separator->subControlRect( Q::Panel ); + if ( rect.isEmpty() ) + return nullptr; - auto gradient = separator->gradientHint( Q::Panel ); + auto hints = separator->boxHints( Q::Panel ); + + auto& gradient = hints.gradient; if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) { // gradient in opposite orientation @@ -53,7 +58,7 @@ QSGNode* QskSeparatorSkinlet::updateSubNode( gradient.setLinearDirection( orientation ); } - return updateBoxNode( separator, node, rect, gradient, Q::Panel ); + return updateBoxNode( separator, node, rect, hints ); } } diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index de23fe99..ae79be86 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -7,9 +7,7 @@ #include "QskArcNode.h" #include "QskAspect.h" -#include "QskArcMetrics.h" -#include "QskBoxBorderColors.h" -#include "QskBoxBorderMetrics.h" +#include "QskArcHints.h" #include "QskBoxNode.h" #include "QskBoxRectangleNode.h" #include "QskBoxShapeMetrics.h" @@ -156,18 +154,6 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics, return !borderMetrics.isNull() && borderColors.isVisible(); } -static inline bool qskIsArcVisible( const QskArcMetrics& arcMetrics, - qreal borderWidth, const QColor borderColor, const QskGradient& gradient ) -{ - if ( arcMetrics.isNull() ) - return false; - - if ( borderWidth > 0.0 && borderColor.isValid() && borderColor.alpha() > 0 ) - return true; - - return gradient.isVisible(); -} - static inline bool qskIsLineVisible( const QColor& lineColor, qreal lineWidth ) { return ( lineWidth > 0.0 ) && lineColor.isValid() && ( lineColor.alpha() > 0 ); @@ -202,22 +188,18 @@ static inline QQuickWindow* qskWindowOfSkinnable( const QskSkinnable* skinnable return nullptr; } -static inline QSGNode* qskUpdateBoxNode( - const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, - const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics, - const QskBoxBorderColors& borderColors, const QskGradient& gradient, - const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) +static inline QSGNode* qskUpdateBoxNode( const QskSkinnable* skinnable, + QSGNode* node, const QRectF& rect, const QskBoxHints& hints ) { if ( !rect.isEmpty() ) { - if ( qskIsBoxVisible( borderMetrics, borderColors, gradient ) - || qskIsShadowVisible( shadowMetrics, shadowColor ) ) + if ( qskIsBoxVisible( hints.borderMetrics, hints.borderColors, hints.gradient ) + || qskIsShadowVisible( hints.shadowMetrics, hints.shadowColor ) ) { if ( auto window = qskWindowOfSkinnable( skinnable ) ) { auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); - boxNode->updateNode( window, rect, shape, borderMetrics, - borderColors, gradient, shadowMetrics, shadowColor ); + boxNode->updateNode( window, rect, hints ); return boxNode; } @@ -227,21 +209,20 @@ static inline QSGNode* qskUpdateBoxNode( return nullptr; } -static inline QSGNode* qskUpdateArcNode( - const QskSkinnable*, QSGNode* node, const QRectF& rect, - qreal borderWidth, const QColor borderColor, - const QskGradient& gradient, const QskArcMetrics& metrics ) +static inline QSGNode* qskUpdateArcNode( const QskSkinnable* skinnable, + QSGNode* node, const QRectF& rect, const QskArcHints& hints ) { - if ( rect.isEmpty() ) - return nullptr; + Q_UNUSED( skinnable ); - if ( !qskIsArcVisible( metrics, borderWidth, borderColor, gradient ) ) - return nullptr; + if ( !rect.isEmpty() && hints.isVisible() ) + { + auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); + arcNode->setArcData( rect, hints ); - auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); - arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient ); + return arcNode; + } - return arcNode; + return nullptr; } static inline QSGNode* qskUpdateLineNode( @@ -435,53 +416,27 @@ QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable, QSGNode* node, QskAspect::Subcontrol subControl ) const { const auto rect = qskSubControlRect( this, skinnable, subControl ); - return updateBoxNode( skinnable, node, rect, subControl ); + if ( rect.isEmpty() ) + return nullptr; + + return qskUpdateBoxNode( skinnable, node, + rect, skinnable->boxHints( subControl ) ); } QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl ) { - const auto fillGradient = skinnable->gradientHint( subControl ); - return updateBoxNode( skinnable, node, rect, fillGradient, subControl ); -} - -QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable, - QSGNode* node, const QRectF& rect, const QskGradient& fillGradient, - QskAspect::Subcontrol subControl ) -{ - const auto margins = skinnable->marginHint( subControl ); - - const auto boxRect = rect.marginsRemoved( margins ); - if ( boxRect.isEmpty() ) + if ( rect.isEmpty() ) return nullptr; - const auto borderMetrics = skinnable->boxBorderMetricsHint( subControl ); - const auto borderColors = skinnable->boxBorderColorsHint( subControl ); - const auto shape = skinnable->boxShapeHint( subControl ); - const auto shadowMetrics = skinnable->shadowMetricsHint( subControl ); - const auto shadowColor = skinnable->shadowColorHint( subControl ); - - return qskUpdateBoxNode( skinnable, node, - boxRect, shape, borderMetrics, borderColors, fillGradient, - shadowMetrics, shadowColor ); -} - -QSGNode* QskSkinlet::updateBoxNode( - const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, - const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics, - const QskBoxBorderColors& borderColors, const QskGradient& fillGradient ) -{ - return qskUpdateBoxNode( skinnable, node, - rect, shape, borderMetrics, borderColors, fillGradient, - QskShadowMetrics(), QColor() ); + const auto hints = skinnable->boxHints( subControl ); + return qskUpdateBoxNode( skinnable, node, rect, hints ); } QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, const QskBoxHints& hints ) { - return qskUpdateBoxNode( skinnable, node, rect, - hints.shape, hints.borderMetrics, hints.borderColors, hints.gradient, - hints.shadowMetrics, hints.shadowColor ); + return qskUpdateBoxNode( skinnable, node, rect, hints ); } QSGNode* QskSkinlet::updateInterpolatedBoxNode( @@ -526,79 +481,24 @@ QSGNode* QskSkinlet::updateInterpolatedBoxNode( QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, QSGNode* node, QskAspect::Subcontrol subControl ) const { - const auto rect = qskSubControlRect( this, skinnable, subControl ); - return updateArcNode( skinnable, node, rect, subControl ); + auto rect = qskSubControlRect( this, skinnable, subControl ); + rect = rect.marginsRemoved( skinnable->marginHint( subControl ) ); + + return qskUpdateArcNode( skinnable, + node, rect, skinnable->arcHints( subControl ) ); +} + +QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, + QSGNode* node, const QRectF& rect, const QskArcHints& hints ) +{ + return qskUpdateArcNode( skinnable, node, rect, hints ); } QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl ) { - const auto fillGradient = skinnable->gradientHint( subControl ); - return updateArcNode( skinnable, node, rect, fillGradient, subControl ); -} - -QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, - QSGNode* node, const QRectF& rect, const QskGradient& fillGradient, - QskAspect::Subcontrol subControl ) -{ - const auto metrics = skinnable->arcMetricsHint( subControl ); - const auto r = rect.marginsRemoved( skinnable->marginHint( subControl ) ); - - const qreal borderWidth = skinnable->metric( subControl | QskAspect::Border ); - - QColor borderColor; - if ( borderWidth > 0.0 ) - borderColor = skinnable->color( subControl | QskAspect::Border ); - return qskUpdateArcNode( skinnable, node, - r, borderWidth, borderColor, fillGradient, metrics ); -} - -QSGNode* QskSkinlet::updateArcNode( - const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect, - qreal borderWidth, const QColor& borderColor, - const QskGradient& fillGradient, const QskArcMetrics& metrics ) -{ - return qskUpdateArcNode( skinnable, node, rect, - borderWidth, borderColor, fillGradient, metrics ); -} - -QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, - QSGNode* node, qreal startAngle, qreal spanAngle, - QskAspect::Subcontrol subControl ) const -{ - const auto rect = qskSubControlRect( this, skinnable, subControl ); - - return updateArcNode( skinnable, node, - rect, startAngle, spanAngle, subControl ); -} - -QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, - QSGNode* node, const QRectF& rect, qreal startAngle, qreal spanAngle, - QskAspect::Subcontrol subControl ) -{ - const auto fillGradient = skinnable->gradientHint( subControl ); - return updateArcNode( skinnable, node, rect, - fillGradient, startAngle, spanAngle, subControl ); -} - -QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, - QSGNode* node, const QRectF& rect, const QskGradient& fillGradient, - qreal startAngle, qreal spanAngle, QskAspect::Subcontrol subControl ) -{ - auto arcMetrics = skinnable->arcMetricsHint( subControl ); - arcMetrics.setStartAngle( startAngle ); - arcMetrics.setSpanAngle( spanAngle ); - - const qreal borderWidth = skinnable->metric( subControl | QskAspect::Border ); - - QColor borderColor; - if ( borderWidth > 0.0 ) - borderColor = skinnable->color( subControl | QskAspect::Border ); - - const auto r = rect.marginsRemoved( skinnable->marginHint( subControl ) ); - return updateArcNode( skinnable, node, r, - borderWidth, borderColor, fillGradient, arcMetrics ); + rect, skinnable->arcHints( subControl ) ); } QSGNode* QskSkinlet::updateLineNode( const QskSkinnable* skinnable, diff --git a/src/controls/QskSkinlet.h b/src/controls/QskSkinlet.h index c13142bd..cf227580 100644 --- a/src/controls/QskSkinlet.h +++ b/src/controls/QskSkinlet.h @@ -23,10 +23,8 @@ class QskColorFilter; class QskGraphic; class QskTextOptions; class QskTextColors; -class QskBoxShapeMetrics; -class QskBoxBorderMetrics; -class QskBoxBorderColors; class QskBoxHints; +class QskArcHints; class QSGNode; @@ -76,13 +74,6 @@ class QSK_EXPORT QskSkinlet static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*, const QRectF&, QskAspect::Subcontrol ); - static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*, - const QRectF&, const QskGradient&, QskAspect::Subcontrol ); - - static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*, - const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, - const QskBoxBorderColors&, const QskGradient& ); - static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*, const QRectF&, const QskBoxHints& ); @@ -94,18 +85,7 @@ class QSK_EXPORT QskSkinlet const QRectF&, QskAspect::Subcontrol ); static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, - const QRectF&, const QskGradient&, QskAspect::Subcontrol ); - - static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, - const QRectF&, qreal borderWidth, const QColor& borderColor, - const QskGradient&, const QskArcMetrics& ); - - static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, - const QRectF&, qreal startAngle, qreal spanAngle, QskAspect::Subcontrol ); - - static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, - const QRectF&, const QskGradient&, qreal startAngle, qreal spanAngle, - QskAspect::Subcontrol ); + const QRectF&, const QskArcHints& ); static QSGNode* updateLineNode( const QskSkinnable*, QSGNode*, const QLineF&, QskAspect::Subcontrol ); @@ -156,10 +136,6 @@ class QSK_EXPORT QskSkinlet QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, QskAspect::Subcontrol ) const; - QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, - qreal startAngle, qreal spanAngle, - QskAspect::Subcontrol ) const; - QSGNode* updateBoxClipNode( const QskSkinnable*, QSGNode*, QskAspect::Subcontrol ) const; diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index 844af312..7010fb39 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -6,7 +6,7 @@ #include "QskSkinnable.h" #include "QskAnimationHint.h" -#include "QskArcMetrics.h" +#include "QskArcHints.h" #include "QskAspect.h" #include "QskColorFilter.h" #include "QskControl.h" @@ -637,9 +637,23 @@ QColor QskSkinnable::shadowColorHint( QskAspect aspect, QskSkinHintStatus* statu QskBoxHints QskSkinnable::boxHints( QskAspect aspect ) const { return QskBoxHints( - boxShapeHint( aspect ), boxBorderMetricsHint( aspect ), - boxBorderColorsHint( aspect ), gradientHint( aspect ), - shadowMetricsHint( aspect ), shadowColorHint( aspect ) ); + boxShapeHint( aspect ), + boxBorderMetricsHint( aspect ), + boxBorderColorsHint( aspect ), + gradientHint( aspect ), + shadowMetricsHint( aspect ), + shadowColorHint( aspect ) + ); +} + +QskArcHints QskSkinnable::arcHints( QskAspect aspect ) const +{ + return QskArcHints( + arcMetricsHint( aspect ), + metric( aspect | QskAspect::Border ), + color( aspect | QskAspect::Border ), + gradientHint( aspect ) + ); } bool QskSkinnable::setArcMetricsHint( diff --git a/src/controls/QskSkinnable.h b/src/controls/QskSkinnable.h index a4772448..26160b97 100644 --- a/src/controls/QskSkinnable.h +++ b/src/controls/QskSkinnable.h @@ -22,6 +22,7 @@ class QDebug; class QSGNode; class QQuickItem; +class QskArcHints; class QskArcMetrics; class QskControl; class QskAnimationHint; @@ -226,6 +227,7 @@ class QSK_EXPORT QskSkinnable QColor shadowColorHint( QskAspect, QskSkinHintStatus* = nullptr ) const; QskBoxHints boxHints( QskAspect ) const; + QskArcHints arcHints( QskAspect ) const; bool setArcMetricsHint( QskAspect, const QskArcMetrics& ); bool resetArcMetricsHint( QskAspect ); diff --git a/src/nodes/QskArcNode.cpp b/src/nodes/QskArcNode.cpp index e048f3b7..af5ee1b1 100644 --- a/src/nodes/QskArcNode.cpp +++ b/src/nodes/QskArcNode.cpp @@ -4,11 +4,10 @@ *****************************************************************************/ #include "QskArcNode.h" -#include "QskArcMetrics.h" +#include "QskArcHints.h" #include "QskArcRenderNode.h" #include "QskArcRenderer.h" #include "QskMargins.h" -#include "QskGradient.h" #include "QskSGNode.h" #include "QskRgbValue.h" @@ -58,24 +57,21 @@ QskArcNode::~QskArcNode() { } -void QskArcNode::setArcData( const QRectF& rect, - const QskArcMetrics& arcMetrics, const QskGradient& gradient ) -{ - setArcData( rect, arcMetrics, 0.0, QColor(), gradient ); -} - -void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics, - const qreal borderWidth, const QColor& borderColor, const QskGradient& gradient ) +void QskArcNode::setArcData( const QRectF& rect, const QskArcHints& hints ) { using namespace QskSGNode; QskArcRenderNode* arcNode = nullptr; QskArcRenderNode* fillNode = nullptr; - if ( !( rect.isEmpty() || arcMetrics.isNull() ) ) + if ( !rect.isEmpty() && hints.isVisible() ) { + const auto& gradient = hints.gradient; + const auto borderWidth = hints.borderWidth; + const auto borderColor = hints.borderColor; + const bool radial = false; - const auto metricsArc = arcMetrics.toAbsolute( rect.size() ); + const auto metricsArc = hints.metrics.toAbsolute( rect.size() ); const auto hasFilling = gradient.isVisible(); const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor ); diff --git a/src/nodes/QskArcNode.h b/src/nodes/QskArcNode.h index 59ca1190..3bfcb916 100644 --- a/src/nodes/QskArcNode.h +++ b/src/nodes/QskArcNode.h @@ -9,8 +9,7 @@ #include "QskGlobal.h" #include -class QskArcMetrics; -class QskGradient; +class QskArcHints; class QSK_EXPORT QskArcNode : public QSGNode { @@ -18,10 +17,7 @@ class QSK_EXPORT QskArcNode : public QSGNode QskArcNode(); ~QskArcNode() override; - void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& ); - - void setArcData( const QRectF&, const QskArcMetrics&, - qreal borderWidth, const QColor& borderColor, const QskGradient& ); + void setArcData( const QRectF&, const QskArcHints& ); }; #endif diff --git a/src/nodes/QskBoxNode.cpp b/src/nodes/QskBoxNode.cpp index a787c8e9..64ff3485 100644 --- a/src/nodes/QskBoxNode.cpp +++ b/src/nodes/QskBoxNode.cpp @@ -8,12 +8,8 @@ #include "QskBoxRectangleNode.h" #include "QskSGNode.h" -#include "QskGradient.h" +#include "QskBoxHints.h" #include "QskGradientDirection.h" -#include "QskShadowMetrics.h" -#include "QskBoxBorderMetrics.h" -#include "QskBoxBorderColors.h" -#include "QskBoxShapeMetrics.h" #include "QskRgbValue.h" namespace @@ -60,10 +56,8 @@ QskBoxNode::~QskBoxNode() { } -void QskBoxNode::updateNode( const QQuickWindow* window, const QRectF& rect, - const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics, - const QskBoxBorderColors& borderColors, const QskGradient& gradient, - const QskShadowMetrics& shadowMetrics, const QColor& shadowColor ) +void QskBoxNode::updateNode( const QQuickWindow* window, + const QRectF& rect, const QskBoxHints& hints ) { using namespace QskSGNode; @@ -74,6 +68,13 @@ void QskBoxNode::updateNode( const QQuickWindow* window, const QRectF& rect, if ( !rect.isEmpty() ) { + const auto& shapeMetrics = hints.shape; + const auto& borderMetrics = hints.borderMetrics; + const auto& borderColors = hints.borderColors; + const auto& gradient = hints.gradient; + const auto& shadowMetrics = hints.shadowMetrics; + const auto& shadowColor = hints.shadowColor; + const auto hasFilling = gradient.isVisible(); const auto hasBorder = !borderMetrics.isNull() && borderColors.isVisible(); const auto hasShadow = !shadowMetrics.isNull() && QskRgb::isVisible( shadowColor ); diff --git a/src/nodes/QskBoxNode.h b/src/nodes/QskBoxNode.h index 8e14d668..7e2ffd3f 100644 --- a/src/nodes/QskBoxNode.h +++ b/src/nodes/QskBoxNode.h @@ -9,14 +9,8 @@ #include "QskGlobal.h" #include -class QskShadowMetrics; -class QskBoxShapeMetrics; -class QskBoxBorderMetrics; -class QskBoxBorderColors; -class QskGradient; -class QskShadowMetrics; +class QskBoxHints; class QQuickWindow; -class QColor; class QSK_EXPORT QskBoxNode : public QSGNode { @@ -24,10 +18,7 @@ class QSK_EXPORT QskBoxNode : public QSGNode QskBoxNode(); ~QskBoxNode() override; - void updateNode( const QQuickWindow*, const QRectF&, - const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, - const QskBoxBorderColors&, const QskGradient&, - const QskShadowMetrics&, const QColor& shadowColor ); + void updateNode( const QQuickWindow*, const QRectF&, const QskBoxHints& ); }; #endif