QskArcHints introduced, API mess for defining arcs in QskSkinlet reduced

This commit is contained in:
Uwe Rathmann 2025-03-12 10:40:03 +01:00
parent fbcce286d4
commit ab2c36ea5a
11 changed files with 191 additions and 156 deletions

View File

@ -8,7 +8,7 @@
#include <QskSkinlet.h> #include <QskSkinlet.h>
#include <QskArcNode.h> #include <QskArcNode.h>
#include <QskArcMetrics.h> #include <QskArcHints.h>
#include <QskShadowMetrics.h> #include <QskShadowMetrics.h>
#include <QskSGNode.h> #include <QskSGNode.h>
#include <QskRgbValue.h> #include <QskRgbValue.h>
@ -107,14 +107,7 @@ namespace
return nullptr; return nullptr;
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, arc->arcHints( Q::Arc ) );
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 );
return arcNode; return arcNode;
} }

View File

@ -5,6 +5,7 @@
list(APPEND HEADERS list(APPEND HEADERS
common/QskArcMetrics.h common/QskArcMetrics.h
common/QskArcHints.h
common/QskAspect.h common/QskAspect.h
common/QskBoxBorderColors.h common/QskBoxBorderColors.h
common/QskBoxBorderMetrics.h common/QskBoxBorderMetrics.h
@ -41,6 +42,7 @@ list(APPEND HEADERS
list(APPEND SOURCES list(APPEND SOURCES
common/QskArcMetrics.cpp common/QskArcMetrics.cpp
common/QskArcHints.cpp
common/QskAspect.cpp common/QskAspect.cpp
common/QskBoxBorderColors.cpp common/QskBoxBorderColors.cpp
common/QskBoxBorderMetrics.cpp common/QskBoxBorderMetrics.cpp

View File

@ -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.h>
QDebug operator<<( QDebug debug, const QskArcHints& hints )
{
debug << hints.metrics << hints.borderWidth
<< hints.borderColor << hints.gradient;
return debug;
}
#endif
#include "moc_QskArcHints.cpp"

47
src/common/QskArcHints.h Normal file
View File

@ -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 <qcolor.h>
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

View File

@ -4,7 +4,7 @@
*****************************************************************************/ *****************************************************************************/
#include "QskProgressRingSkinlet.h" #include "QskProgressRingSkinlet.h"
#include "QskArcMetrics.h" #include "QskArcHints.h"
#include "QskProgressRing.h" #include "QskProgressRing.h"
#include "QskIntervalF.h" #include "QskIntervalF.h"
@ -85,8 +85,12 @@ QSGNode* QskProgressRingSkinlet::updateGrooveNode(
endAngle = fillAngles.first - 360.0 + spacing; endAngle = fillAngles.first - 360.0 + spacing;
} }
return updateArcNode( ring, node, auto hints = indicator->arcHints( Q::Groove );
startAngle, endAngle - startAngle, 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() ) if ( rect.isEmpty() )
return nullptr; return nullptr;
const auto metrics = ring->arcMetricsHint( subControl ); auto hints = ring->arcHints( subControl );
if ( metrics.isNull() ) if ( !hints.isVisible() )
return nullptr;
auto gradient = ring->gradientHint( subControl );
if ( !gradient.isVisible() )
return nullptr; return nullptr;
const auto intv = qskFillInterval( ring ); const auto intv = qskFillInterval( ring );
auto& gradient = hints.gradient;
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
{ {
const auto stops = qskExtractedGradientStops( gradient.stops(), const auto stops = qskExtractedGradientStops( gradient.stops(),
@ -121,14 +123,15 @@ QSGNode* QskProgressRingSkinlet::updateFillNode(
gradient.setStops( stops ); gradient.setStops( stops );
if ( metrics.spanAngle() < 0.0 ) if ( hints.metrics.spanAngle() < 0.0 )
gradient.reverse(); 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, return updateArcNode( ring, node, rect, hints );
angles.first, angles.second - angles.first, subControl );
} }
QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable, QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,

View File

@ -7,9 +7,7 @@
#include "QskArcNode.h" #include "QskArcNode.h"
#include "QskAspect.h" #include "QskAspect.h"
#include "QskArcMetrics.h" #include "QskArcHints.h"
#include "QskBoxBorderColors.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxNode.h" #include "QskBoxNode.h"
#include "QskBoxRectangleNode.h" #include "QskBoxRectangleNode.h"
#include "QskBoxShapeMetrics.h" #include "QskBoxShapeMetrics.h"
@ -156,18 +154,6 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
return !borderMetrics.isNull() && borderColors.isVisible(); 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 ) static inline bool qskIsLineVisible( const QColor& lineColor, qreal lineWidth )
{ {
return ( lineWidth > 0.0 ) && lineColor.isValid() && ( lineColor.alpha() > 0 ); return ( lineWidth > 0.0 ) && lineColor.isValid() && ( lineColor.alpha() > 0 );
@ -223,21 +209,20 @@ static inline QSGNode* qskUpdateBoxNode( const QskSkinnable* skinnable,
return nullptr; return nullptr;
} }
static inline QSGNode* qskUpdateArcNode( static inline QSGNode* qskUpdateArcNode( const QskSkinnable* skinnable,
const QskSkinnable*, QSGNode* node, const QRectF& rect, QSGNode* node, const QRectF& rect, const QskArcHints& hints )
qreal borderWidth, const QColor borderColor,
const QskGradient& gradient, const QskArcMetrics& metrics )
{ {
if ( rect.isEmpty() ) Q_UNUSED( skinnable );
return nullptr;
if ( !qskIsArcVisible( metrics, borderWidth, borderColor, gradient ) ) if ( !rect.isEmpty() && hints.isVisible() )
return nullptr; {
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, hints );
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); return arcNode;
arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient ); }
return arcNode; return nullptr;
} }
static inline QSGNode* qskUpdateLineNode( static inline QSGNode* qskUpdateLineNode(
@ -496,79 +481,24 @@ QSGNode* QskSkinlet::updateInterpolatedBoxNode(
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, QskAspect::Subcontrol subControl ) const QSGNode* node, QskAspect::Subcontrol subControl ) const
{ {
const auto rect = qskSubControlRect( this, skinnable, subControl ); auto rect = qskSubControlRect( this, skinnable, subControl );
return updateArcNode( skinnable, node, rect, 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* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl ) 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, return qskUpdateArcNode( skinnable, node,
r, borderWidth, borderColor, fillGradient, metrics ); rect, skinnable->arcHints( subControl ) );
}
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 );
} }
QSGNode* QskSkinlet::updateLineNode( const QskSkinnable* skinnable, QSGNode* QskSkinlet::updateLineNode( const QskSkinnable* skinnable,

View File

@ -23,10 +23,8 @@ class QskColorFilter;
class QskGraphic; class QskGraphic;
class QskTextOptions; class QskTextOptions;
class QskTextColors; class QskTextColors;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
class QskBoxHints; class QskBoxHints;
class QskArcHints;
class QSGNode; class QSGNode;
@ -87,18 +85,7 @@ class QSK_EXPORT QskSkinlet
const QRectF&, QskAspect::Subcontrol ); const QRectF&, QskAspect::Subcontrol );
static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
const QRectF&, const QskGradient&, QskAspect::Subcontrol ); const QRectF&, const QskArcHints& );
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 );
static QSGNode* updateLineNode( const QskSkinnable*, QSGNode*, static QSGNode* updateLineNode( const QskSkinnable*, QSGNode*,
const QLineF&, QskAspect::Subcontrol ); const QLineF&, QskAspect::Subcontrol );
@ -149,10 +136,6 @@ class QSK_EXPORT QskSkinlet
QSGNode* updateArcNode( const QskSkinnable*, QSGNode*, QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
QskAspect::Subcontrol ) const; QskAspect::Subcontrol ) const;
QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
qreal startAngle, qreal spanAngle,
QskAspect::Subcontrol ) const;
QSGNode* updateBoxClipNode( const QskSkinnable*, QSGNode*, QSGNode* updateBoxClipNode( const QskSkinnable*, QSGNode*,
QskAspect::Subcontrol ) const; QskAspect::Subcontrol ) const;

