QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskProgressRingSkinlet.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskProgressRingSkinlet.h"
7#include "QskArcMetrics.h"
8#include "QskProgressRing.h"
9#include "QskIntervalF.h"
10
11using Q = QskProgressRing;
12
13QskProgressRingSkinlet::QskProgressRingSkinlet( QskSkin* skin )
14 : Inherited( skin )
15{
16}
17
18QskProgressRingSkinlet::~QskProgressRingSkinlet()
19{
20}
21
22QRectF QskProgressRingSkinlet::subControlRect(
23 const QskSkinnable* skinnable, const QRectF& contentsRect,
24 QskAspect::Subcontrol subControl ) const
25{
26 if( subControl == Q::Groove || subControl == Q::Fill )
27 return contentsRect;
28
29 return Inherited::subControlRect( skinnable, contentsRect, subControl );
30}
31
32QSGNode* QskProgressRingSkinlet::updateGrooveNode(
33 const QskProgressIndicator* indicator, QSGNode* node ) const
34{
35 return updateArcNode( indicator, node, Q::Groove );
36}
37
38QSGNode* QskProgressRingSkinlet::updateFillNode(
39 const QskProgressIndicator* indicator, QSGNode* node ) const
40{
41 const auto ring = static_cast< const Q* >( indicator );
42
43 const auto subControl = Q::Fill;
44
45 const auto rect = ring->subControlRect( subControl );
46 if ( rect.isEmpty() )
47 return nullptr;
48
49 const auto metrics = ring->arcMetricsHint( subControl );
50 if ( metrics.isNull() )
51 return nullptr;
52
53 auto gradient = ring->gradientHint( subControl );
54 if ( !gradient.isVisible() )
55 return nullptr;
56
57 const auto intv = fillInterval( ring );
58
59 if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
60 {
61 const auto stops = qskExtractedGradientStops( gradient.stops(),
62 intv.lowerBound(), intv.upperBound() );
63
64 gradient.setStops( stops );
65
66 if ( metrics.spanAngle() < 0.0 )
67 gradient.reverse();
68 }
69
70 const auto startAngle = metrics.startAngle() + intv.lowerBound() * metrics.spanAngle();
71 const auto spanAngle = intv.upperBound() * metrics.spanAngle();
72
73 return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl );
74}
75
76QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
77 Qt::SizeHint which, const QSizeF& constraint ) const
78{
79 if ( which != Qt::PreferredSize )
80 return QSizeF();
81
82 auto hint = skinnable->strutSizeHint( Q::Fill );
83 hint = hint.expandedTo( skinnable->strutSizeHint( Q::Groove ) );
84
85 if ( !constraint.isEmpty() )
86 {
87 const qreal aspectRatio = hint.isEmpty() ? 1.0 : hint.width() / hint.height();
88
89 if ( constraint.width() >= 0.0 )
90 hint.setHeight( constraint.width() / aspectRatio );
91 else
92 hint.setWidth( constraint.height() * aspectRatio );
93 }
94
95 return hint;
96}
97
98QskIntervalF QskProgressRingSkinlet::fillInterval(
99 const QskProgressIndicator* indicator ) const
100{
101 qreal pos1, pos2;
102
103 if ( indicator->isIndeterminate() )
104 {
105 pos1 = pos2 = indicator->positionHint( QskProgressIndicator::Fill );
106 }
107 else
108 {
109 pos1 = indicator->valueAsRatio( indicator->origin() );
110 pos2 = indicator->valueAsRatio( indicator->value() );
111 }
112
113 if ( pos1 > pos2 )
114 std::swap( pos1, pos2 );
115
116 return QskIntervalF( pos1, pos2 );
117}
118
119#include "moc_QskProgressRingSkinlet.cpp"
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
Definition QskAspect.h:104
QRectF subControlRect(QskAspect::Subcontrol) const
QSizeF strutSizeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a strut size hint.