QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskProgressIndicator.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskProgressIndicator.h"
7
8#include "QskIntervalF.h"
9#include "QskFunctions.h"
10#include "QskAnimator.h"
11#include "QskAspect.h"
12
13QSK_SUBCONTROL( QskProgressIndicator, Groove )
14QSK_SUBCONTROL( QskProgressIndicator, Fill )
15
16namespace
17{
18 class PositionAnimator : public QskAnimator
19 {
20 public:
21 PositionAnimator( QskProgressIndicator* indicator )
22 : m_indicator( indicator )
23 {
24 setAutoRepeat( true );
25 setDuration( 1300 );
26
27 setWindow( indicator->window() );
28 }
29
30 void advance( qreal value ) override
31 {
32 if ( m_indicator->setPositionHint( QskProgressIndicator::Fill, value ) )
33 m_indicator->update();
34 }
35
36 private:
37 QskProgressIndicator* m_indicator;
38 };
39}
40
41class QskProgressIndicator::PrivateData
42{
43 public:
44 void updateIndeterminateAnimator( QskProgressIndicator* indicator )
45 {
46 if ( !isIndeterminate )
47 {
48 delete animator;
49 animator = nullptr;
50
51 return;
52 }
53
54 if ( indicator->window() && indicator->isVisible() )
55 {
56 if ( animator == nullptr )
57 animator = new PositionAnimator( indicator );
58
59 animator->start();
60 }
61 else
62 {
63 if ( animator )
64 animator->stop();
65 }
66 }
67
68 PositionAnimator* animator = nullptr;
69
70 qreal value = 0.0;
71 qreal origin = 0.0;
72
73 bool hasOrigin = false;
74 bool isIndeterminate = false;
75};
76
77QskProgressIndicator::QskProgressIndicator( qreal min, qreal max, QQuickItem* parent )
78 : QskBoundedControl( min, max, parent )
79 , m_data( new PrivateData )
80{
81 m_data->value = minimum();
82
83 connect( this, &QskBoundedControl::boundariesChanged,
84 this, &QskProgressIndicator::adjustValue );
85}
86
87QskProgressIndicator::QskProgressIndicator( QQuickItem* parent )
88 : QskProgressIndicator( 0.0, 100.0, parent )
89{
90}
91
92QskProgressIndicator::QskProgressIndicator( const QskIntervalF& boundaries, QQuickItem* parent )
93 : QskProgressIndicator( boundaries.lowerBound(), boundaries.upperBound(), parent )
94{
95}
96
97QskProgressIndicator::~QskProgressIndicator()
98{
99 delete m_data->animator;
100}
101
102bool QskProgressIndicator::isIndeterminate() const
103{
104 return m_data->isIndeterminate;
105}
106
107void QskProgressIndicator::setIndeterminate( bool on )
108{
109 if ( on == m_data->isIndeterminate )
110 return;
111
112 m_data->isIndeterminate = on;
113 m_data->updateIndeterminateAnimator( this );
114
115 update();
116 Q_EMIT indeterminateChanged( on );
117}
118
119void QskProgressIndicator::setFillGradient( const QskGradient& gradient )
120{
121 setGradientHint( Fill, gradient );
122}
123
124void QskProgressIndicator::resetFillGradient()
125{
126 resetColor( Fill );
127}
128
129QskGradient QskProgressIndicator::fillGradient() const
130{
131 return gradientHint( Fill );
132}
133
134void QskProgressIndicator::setExtent( qreal extent )
135{
136 if ( extent < 0.0 )
137 extent = 0.0;
138
139 if ( setMetric( Groove | QskAspect::Size, extent ) )
140 Q_EMIT extentChanged( extent );
141}
142
143void QskProgressIndicator::resetExtent()
144{
145 if ( resetMetric( Groove | QskAspect::Size ) )
146 Q_EMIT extentChanged( extent() );
147}
148
149qreal QskProgressIndicator::extent() const
150{
151 auto grooveSize = metric( Groove | QskAspect::Size );
152 auto fillSize = metric( Fill | QskAspect::Size );
153 return qMax( grooveSize, fillSize );
154}
155
156void QskProgressIndicator::setOrigin( qreal origin )
157{
158 if ( isComponentComplete() )
159 origin = boundedValue( origin );
160
161 if( !m_data->hasOrigin || !qskFuzzyCompare( m_data->origin, origin ) )
162 {
163 m_data->hasOrigin = true;
164 m_data->origin = origin;
165
166 update();
167 Q_EMIT originChanged( origin );
168 }
169}
170
171void QskProgressIndicator::resetOrigin()
172{
173 if ( m_data->hasOrigin )
174 {
175 m_data->hasOrigin = false;
176
177 update();
178 Q_EMIT originChanged( origin() );
179 }
180}
181
182qreal QskProgressIndicator::origin() const
183{
184 if ( m_data->hasOrigin )
185 {
186 return boundedValue( m_data->origin );
187 }
188
189 return minimum();
190}
191
192void QskProgressIndicator::setValue( qreal value )
193{
194 if ( isComponentComplete() )
195 value = boundedValue( value );
196
197 setValueInternal( value );
198}
199
200qreal QskProgressIndicator::value() const
201{
202 return m_data->value;
203}
204
205void QskProgressIndicator::setValueAsRatio( qreal ratio )
206{
207 ratio = qBound( 0.0, ratio, 1.0 );
208 setValue( minimum() + ratio * boundaryLength() );
209}
210
211qreal QskProgressIndicator::valueAsRatio() const
212{
213 return valueAsRatio( m_data->value );
214}
215
216void QskProgressIndicator::componentComplete()
217{
218 Inherited::componentComplete();
219 adjustValue();
220}
221
222void QskProgressIndicator::adjustValue()
223{
224 if ( isComponentComplete() )
225 setValueInternal( boundedValue( m_data->value ) );
226}
227
228void QskProgressIndicator::setValueInternal( qreal value )
229{
230 if ( !qskFuzzyCompare( value, m_data->value ) )
231 {
232 m_data->value = value;
233 Q_EMIT valueChanged( value );
234
235 update();
236 }
237}
238
239void QskProgressIndicator::itemChange( QQuickItem::ItemChange change,
240 const QQuickItem::ItemChangeData& value )
241{
242 switch( static_cast< int >( change ) )
243 {
244 case QQuickItem::ItemVisibleHasChanged:
245 case QQuickItem::ItemSceneChange:
246 {
247 m_data->updateIndeterminateAnimator( this );
248 break;
249 }
250 }
251
252 Inherited::itemChange( change, value );
253}
254
255#include "moc_QskProgressIndicator.cpp"
void itemChange(ItemChange, const ItemChangeData &) override
bool resetColor(QskAspect)
Removes a color hint from the local table.
QskGradient gradientHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a color hint as gradient.
bool setGradientHint(QskAspect, const QskGradient &)
Sets a gradient as color hint.
bool setMetric(QskAspect, qreal)
Sets a metric hint.
qreal metric(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a metric hint.
bool resetMetric(QskAspect)
Removes a metric hint from the local table.