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
qquickmaterialbusyindicator.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 <QtGui/qpainter.h>
9#include <QtQuick/qsgimagenode.h>
10#include <QtQuick/qquickwindow.h>
11#include <QtQuickControls2Impl/private/qquickanimatednode_p.h>
12
14
15/*
16 Relevant Android code:
17
18 - core/res/res/anim/progress_indeterminate_rotation_material.xml contains
19 the rotation animation data.
20 - core/res/res/anim/progress_indeterminate_material.xml contains the trim
21 animation data.
22 - core/res/res/interpolator/trim_start_interpolator.xml and
23 core/res/res/interpolator/trim_end_interpolator.xml contain the start
24 and end trim path interpolators.
25 - addCommand() in core/java/android/util/PathParser.java has a list of the
26 different path commands available.
27*/
28
29static const int SpanAnimationDuration = 700;
31static const int TargetRotation = 720;
32static const int OneDegree = 16;
33static const qreal MinSweepSpan = 10 * OneDegree;
34static const qreal MaxSweepSpan = 300 * OneDegree;
35
37{
38public:
40
41 void sync(QQuickItem *item) override;
42
43protected:
44 void updateCurrentTime(int time) override;
45
46private:
47 int m_lastStartAngle = 0;
48 int m_lastEndAngle = 0;
49 qreal m_width = 0;
50 qreal m_height = 0;
51 qreal m_devicePixelRatio = 1;
52 QColor m_color;
53};
54
57{
59 setCurrentTime(item->elapsed());
61
62 QSGImageNode *textureNode = item->window()->createImageNode();
63 textureNode->setOwnsTexture(true);
64 appendChildNode(textureNode);
65
66 // A texture seems to be required here, but we don't have one yet, as we haven't drawn anything,
67 // so just use a blank image.
68 QImage blankImage(item->width(), item->height(), QImage::Format_ARGB32_Premultiplied);
69 blankImage.fill(Qt::transparent);
70 textureNode->setTexture(item->window()->createTextureFromImage(blankImage));
71}
72
74{
75 const qreal w = m_width;
76 const qreal h = m_height;
77 const qreal size = qMin(w, h);
78 const qreal dx = (w - size) / 2;
79 const qreal dy = (h - size) / 2;
80
81 QImage image(size * m_devicePixelRatio, size * m_devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
83
86
87 QPen pen;
88 QSGImageNode *textureNode = static_cast<QSGImageNode *>(firstChild());
89 pen.setColor(m_color);
90 pen.setWidth(qCeil(size / 12) * m_devicePixelRatio);
91 painter.setPen(pen);
92
93 const qreal percentageComplete = time / qreal(RotationAnimationDuration);
94 const qreal spanPercentageComplete = (time % SpanAnimationDuration) / qreal(SpanAnimationDuration);
95 const int iteration = time / SpanAnimationDuration;
96 int startAngle = 0;
97 int endAngle = 0;
98
99 if (iteration % 2 == 0) {
100 if (m_lastStartAngle > 360 * OneDegree)
101 m_lastStartAngle -= 360 * OneDegree;
102
103 // The start angle is only affected by the rotation animation for the "grow" phase.
104 startAngle = m_lastStartAngle;
106 const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
107 endAngle = m_lastStartAngle + MinSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan);
108 m_lastEndAngle = endAngle;
109 } else {
110 // Both the start angle *and* the span are affected by the "shrink" phase.
112 const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
113 startAngle = m_lastEndAngle - MaxSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan);
114 endAngle = m_lastEndAngle;
115 m_lastStartAngle = startAngle;
116 }
117
118 const int halfPen = pen.width() / 2;
119 const QRectF arcBounds = QRectF(halfPen, halfPen,
120 m_devicePixelRatio * size - pen.width(),
121 m_devicePixelRatio * size - pen.width());
122 // The current angle of the rotation animation.
123 const qreal rotation = OneDegree * percentageComplete * -TargetRotation;
124 startAngle -= rotation;
125 endAngle -= rotation;
126 const int angleSpan = endAngle - startAngle;
127 painter.drawArc(arcBounds, -startAngle, -angleSpan);
128 painter.end();
129
130 textureNode->setRect(QRectF(dx, dy, size, size));
131 textureNode->setTexture(window()->createTextureFromImage(image));
132}
133
135{
137 m_color = indicator->color();
138 m_width = indicator->width();
139 m_height = indicator->height();
140 m_devicePixelRatio = indicator->window()->effectiveDevicePixelRatio();
141}
142
148
150{
151 return m_color;
152}
153
155{
156 if (m_color == color)
157 return;
158
159 m_color = color;
160 update();
161}
162
164{
165 return isVisible();
166}
167
169{
170 if (running)
171 setVisible(true);
172}
173
175{
176 return m_elapsed;
177}
178
180{
182 switch (change) {
184 if (qFuzzyIsNull(data.realValue))
185 setVisible(false);
186 break;
188 update();
189 break;
190 default:
191 break;
192 }
193}
194
196{
198 if (isRunning() && width() > 0 && height() > 0) {
199 if (!node) {
200 node = new QQuickMaterialBusyIndicatorNode(this);
201 node->start();
202 }
203 node->sync(this);
204 } else {
205 m_elapsed = node ? node->currentTime() : 0;
206 delete node;
207 node = nullptr;
208 }
209 return node;
210}
211
213
214#include "moc_qquickmaterialbusyindicator_p.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
QGraphicsWidget * window() const
\inmodule QtGui
Definition qimage.h:37
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void drawArc(const QRectF &rect, int a, int alen)
Draws the arc defined by the given rectangle, startAngle and spanAngle.
@ Antialiasing
Definition qpainter.h:52
bool end()
Ends painting.
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint.
\inmodule QtGui
Definition qpen.h:28
void setWidth(int width)
Sets the pen width to the given width in pixels with integer precision.
Definition qpen.cpp:592
int width() const
Returns the pen width with integer precision.
Definition qpen.cpp:560
void setColor(const QColor &color)
Sets the color of this pen's brush to the given color.
Definition qpen.cpp:705
QQuickWindow * window() const
void setLoopCount(int count)
void setCurrentTime(int time)
void setDuration(int duration)
void start(int duration=0)
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
QQuickWindow * window() const
Returns the window in which this item is rendered.
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
void setVisible(bool)
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
@ ItemOpacityHasChanged
Definition qquickitem.h:150
void update()
Schedules a call to updatePaintNode() for this item.
QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item)
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.
QQuickMaterialBusyIndicator(QQuickItem *parent=nullptr)
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
\inmodule QtCore\reentrant
Definition qrect.h:484
The QSGImageNode class is provided for convenience to easily draw textured content using the QML scen...
\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
QSGNode * firstChild() const
Returns the first child of this node.
Definition qsgnode.h:105
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
Definition image.cpp:4
static Q_CONSTINIT QBasicAtomicInt running
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
int qCeil(T v)
Definition qmath.h:36
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint color
[2]
GLfloat GLfloat GLfloat GLfloat h
static const int OneDegree
static QT_BEGIN_NAMESPACE const int SpanAnimationDuration
static const int TargetRotation
static const qreal MaxSweepSpan
static const int RotationAnimationDuration
static const qreal MinSweepSpan
double qreal
Definition qtypes.h:187
QGraphicsItem * item
QPainter painter(this)
[7]
\inmodule QtQuick
Definition qquickitem.h:159