qskinny/src/nodes/QskArcNode.cpp

114 lines
3.1 KiB
C++
Raw Normal View History

2023-04-06 07:23:37 +00:00
/******************************************************************************
2024-01-17 13:31:45 +00:00
* QSkinny - Copyright (C) The authors
2023-04-06 07:23:37 +00:00
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskArcNode.h"
#include "QskArcMetrics.h"
2024-09-11 08:24:22 +00:00
#include "QskArcRenderNode.h"
#include "QskArcRenderer.h"
#include "QskMargins.h"
2022-06-01 14:57:57 +00:00
#include "QskGradient.h"
#include "QskSGNode.h"
2024-09-24 08:14:26 +00:00
#include "QskRgbValue.h"
namespace
{
enum NodeRole
{
2024-09-23 14:04:09 +00:00
/*
If possible border + filling will be displayed by ArcRole
Otherwise ArcRole displays the border and FillRole the filling
*/
ArcRole,
FillRole
};
}
2024-09-23 14:04:09 +00:00
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
2023-04-14 07:47:10 +00:00
{
static const QVector< quint8 > roles = { ArcRole, FillRole };
2023-04-14 07:47:10 +00:00
2024-09-23 14:04:09 +00:00
auto oldNode = QskSGNode::findChildNode( parentNode, role );
QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
2022-06-01 14:57:57 +00:00
}
2024-09-11 08:24:22 +00:00
template< typename Node >
2024-09-23 14:04:09 +00:00
inline Node* qskNode( QSGNode* parentNode, quint8 role )
{
2024-09-11 08:24:22 +00:00
using namespace QskSGNode;
2024-09-23 14:04:09 +00:00
auto node = static_cast< Node* > ( findChildNode( parentNode, role ) );
2024-09-23 14:04:09 +00:00
if ( node == nullptr )
{
node = new Node();
setNodeRole( node, role );
}
2024-09-23 14:04:09 +00:00
return node;
}
QskArcNode::QskArcNode()
{
}
QskArcNode::~QskArcNode()
{
}
void QskArcNode::setArcData( const QRectF& rect,
2024-09-11 08:24:22 +00:00
const QskArcMetrics& arcMetrics, const QskGradient& gradient )
{
setArcData( rect, arcMetrics, 0.0, QColor(), gradient );
}
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
2024-09-11 08:24:22 +00:00
const qreal borderWidth, const QColor& borderColor, const QskGradient& gradient )
{
2024-09-23 14:04:09 +00:00
using namespace QskSGNode;
2024-09-23 14:04:09 +00:00
QskArcRenderNode* arcNode = nullptr;
QskArcRenderNode* fillNode = nullptr;
2024-09-23 14:04:09 +00:00
if ( !( rect.isEmpty() || arcMetrics.isNull() ) )
{
2024-09-23 14:04:09 +00:00
const bool radial = false;
const auto metricsArc = arcMetrics.toAbsolute( rect.size() );
2024-09-23 14:04:09 +00:00
const auto hasFilling = gradient.isVisible();
2024-09-24 08:14:26 +00:00
const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor );
2024-09-23 14:04:09 +00:00
if ( hasBorder || hasFilling )
{
arcNode = qskNode< QskArcRenderNode >( this, ArcRole );
if ( hasBorder && hasFilling )
{
2024-09-24 08:17:10 +00:00
const bool doCombine = arcNode->hasHint( QskFillNode::PreferColoredGeometry )
&& QskArcRenderer::isGradientSupported( rect, metricsArc, gradient );
if ( !doCombine )
2024-09-23 14:04:09 +00:00
fillNode = qskNode< QskArcRenderNode >( this, FillRole );
}
if ( fillNode )
{
arcNode->updateBorder( rect, metricsArc,
radial, borderWidth, borderColor );
fillNode->updateFilling( rect, metricsArc, radial, borderWidth, gradient );
}
else
{
arcNode->updateArc( rect, metricsArc,
radial, borderWidth, borderColor, gradient );
}
}
}
2024-09-23 14:04:09 +00:00
qskUpdateChildren( this, ArcRole, arcNode );
qskUpdateChildren( this, FillRole, fillNode );
}