1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Extras module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquickflatprogressbar_p.h"
41
42#include <QtCore/QtMath>
43#include <QtGui/QPainter>
44
45QQuickFlatProgressBar::QQuickFlatProgressBar(QQuickItem *parent) :
46 QQuickPaintedItem(parent),
47 mStripeOffset(0),
48 mRadius(0),
49 mIndeterminate(false)
50{
51 mAnimation.setTargetObject(this);
52 mAnimation.setPropertyName("stripeOffset");
53 mAnimation.setEndValue(0);
54 mAnimation.setDuration(800);
55 mAnimation.setLoopCount(-1);
56
57 connect(sender: this, SIGNAL(stripeOffsetChanged(qreal)), receiver: this, SLOT(repaint()));
58 connect(sender: this, SIGNAL(progressChanged(qreal)), receiver: this, SLOT(repaint()));
59 connect(sender: this, SIGNAL(enabledChanged()), receiver: this, SLOT(repaint()));
60 connect(sender: this, SIGNAL(indeterminateChanged(bool)), receiver: this, SLOT(repaint()));
61 connect(sender: this, SIGNAL(widthChanged()), receiver: this, SLOT(onWidthChanged()));
62 connect(sender: this, SIGNAL(heightChanged()), receiver: this, SLOT(onHeightChanged()));
63 connect(sender: this, SIGNAL(visibleChanged()), receiver: this, SLOT(onVisibleChanged()));
64}
65
66int QQuickFlatProgressBar::barWidth()
67{
68 // 14 is the design height of stripes on the bar, 10 is design width of stripe
69 return int(height() * 10 / 14);
70}
71
72void QQuickFlatProgressBar::paint(QPainter *painter)
73{
74 // This item should always be rounded to an integer size, so it is safe to use int here.
75 const int w = width();
76 const int h = height();
77
78 painter->setRenderHint(hint: QPainter::Antialiasing, on: true);
79 painter->setPen(Qt::transparent);
80
81 // Draw the background.
82 painter->setBrush(isIndeterminate() && mProgress > 0 ? QColor(92, 170, 21) : QColor(0, 0, 0, 255 * 0.15));
83 painter->drawRoundedRect(x: 0, y: 0, w, h, xRadius: mRadius, yRadius: mRadius);
84
85 // Draw progress, or indeterminate stripes.
86 painter->setClipPath(path: mClipPath);
87
88 if (!mIndeterminate) {
89 painter->setBrush(isEnabled() ? QColor(92, 170, 21) : QColor(179, 179, 179));
90 painter->drawRect(x: 0, y: 0, w: int(w * mProgress), h);
91 } else {
92 QPainterPath innerClipPath;
93 // 1 is the design margin thickness.
94 const int margin = qMax(a: 1, b: int(height() * (1.0 / 16.0)));
95 // We take the margin from the radius so that the inner and outer radii match each other visually.
96 innerClipPath.addRoundedRect(x: margin, y: margin, w: width() - margin * 2, h: height() - margin * 2, xRadius: mRadius - margin, yRadius: mRadius - margin);
97 painter->setClipPath(path: innerClipPath);
98
99 painter->translate(dx: mStripeOffset, dy: 0);
100
101 const qreal stripeWidth = barWidth();
102 // The horizontal distance created by the slant of the stripe.
103 const qreal stripeSlantDistance = h;
104
105 // One stripe width is equal to the height of the bar.
106 QPainterPath stripe;
107 stripe.moveTo(x: 0, y: h);
108 stripe.lineTo(x: stripeSlantDistance, y: 0);
109 stripe.lineTo(x: stripeSlantDistance + stripeWidth, y: 0);
110 stripe.lineTo(x: stripeWidth, y: h);
111 stripe.closeSubpath();
112
113 painter->setBrush(QBrush(mProgress > 0 ? QColor(255, 255, 255, 77) : Qt::white));
114
115 for (int i = -stripeWidth * 2; i < w + stripeWidth * 2; i += stripeWidth * 2) {
116 painter->translate(dx: i, dy: 0);
117 painter->drawPath(path: stripe);
118 painter->translate(dx: -i, dy: 0);
119 }
120
121 painter->translate(dx: -mStripeOffset, dy: 0);
122 }
123}
124
125qreal QQuickFlatProgressBar::stripeOffset() const
126{
127 return mStripeOffset;
128}
129
130void QQuickFlatProgressBar::setStripeOffset(qreal pos)
131{
132 if (pos != mStripeOffset) {
133 mStripeOffset = pos;
134 emit stripeOffsetChanged(stripeOffset: pos);
135 }
136}
137
138qreal QQuickFlatProgressBar::progress() const
139{
140 return mProgress;
141}
142
143void QQuickFlatProgressBar::setProgress(qreal progress)
144{
145 if (progress != mProgress) {
146 mProgress = progress;
147 emit progressChanged(progress: mProgress);
148 }
149}
150
151bool QQuickFlatProgressBar::isIndeterminate()
152{
153 return mIndeterminate;
154}
155
156void QQuickFlatProgressBar::setIndeterminate(bool indeterminate)
157{
158 if (indeterminate != mIndeterminate) {
159 mIndeterminate = indeterminate;
160 emit indeterminateChanged(indeterminate: mIndeterminate);
161 }
162}
163
164void QQuickFlatProgressBar::repaint()
165{
166 QQuickPaintedItem::update(rect: QRect(0, 0, width(), height()));
167}
168
169void QQuickFlatProgressBar::restartAnimation()
170{
171 mAnimation.stop();
172 mAnimation.setStartValue(-barWidth() * 2);
173 mAnimation.start();
174}
175
176void QQuickFlatProgressBar::onVisibleChanged()
177{
178 if (isVisible()) {
179 restartAnimation();
180 } else {
181 mAnimation.stop();
182 }
183}
184
185void QQuickFlatProgressBar::onWidthChanged()
186{
187 restartAnimation();
188
189 mClipPath = QPainterPath();
190 mClipPath.addRoundedRect(x: 0, y: 0, w: width(), h: height(), xRadius: mRadius, yRadius: mRadius);
191}
192
193void QQuickFlatProgressBar::onHeightChanged()
194{
195 restartAnimation();
196
197 // 3 is the design radius, 16 is the design height of the bar
198 const qreal radius = height() * 3 / 16;
199 if (radius != mRadius) {
200 mRadius = radius;
201 }
202
203 mClipPath = QPainterPath();
204 mClipPath.addRoundedRect(x: 0, y: 0, w: width(), h: height(), xRadius: mRadius, yRadius: mRadius);
205}
206

source code of qtquickcontrols/src/extras/Private/qquickflatprogressbar.cpp