QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskArcNode.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskArcNode.h"
7#include "QskArcMetrics.h"
8#include "QskArcRenderNode.h"
9#include "QskArcRenderer.h"
10#include "QskMargins.h"
11#include "QskGradient.h"
12#include "QskSGNode.h"
13#include "QskRgbValue.h"
14
15namespace
16{
17 enum NodeRole
18 {
19 /*
20 If possible border + filling will be displayed by ArcRole
21 Otherwise ArcRole displays the border and FillRole the filling
22 */
23
24 ArcRole,
25 FillRole
26 };
27}
28
29static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
30{
31 static const QVector< quint8 > roles = { ArcRole, FillRole };
32
33 auto oldNode = QskSGNode::findChildNode( parentNode, role );
34 QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
35}
36
37template< typename Node >
38inline Node* qskNode( QSGNode* parentNode, quint8 role )
39{
40 using namespace QskSGNode;
41
42 auto node = static_cast< Node* > ( findChildNode( parentNode, role ) );
43
44 if ( node == nullptr )
45 {
46 node = new Node();
47 setNodeRole( node, role );
48 }
49
50 return node;
51}
52
53QskArcNode::QskArcNode()
54{
55}
56
57QskArcNode::~QskArcNode()
58{
59}
60
61void QskArcNode::setArcData( const QRectF& rect,
62 const QskArcMetrics& arcMetrics, const QskGradient& gradient )
63{
64 setArcData( rect, arcMetrics, 0.0, QColor(), gradient );
65}
66
67void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
68 const qreal borderWidth, const QColor& borderColor, const QskGradient& gradient )
69{
70 using namespace QskSGNode;
71
72 QskArcRenderNode* arcNode = nullptr;
73 QskArcRenderNode* fillNode = nullptr;
74
75 if ( !( rect.isEmpty() || arcMetrics.isNull() ) )
76 {
77 const bool radial = false;
78 const auto metricsArc = arcMetrics.toAbsolute( rect.size() );
79
80 const auto hasFilling = gradient.isVisible();
81 const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor );
82
83 if ( hasBorder || hasFilling )
84 {
85 arcNode = qskNode< QskArcRenderNode >( this, ArcRole );
86
87 if ( hasBorder && hasFilling )
88 {
89 const bool doCombine = arcNode->hasHint( QskFillNode::PreferColoredGeometry )
90 && QskArcRenderer::isGradientSupported( rect, metricsArc, gradient );
91
92 if ( !doCombine )
93 fillNode = qskNode< QskArcRenderNode >( this, FillRole );
94 }
95
96 if ( fillNode )
97 {
98 arcNode->updateBorder( rect, metricsArc,
99 radial, borderWidth, borderColor );
100
101 fillNode->updateFilling( rect, metricsArc, radial, borderWidth, gradient );
102 }
103 else
104 {
105 arcNode->updateArc( rect, metricsArc,
106 radial, borderWidth, borderColor, gradient );
107 }
108 }
109 }
110
111 qskUpdateChildren( this, ArcRole, arcNode );
112 qskUpdateChildren( this, FillRole, fillNode );
113}