1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL3$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or later as published by the Free
28 ** Software Foundation and appearing in the file LICENSE.GPL included in
29 ** the packaging of this file. Please review the following information to
30 ** ensure the GNU General Public License version 2.0 requirements will be
31 ** met: http://www.gnu.org/licenses/gpl-2.0.html.
32 **
33 ** $QT_END_LICENSE$
34 **
35 ****************************************************************************/
36 
37 #include "qquickprogressbar_p.h"
38 #include "qquickcontrol_p_p.h"
39 
40 QT_BEGIN_NAMESPACE
41 
42 /*!
43     \qmltype ProgressBar
44     \inherits Control
45 //!     \instantiates QQuickProgressBar
46     \inqmlmodule QtQuick.Controls
47     \since 5.7
48     \ingroup qtquickcontrols2-indicators
49     \brief Indicates the progress of an operation.
50 
51     \image qtquickcontrols2-progressbar.gif
52 
53     ProgressBar indicates the progress of an operation. The value should be updated
54     regularly. The range is defined by \l from and \l to, which both can contain any value.
55 
56     \code
57     ProgressBar {
58         value: 0.5
59     }
60     \endcode
61 
62     ProgressBar also supports a special \l indeterminate mode, which is useful,
63     for example, when unable to determine the size of the item being downloaded,
64     or if the download progress gets interrupted due to a network disconnection.
65 
66     \image qtquickcontrols2-progressbar-indeterminate.gif
67 
68     \code
69     ProgressBar {
70         indeterminate: true
71     }
72     \endcode
73 
74     The indeterminate mode is similar to a \l BusyIndicator. Both can be used
75     to indicate background activity. The main difference is visual, and that
76     ProgressBar can also present a concrete amount of progress (when it can be
77     determined). Due to the visual difference, indeterminate progress bars and
78     busy indicators fit different places in user interfaces. Typical places for
79     an indeterminate progress bar:
80     \list
81     \li at the bottom of a \l ToolBar
82     \li inline within the content of a \l Page
83     \li in an \l ItemDelegate to show the progress of a particular item
84     \endlist
85 
86     \sa {Customizing ProgressBar}, BusyIndicator, {Indicator Controls}
87 */
88 
89 class QQuickProgressBarPrivate : public QQuickControlPrivate
90 {
91 public:
92     qreal from = 0;
93     qreal to = 1;
94     qreal value = 0;
95     bool indeterminate = false;
96 };
97 
QQuickProgressBar(QQuickItem * parent)98 QQuickProgressBar::QQuickProgressBar(QQuickItem *parent)
99     : QQuickControl(*(new QQuickProgressBarPrivate), parent)
100 {
101 }
102 
103 /*!
104     \qmlproperty real QtQuick.Controls::ProgressBar::from
105 
106     This property holds the starting value for the progress. The default value is \c 0.0.
107 
108     \sa to, value
109 */
from() const110 qreal QQuickProgressBar::from() const
111 {
112     Q_D(const QQuickProgressBar);
113     return d->from;
114 }
115 
setFrom(qreal from)116 void QQuickProgressBar::setFrom(qreal from)
117 {
118     Q_D(QQuickProgressBar);
119     if (qFuzzyCompare(d->from, from))
120         return;
121 
122     d->from = from;
123     emit fromChanged();
124     emit positionChanged();
125     emit visualPositionChanged();
126     if (isComponentComplete())
127         setValue(d->value);
128 }
129 
130 /*!
131     \qmlproperty real QtQuick.Controls::ProgressBar::to
132 
133     This property holds the end value for the progress. The default value is \c 1.0.
134 
135     \sa from, value
136 */
to() const137 qreal QQuickProgressBar::to() const
138 {
139     Q_D(const QQuickProgressBar);
140     return d->to;
141 }
142 
setTo(qreal to)143 void QQuickProgressBar::setTo(qreal to)
144 {
145     Q_D(QQuickProgressBar);
146     if (qFuzzyCompare(d->to, to))
147         return;
148 
149     d->to = to;
150     emit toChanged();
151     emit positionChanged();
152     emit visualPositionChanged();
153     if (isComponentComplete())
154         setValue(d->value);
155 }
156 
157 /*!
158     \qmlproperty real QtQuick.Controls::ProgressBar::value
159 
160     This property holds the progress value. The default value is \c 0.0.
161 
162     \sa from, to, position
163 */
value() const164 qreal QQuickProgressBar::value() const
165 {
166     Q_D(const QQuickProgressBar);
167     return d->value;
168 }
169 
setValue(qreal value)170 void QQuickProgressBar::setValue(qreal value)
171 {
172     Q_D(QQuickProgressBar);
173     if (isComponentComplete())
174         value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);
175 
176     if (qFuzzyCompare(d->value, value))
177         return;
178 
179     d->value = value;
180     emit valueChanged();
181     emit positionChanged();
182     emit visualPositionChanged();
183 }
184 
185 /*!
186     \qmlproperty real QtQuick.Controls::ProgressBar::position
187     \readonly
188 
189     This property holds the logical position of the progress.
190 
191     The position is expressed as a fraction of the value, in the range
192     \c {0.0 - 1.0}. For visualizing the progress, the right-to-left
193     aware \l visualPosition should be used instead.
194 
195     \sa value, visualPosition
196 */
position() const197 qreal QQuickProgressBar::position() const
198 {
199     Q_D(const QQuickProgressBar);
200     if (qFuzzyCompare(d->from, d->to))
201         return 0;
202     return (d->value - d->from) / (d->to - d->from);
203 }
204 
205 /*!
206     \qmlproperty real QtQuick.Controls::ProgressBar::visualPosition
207     \readonly
208 
209     This property holds the visual position of the progress.
210 
211     The position is expressed as a fraction of the value, in the range \c {0.0 - 1.0}.
212     When the control is \l {Control::mirrored}{mirrored}, \c visuaPosition is equal
213     to \c {1.0 - position}. This makes \c visualPosition suitable for visualizing
214     the progress, taking right-to-left support into account.
215 
216     \sa position, value
217 */
visualPosition() const218 qreal QQuickProgressBar::visualPosition() const
219 {
220     if (isMirrored())
221         return 1.0 - position();
222     return position();
223 }
224 
225 /*!
226     \qmlproperty bool QtQuick.Controls::ProgressBar::indeterminate
227 
228     This property holds whether the progress bar is in indeterminate mode.
229     A progress bar in indeterminate mode displays that an operation is in progress, but it
230     doesn't show how much progress has been made.
231 
232     \image qtquickcontrols2-progressbar-indeterminate.gif
233 */
isIndeterminate() const234 bool QQuickProgressBar::isIndeterminate() const
235 {
236     Q_D(const QQuickProgressBar);
237     return d->indeterminate;
238 }
239 
setIndeterminate(bool indeterminate)240 void QQuickProgressBar::setIndeterminate(bool indeterminate)
241 {
242     Q_D(QQuickProgressBar);
243     if (d->indeterminate == indeterminate)
244         return;
245 
246     d->indeterminate = indeterminate;
247     emit indeterminateChanged();
248 }
249 
mirrorChange()250 void QQuickProgressBar::mirrorChange()
251 {
252     QQuickControl::mirrorChange();
253     if (!qFuzzyCompare(position(), qreal(0.5)))
254         emit visualPositionChanged();
255 }
256 
componentComplete()257 void QQuickProgressBar::componentComplete()
258 {
259     Q_D(QQuickProgressBar);
260     QQuickControl::componentComplete();
261     setValue(d->value);
262 }
263 
264 #if QT_CONFIG(accessibility)
accessibleRole() const265 QAccessible::Role QQuickProgressBar::accessibleRole() const
266 {
267     return QAccessible::ProgressBar;
268 }
269 #endif
270 
271 QT_END_NAMESPACE
272