Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickuniversalprogressbar.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/qmath.h>
7#include <QtCore/qeasingcurve.h>
8#include <QtQuick/private/qquickitem_p.h>
9#include <QtQuick/private/qsgadaptationlayer_p.h>
10#include <QtQuick/qsgrectanglenode.h>
11#include <QtQuickControls2Impl/private/qquickanimatednode_p.h>
12
14
15static const int QupbPhaseCount = 4;
16static const int EllipseCount = 5;
17static const int QupbInterval = 167;
18static const int QupbTotalDuration = 3917;
19static const int VisibleDuration = 3000;
20static const qreal EllipseDiameter = 4;
21static const qreal EllipseOffset = 4;
22static const qreal ContainerAnimationStartPosition = -34; // absolute
23static const qreal ContainerAnimationEndPosition = 0.435222; // relative
24static const qreal EllipseAnimationWellPosition = 0.333333333333333; // relative
25static const qreal EllipseAnimationEndPosition = 0.666666666666667; // relative
26
28{
29public:
31
32 void updateCurrentTime(int time) override;
33 void sync(QQuickItem *item) override;
34
35private:
36 struct Phase {
37 Phase() = default;
38 Phase(int d, qreal f, qreal t) : duration(d), from(f), to(t) { }
39 int duration = 0;
40 qreal from = 0;
41 qreal to = 0;
42 };
43
44 bool m_indeterminate = false;
45 Phase m_borderPhases[QupbPhaseCount];
46 Phase m_ellipsePhases[QupbPhaseCount];
47};
48
51{
54
55 m_borderPhases[0] = Phase( 500, -50, 0);
56 m_borderPhases[1] = Phase(1500, 0, 0);
57 m_borderPhases[2] = Phase(1000, 0, 100);
58 m_borderPhases[3] = Phase( 917, 100, 100);
59
60 m_ellipsePhases[0] = Phase(1000, 0, EllipseAnimationWellPosition);
61 m_ellipsePhases[1] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationWellPosition);
62 m_ellipsePhases[2] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition);
63 m_ellipsePhases[3] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition);
64}
65
67{
68 QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
69 Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType);
70 if (!geometryNode)
71 return;
72
73 QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
74 Q_ASSERT(!gridNode || gridNode->type() == QSGNode::TransformNodeType);
75 if (!gridNode)
76 return;
77
78 qreal width = geometryNode->rect().width();
79 {
82 qreal progress = static_cast<qreal>(time) / QupbTotalDuration;
83 qreal dx = from + (to - from) * progress;
84
86 matrix.translate(dx, 0);
87 gridNode->setMatrix(matrix);
88 }
89
90 int nodeIndex = 0;
91 QSGTransformNode *borderNode = static_cast<QSGTransformNode *>(gridNode->firstChild());
92 while (borderNode) {
93 Q_ASSERT(borderNode->type() == QSGNode::TransformNodeType);
94
95 QSGTransformNode *ellipseNode = static_cast<QSGTransformNode *>(borderNode->firstChild());
96 Q_ASSERT(ellipseNode->type() == QSGNode::TransformNodeType);
97
98 QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(ellipseNode->firstChild());
99 Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
100
101 int begin = nodeIndex * QupbInterval;
102 int end = VisibleDuration + nodeIndex * QupbInterval;
103
104 bool visible = time >= begin && time <= end;
105 opacityNode->setOpacity(visible ? 1.0 : 0.0);
106
107 if (visible) {
108 {
109 int phaseIndex, remain = time, elapsed = 0;
110 for (phaseIndex = 0; phaseIndex < QupbPhaseCount - 1; ++phaseIndex) {
111 if (remain <= m_borderPhases[phaseIndex].duration + begin)
112 break;
113 remain -= m_borderPhases[phaseIndex].duration;
114 elapsed += m_borderPhases[phaseIndex].duration;
115 }
116
117 const Phase &phase = m_borderPhases[phaseIndex];
118
119 qreal pos = time - elapsed - begin;
120 qreal progress = pos / phase.duration;
121 qreal dx = phase.from + (phase.to - phase.from) * progress;
122
124 matrix.translate(dx, 0);
125 borderNode->setMatrix(matrix);
126 }
127
128 {
130 curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(0.6, 1.0), QPointF(1.0, 1.0));
131
132 int phaseIndex, remain = time, elapsed = 0;
133 for (phaseIndex = 0; phaseIndex < QupbPhaseCount - 1; ++phaseIndex) {
134 if (remain <= m_ellipsePhases[phaseIndex].duration + begin)
135 break;
136 remain -= m_ellipsePhases[phaseIndex].duration;
137 elapsed += m_ellipsePhases[phaseIndex].duration;
138 }
139
140 const Phase &phase = m_ellipsePhases[phaseIndex];
141
142 qreal from = phase.from * width;
143 qreal to = phase.to * width;
144 qreal pos = time - elapsed - begin;
145 qreal progress = curve.valueForProgress(pos / phase.duration);
146 qreal dx = from + (to - from) * progress;
147
149 matrix.translate(dx, 0);
150 ellipseNode->setMatrix(matrix);
151 }
152 }
153
154 borderNode = static_cast<QSGTransformNode *>(borderNode->nextSibling());
155 ++nodeIndex;
156 }
157}
158
160{
162 if (m_indeterminate != bar->isIndeterminate()) {
163 m_indeterminate = bar->isIndeterminate();
164 if (m_indeterminate)
165 start();
166 else
167 stop();
168 }
169
171
172 QRectF bounds = item->boundingRect();
173 bounds.setHeight(item->implicitHeight());
174 bounds.moveTop((item->height() - bounds.height()) / 2.0);
175 if (!m_indeterminate)
176 bounds.setWidth(bar->progress() * bounds.width());
177
178 QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
179 if (!geometryNode) {
180 geometryNode = item->window()->createRectangleNode();
181 appendChildNode(geometryNode);
182 }
183 geometryNode->setRect(bounds);
184 geometryNode->setColor(m_indeterminate ? Qt::transparent : bar->color());
185
186 if (!m_indeterminate) {
187 while (QSGNode *node = geometryNode->firstChild())
188 delete node;
189 return;
190 }
191
192 QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
193 if (!gridNode) {
194 gridNode = new QSGTransformNode;
195 geometryNode->appendChildNode(gridNode);
196 }
197 Q_ASSERT(gridNode->type() == QSGNode::TransformNodeType);
198
199 QSGNode *borderNode = gridNode->firstChild();
200 for (int i = 0; i < EllipseCount; ++i) {
201 if (!borderNode) {
202 borderNode = new QSGTransformNode;
203 gridNode->appendChildNode(borderNode);
204
205 QSGTransformNode *ellipseNode = new QSGTransformNode;
206 borderNode->appendChildNode(ellipseNode);
207
208 QSGOpacityNode *opacityNode = new QSGOpacityNode;
209 ellipseNode->appendChildNode(opacityNode);
210
211 QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
212 rectNode->setAntialiasing(true);
213 rectNode->setRadius(EllipseDiameter / 2);
214 opacityNode->appendChildNode(rectNode);
215 }
216 Q_ASSERT(borderNode->type() == QSGNode::TransformNodeType);
217
218 QSGNode *ellipseNode = borderNode->firstChild();
219 Q_ASSERT(ellipseNode->type() == QSGNode::TransformNodeType);
220
221 QSGNode *opacityNode = ellipseNode->firstChild();
222 Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
223
224 QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
225 Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
226
227 rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (item->height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter));
228 rectNode->setColor(bar->color());
229 rectNode->update();
230
231 borderNode = borderNode->nextSibling();
232 }
233}
234
240
242{
243 return m_color;
244}
245
247{
248 if (m_color == color)
249 return;
250
251 m_color = color;
252 update();
253}
254
256{
257 return m_progress;
258}
259
261{
262 if (progress == m_progress)
263 return;
264
265 m_progress = progress;
266 update();
267}
268
270{
271 return m_indeterminate;
272}
273
275{
276 if (indeterminate == m_indeterminate)
277 return;
278
279 m_indeterminate = indeterminate;
280 setClip(m_indeterminate);
281 update();
282}
283
290
292{
294 if (isVisible() && width() > 0 && height() > 0) {
295 if (!node)
296 node = new QQuickUniversalProgressBarNode(this);
297 node->sync(this);
298 } else {
299 delete node;
300 node = nullptr;
301 }
302 return node;
303}
304
306
307#include "moc_qquickuniversalprogressbar_p.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
void addCubicBezierSegment(const QPointF &c1, const QPointF &c2, const QPointF &endPoint)
Adds a segment of a cubic bezier spline to define a custom easing curve.
qreal valueForProgress(qreal progress) const
Return the effective progress for the easing curve at progress.
QGraphicsWidget * window() const
virtual QRectF boundingRect() const =0
This pure virtual function defines the outer bounds of the item as a rectangle; all painting must be ...
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
void translate(const QVector3D &vector)
Multiplies this matrix by another that translates coordinates by the components of vector.
\inmodule QtCore\reentrant
Definition qpoint.h:217
void setLoopCount(int count)
void setDuration(int duration)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
bool isVisible() const
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
virtual void itemChange(ItemChange, const ItemChangeData &)
Called when change occurs for this item.
qreal height
This property holds the height of this item.
Definition qquickitem.h:76
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:144
@ ItemVisibleHasChanged
Definition qquickitem.h:148
void setClip(bool)
void update()
Schedules a call to updatePaintNode() for this item.
QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *item)
void sync(QQuickItem *item) override
QSGNode * updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
void setIndeterminate(bool indeterminate)
QQuickUniversalProgressBar(QQuickItem *parent=nullptr)
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:732
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
constexpr void setWidth(qreal w) noexcept
Sets the width of the rectangle to the given finite width.
Definition qrect.h:818
constexpr void setHeight(qreal h) noexcept
Sets the height of the rectangle to the given finite height.
Definition qrect.h:821
constexpr void moveTop(qreal pos) noexcept
Moves the rectangle vertically, leaving the rectangle's top line at the given finite y coordinate.
Definition qrect.h:705
virtual void setAntialiasing(bool antialiasing)
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
void appendChildNode(QSGNode *node)
Appends node to this node's list of children.
Definition qsgnode.cpp:398
@ TransformNodeType
Definition qsgnode.h:42
@ GeometryNodeType
Definition qsgnode.h:41
@ OpacityNodeType
Definition qsgnode.h:44
QSGNode * firstChild() const
Returns the first child of this node.
Definition qsgnode.h:105
NodeType type() const
Returns the type of this node.
Definition qsgnode.h:110
The QSGOpacityNode class is used to change opacity of nodes.
Definition qsgnode.h:276
void setOpacity(qreal opacity)
Sets the opacity of this node to opacity.
Definition qsgnode.cpp:1312
The QSGRectangleNode class is a convenience class for drawing solid filled rectangles using scenegrap...
The QSGTransformNode class implements transformations in the scene graph.
Definition qsgnode.h:241
const QMatrix4x4 & matrix() const
Returns this transform node's matrix.
Definition qsgnode.h:247
QSGTransformNode()
Create a new QSGTransformNode with its matrix set to the identity matrix.
Definition qsgnode.cpp:1133
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
GLuint GLuint end
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLint GLsizei width
GLuint color
[2]
GLuint start
GLuint GLenum matrix
GLdouble GLdouble t
Definition qopenglext.h:243
static const qreal ContainerAnimationStartPosition
static const int QupbTotalDuration
static const qreal EllipseAnimationEndPosition
static const qreal ContainerAnimationEndPosition
static const qreal EllipseOffset
static const int VisibleDuration
static const int EllipseCount
static QT_BEGIN_NAMESPACE const int QupbPhaseCount
static const int QupbInterval
static const qreal EllipseAnimationWellPosition
static const qreal EllipseDiameter
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static double elapsed(qint64 after, qint64 before)
double qreal
Definition qtypes.h:187
QGraphicsItem * item
\inmodule QtQuick
Definition qquickitem.h:159