Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickmaterialprogressbar.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// Qt-Security score:significant reason:default
4
6
7#include <QtCore/qmath.h>
8#include <QtCore/qeasingcurve.h>
9#include <QtQuick/private/qquickitem_p.h>
10#include <QtQuick/private/qsgadaptationlayer_p.h>
11#include <QtQuick/qsgrectanglenode.h>
12#include <QtQuick/qsgimagenode.h>
13#include <QtQuick/qquickwindow.h>
14#include <QtQuickControls2Impl/private/qquickanimatednode_p.h>
15
17
18static const int PauseDuration = 520;
19static const int SlideDuration = 1240;
21
23{
24public:
25 QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item);
26
28 void sync(QQuickItem *item) override;
29
30private:
31 void moveNode(QSGTransformNode *node, const QRectF &geometry, qreal progress);
32
33 bool m_indeterminate = false;
34 QEasingCurve m_easing = QEasingCurve::OutCubic;
35};
36
39{
40 setLoopCount(Infinite);
41 setDuration(QmpbTotalDuration);
42}
43
45{
46 QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
47 Q_ASSERT(geometryNode->type() == QSGNode::GeometryNodeType);
48 const QRectF geometry = geometryNode->rect();
49
50 QSGTransformNode *firstNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
51 if (firstNode) {
52 Q_ASSERT(firstNode->type() == QSGNode::TransformNodeType);
53
54 const qreal progress = qMin<qreal>(1.0, static_cast<qreal>(time) / SlideDuration);
55 moveNode(static_cast<QSGTransformNode *>(firstNode), geometry, progress);
56 }
57
58 QSGTransformNode *secondNode = static_cast<QSGTransformNode *>(geometryNode->lastChild());
59 if (secondNode) {
60 Q_ASSERT(secondNode->type() == QSGNode::TransformNodeType);
61
62 const qreal progress = qMax<qreal>(0.0, static_cast<qreal>(time - PauseDuration) / SlideDuration);
63 moveNode(static_cast<QSGTransformNode *>(secondNode), geometry, progress);
64 }
65}
66
67void QQuickMaterialProgressBarNode::sync(QQuickItem *item)
68{
69 QQuickMaterialProgressBar *bar = static_cast<QQuickMaterialProgressBar *>(item);
70 if (m_indeterminate != bar->isIndeterminate()) {
71 m_indeterminate = bar->isIndeterminate();
72 if (m_indeterminate)
73 start();
74 else
75 stop();
76 }
77
78 QQuickItemPrivate *d = QQuickItemPrivate::get(item);
79
80 QRectF bounds = item->boundingRect();
81 bounds.setHeight(item->implicitHeight());
82 bounds.moveTop((item->height() - bounds.height()) / 2.0);
83
84 QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
85 if (!geometryNode) {
86 geometryNode = item->window()->createRectangleNode();
87 geometryNode->setColor(Qt::transparent);
88 appendChildNode(geometryNode);
89 }
90 geometryNode->setRect(bounds);
91
92 const int count = m_indeterminate ? 2 : 1;
93 const qreal w = m_indeterminate ? 0 : bar->progress() * item->width();
94 const QRectF rect(0, bounds.y(), w, bounds.height());
95
96 QSGNode *transformNode = geometryNode->firstChild();
97 for (int i = 0; i < count; ++i) {
98 if (!transformNode) {
99 transformNode = new QSGTransformNode;
100 geometryNode->appendChildNode(transformNode);
101
102 QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
103 rectNode->setAntialiasing(true);
104 transformNode->appendChildNode(rectNode);
105 }
106 Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
107 static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4());
108
109 QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
110 Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
111
112 rectNode->setRect(rect);
113 rectNode->setColor(bar->color());
114 rectNode->update();
115
116 transformNode = transformNode->nextSibling();
117 }
118
119 while (transformNode) {
120 QSGNode *nextSibling = transformNode->nextSibling();
121 delete transformNode;
122 transformNode = nextSibling;
123 }
124}
125
126void QQuickMaterialProgressBarNode::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress)
127{
128 const qreal value = m_easing.valueForProgress(progress);
129 const qreal x = value * geometry.width();
130
131 QMatrix4x4 matrix;
132 matrix.translate(x, 0);
133 transformNode->setMatrix(matrix);
134
135 QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
136 Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
137
138 QRectF r = geometry;
139 r.setWidth(value * (geometry.width() - x));
140 rectNode->setRect(r);
141 rectNode->update();
142}
143
144QQuickMaterialProgressBar::QQuickMaterialProgressBar(QQuickItem *parent)
145 : QQuickItem(parent)
146{
147 setFlag(ItemHasContents);
148}
149
150QColor QQuickMaterialProgressBar::color() const
151{
152 return m_color;
153}
154
155void QQuickMaterialProgressBar::setColor(const QColor &color)
156{
157 if (color == m_color)
158 return;
159
160 m_color = color;
161 update();
162}
163
164qreal QQuickMaterialProgressBar::progress() const
165{
166 return m_progress;
167}
168
169void QQuickMaterialProgressBar::setProgress(qreal progress)
170{
171 if (progress == m_progress)
172 return;
173
174 m_progress = progress;
175 update();
176}
177
178bool QQuickMaterialProgressBar::isIndeterminate() const
179{
180 return m_indeterminate;
181}
182
183void QQuickMaterialProgressBar::setIndeterminate(bool indeterminate)
184{
185 if (indeterminate == m_indeterminate)
186 return;
187
188 m_indeterminate = indeterminate;
189 update();
190}
191
192void QQuickMaterialProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
193{
194 QQuickItem::itemChange(change, data);
195 if (change == ItemVisibleHasChanged)
196 update();
197}
198
199QSGNode *QQuickMaterialProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
200{
201 QQuickMaterialProgressBarNode *node = static_cast<QQuickMaterialProgressBarNode *>(oldNode);
202 if (isVisible() && width() > 0 && height() > 0) {
203 if (!node)
204 node = new QQuickMaterialProgressBarNode(this);
205 node->sync(this);
206 } else {
207 delete node;
208 node = nullptr;
209 }
210 return node;
211}
212
213QT_END_NAMESPACE
214
215#include "moc_qquickmaterialprogressbar_p.cpp"
QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item)
void sync(QQuickItem *item) override
static const int SlideDuration
static QT_BEGIN_NAMESPACE const int PauseDuration
static const int QmpbTotalDuration