View File

@ -6,7 +6,7 @@
#include "QskSkinnable.h" #include "QskSkinnable.h"
#include "QskAnimationHint.h" #include "QskAnimationHint.h"
#include "QskArcMetrics.h" #include "QskArcHints.h"
#include "QskAspect.h" #include "QskAspect.h"
#include "QskColorFilter.h" #include "QskColorFilter.h"
#include "QskControl.h" #include "QskControl.h"
@ -637,9 +637,23 @@ QColor QskSkinnable::shadowColorHint( QskAspect aspect, QskSkinHintStatus* statu
QskBoxHints QskSkinnable::boxHints( QskAspect aspect ) const QskBoxHints QskSkinnable::boxHints( QskAspect aspect ) const
{ {
return QskBoxHints( return QskBoxHints(
boxShapeHint( aspect ), boxBorderMetricsHint( aspect ), boxShapeHint( aspect ),
boxBorderColorsHint( aspect ), gradientHint( aspect ), boxBorderMetricsHint( aspect ),
shadowMetricsHint( aspect ), shadowColorHint( 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( bool QskSkinnable::setArcMetricsHint(

View File

@ -22,6 +22,7 @@ class QDebug;
class QSGNode; class QSGNode;
class QQuickItem; class QQuickItem;
class QskArcHints;
class QskArcMetrics; class QskArcMetrics;
class QskControl; class QskControl;
class QskAnimationHint; class QskAnimationHint;
@ -226,6 +227,7 @@ class QSK_EXPORT QskSkinnable
QColor shadowColorHint( QskAspect, QskSkinHintStatus* = nullptr ) const; QColor shadowColorHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
QskBoxHints boxHints( QskAspect ) const; QskBoxHints boxHints( QskAspect ) const;
QskArcHints arcHints( QskAspect ) const;
bool setArcMetricsHint( QskAspect, const QskArcMetrics& ); bool setArcMetricsHint( QskAspect, const QskArcMetrics& );
bool resetArcMetricsHint( QskAspect ); bool resetArcMetricsHint( QskAspect );

View File

@ -4,11 +4,10 @@
*****************************************************************************/ *****************************************************************************/
#include "QskArcNode.h" #include "QskArcNode.h"
#include "QskArcMetrics.h" #include "QskArcHints.h"
#include "QskArcRenderNode.h" #include "QskArcRenderNode.h"
#include "QskArcRenderer.h" #include "QskArcRenderer.h"
#include "QskMargins.h" #include "QskMargins.h"
#include "QskGradient.h"
#include "QskSGNode.h" #include "QskSGNode.h"
#include "QskRgbValue.h" #include "QskRgbValue.h"
@ -58,24 +57,21 @@ QskArcNode::~QskArcNode()
{ {
} }
void QskArcNode::setArcData( const QRectF& rect, void QskArcNode::setArcData( const QRectF& rect, const QskArcHints& hints )
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 )
{ {
using namespace QskSGNode; using namespace QskSGNode;
QskArcRenderNode* arcNode = nullptr; QskArcRenderNode* arcNode = nullptr;
QskArcRenderNode* fillNode = 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 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 hasFilling = gradient.isVisible();
const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor ); const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor );

View File

@ -9,8 +9,7 @@
#include "QskGlobal.h" #include "QskGlobal.h"
#include <qsgnode.h> #include <qsgnode.h>
class QskArcMetrics; class QskArcHints;
class QskGradient;
class QSK_EXPORT QskArcNode : public QSGNode class QSK_EXPORT QskArcNode : public QSGNode
{ {
@ -18,10 +17,7 @@ class QSK_EXPORT QskArcNode : public QSGNode
QskArcNode(); QskArcNode();
~QskArcNode() override; ~QskArcNode() override;
void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& ); void setArcData( const QRectF&, const QskArcHints& );
void setArcData( const QRectF&, const QskArcMetrics&,
qreal borderWidth, const QColor& borderColor, const QskGradient& );
}; };
#endif #endif