QskArcNode as composite of fill/border nodes
This commit is contained in:
parent
73dd618626
commit
328e6a9e6f
@ -205,25 +205,16 @@ static inline QSGNode* qskUpdateBoxNode(
|
|||||||
|
|
||||||
static inline QSGNode* qskUpdateArcNode(
|
static inline QSGNode* qskUpdateArcNode(
|
||||||
const QskSkinnable*, QSGNode* node, const QRectF& rect,
|
const QskSkinnable*, QSGNode* node, const QRectF& rect,
|
||||||
const QskGradient& fillGradient, const QskArcMetrics& metrics )
|
const QskGradient& gradient, const QskArcMetrics& metrics )
|
||||||
{
|
{
|
||||||
if ( rect.isEmpty() )
|
if ( rect.isEmpty() || !qskIsArcVisible( metrics, gradient ) )
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const auto rx = 0.5 * rect.width();
|
|
||||||
const auto ry = 0.5 * rect.height();
|
|
||||||
|
|
||||||
const auto absoluteMetrics = metrics.toAbsolute( rx, ry );
|
|
||||||
|
|
||||||
if ( !qskIsArcVisible( absoluteMetrics, fillGradient ) )
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto arcNode = static_cast< QskArcNode* >( node );
|
auto arcNode = static_cast< QskArcNode* >( node );
|
||||||
|
|
||||||
if ( arcNode == nullptr )
|
if ( arcNode == nullptr )
|
||||||
arcNode = new QskArcNode();
|
arcNode = new QskArcNode();
|
||||||
|
|
||||||
arcNode->setArcData( rect, absoluteMetrics, fillGradient );
|
arcNode->setArcData( rect, metrics, gradient );
|
||||||
|
|
||||||
return arcNode;
|
return arcNode;
|
||||||
}
|
}
|
||||||
|
@ -6,16 +6,21 @@
|
|||||||
#include "QskArcNode.h"
|
#include "QskArcNode.h"
|
||||||
#include "QskArcRenderer.h"
|
#include "QskArcRenderer.h"
|
||||||
#include "QskArcMetrics.h"
|
#include "QskArcMetrics.h"
|
||||||
|
#include "QskMargins.h"
|
||||||
#include "QskGradient.h"
|
#include "QskGradient.h"
|
||||||
#include "QskGradientDirection.h"
|
#include "QskGradientDirection.h"
|
||||||
|
#include "QskShapeNode.h"
|
||||||
|
#include "QskStrokeNode.h"
|
||||||
|
#include "QskSGNode.h"
|
||||||
|
|
||||||
|
#include <qpen.h>
|
||||||
#include <qpainterpath.h>
|
#include <qpainterpath.h>
|
||||||
|
|
||||||
#define LINEAR_GRADIENT_HACK 1
|
#define LINEAR_GRADIENT_HACK 1
|
||||||
|
|
||||||
#if LINEAR_GRADIENT_HACK
|
#if LINEAR_GRADIENT_HACK
|
||||||
|
|
||||||
static inline QskGradient buildGradient( QskGradient::Type type,
|
static inline QskGradient qskBuildGradient( QskGradient::Type type,
|
||||||
const QRectF& rect, const QskArcMetrics& metrics,
|
const QRectF& rect, const QskArcMetrics& metrics,
|
||||||
const QskGradientStops& stops )
|
const QskGradientStops& stops )
|
||||||
{
|
{
|
||||||
@ -63,8 +68,9 @@ static inline QskGradient buildGradient( QskGradient::Type type,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline QskGradient effectiveGradient( const QRectF& rect,
|
static inline QskGradient qskEffectiveGradient(
|
||||||
const QskArcMetrics& metrics, const QskGradient& gradient )
|
const QskGradient& gradient, const QRectF& rect,
|
||||||
|
const QskArcMetrics& metrics )
|
||||||
{
|
{
|
||||||
if ( !gradient.isMonochrome() )
|
if ( !gradient.isMonochrome() )
|
||||||
{
|
{
|
||||||
@ -91,7 +97,7 @@ static inline QskGradient effectiveGradient( const QRectF& rect,
|
|||||||
const auto type = gradient.linearDirection().isHorizontal()
|
const auto type = gradient.linearDirection().isHorizontal()
|
||||||
? QskGradient::Conic : QskGradient::Radial;
|
? QskGradient::Conic : QskGradient::Radial;
|
||||||
|
|
||||||
return buildGradient( type, rect, metrics, gradient.stops() );
|
return qskBuildGradient( type, rect, metrics, gradient.stops() );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -99,6 +105,29 @@ static inline QskGradient effectiveGradient( const QRectF& rect,
|
|||||||
return gradient;
|
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 )
|
||||||
|
{
|
||||||
|
if ( borderWidth <= 0.0 )
|
||||||
|
return rect;
|
||||||
|
|
||||||
|
return qskValidOrEmptyInnerRect( rect, QskMargins( 0.5 * borderWidth ) );
|
||||||
|
}
|
||||||
|
|
||||||
QskArcNode::QskArcNode()
|
QskArcNode::QskArcNode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -108,10 +137,74 @@ QskArcNode::~QskArcNode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QskArcNode::setArcData( const QRectF& rect,
|
void QskArcNode::setArcData( const QRectF& rect,
|
||||||
const QskArcMetrics& metrics, const QskGradient& gradient )
|
const QskArcMetrics& arcMetrics, const QskGradient& fillGradient )
|
||||||
{
|
{
|
||||||
const auto path = QskArcRenderer::arcPath( rect, metrics );
|
setArcData( rect, arcMetrics, 0.0, QColor(), fillGradient );
|
||||||
|
}
|
||||||
updateNode( path, QTransform(), rect,
|
|
||||||
effectiveGradient( rect, metrics, gradient ) );
|
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
|
||||||
|
qreal borderWidth, const QColor borderColor, const QskGradient& fillGradient )
|
||||||
|
{
|
||||||
|
enum NodeRole
|
||||||
|
{
|
||||||
|
FillRole,
|
||||||
|
BorderRole
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto metrics = qskEffectiveMetrics( arcMetrics, rect );
|
||||||
|
const auto gradient = qskEffectiveGradient( fillGradient, rect, metrics );
|
||||||
|
|
||||||
|
auto fillNode = static_cast< QskShapeNode* >(
|
||||||
|
QskSGNode::findChildNode( this, FillRole ) );
|
||||||
|
|
||||||
|
auto borderNode = static_cast< QskStrokeNode* >(
|
||||||
|
QskSGNode::findChildNode( this, BorderRole ) );
|
||||||
|
|
||||||
|
const auto arcRect = qskEffectiveRect( rect, borderWidth );
|
||||||
|
if ( arcRect.isEmpty() )
|
||||||
|
{
|
||||||
|
delete fillNode;
|
||||||
|
delete borderNode;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto path = QskArcRenderer::arcPath( arcRect, metrics );
|
||||||
|
|
||||||
|
if ( gradient.isVisible() && !metrics.isNull() )
|
||||||
|
{
|
||||||
|
if ( fillNode == nullptr )
|
||||||
|
{
|
||||||
|
fillNode = new QskShapeNode;
|
||||||
|
QskSGNode::setNodeRole( fillNode, FillRole );
|
||||||
|
|
||||||
|
prependChildNode( fillNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
fillNode->updateNode( path, QTransform(), arcRect, gradient );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete fillNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( borderWidth > 0.0 && borderColor.alpha() > 0 )
|
||||||
|
{
|
||||||
|
if ( borderNode == nullptr )
|
||||||
|
{
|
||||||
|
borderNode = new QskStrokeNode;
|
||||||
|
QskSGNode::setNodeRole( borderNode, BorderRole );
|
||||||
|
|
||||||
|
appendChildNode( borderNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
QPen pen( borderColor, borderWidth );
|
||||||
|
pen.setCapStyle( Qt::FlatCap );
|
||||||
|
|
||||||
|
borderNode->updateNode( path, QTransform(), pen );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete borderNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ class QSK_EXPORT QskArcNode : public QskShapeNode
|
|||||||
~QskArcNode() override;
|
~QskArcNode() override;
|
||||||
|
|
||||||
void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& );
|
void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& );
|
||||||
|
void setArcData( const QRectF&, const QskArcMetrics&,
|
||||||
|
qreal borderWidth, const QColor borderColor, const QskGradient& );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user