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
qquicksprite.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
7#include <qqml.h>
8#include <QQmlContext>
9#include <QDebug>
10#include <QRandomGenerator>
11
13
14/*!
15 \qmltype Sprite
16 \nativetype QQuickSprite
17 \inqmlmodule QtQuick
18 \ingroup qtquick-visual-utility
19 \brief Specifies sprite animations.
20
21 Sprite defines a series of one or more frames to be animated and rendered by SpriteSequence.
22 The sprites can be in the middle of an image file, or split along multiple rows, as long as they form
23 a contiguous line wrapping to the next row of the file from the left edge of the file.
24
25 For full details, see the \l{Sprite Animations} overview.
26*/
27/*!
28 \qmlproperty int QtQuick::Sprite::duration
29
30 Duration of the animation. Values below 0 are invalid.
31
32 If frameRate is valid then it will be used to calculate the duration of the frames.
33 If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
34*/
35/*!
36 \qmlproperty int QtQuick::Sprite::durationVariation
37
38 The duration of the animation can vary by up to this amount. Variation will never decrease the
39 length of the animation to less than 0.
40
41 durationVariation will only take effect if duration is
42 used to calculate the duration of frames.
43
44 Default is 0.
45*/
46
47/*!
48 \qmlproperty real QtQuick::Sprite::frameRate
49
50 Frames per second to show in the animation. Values below 0 are invalid.
51
52 If frameRate is valid then it will be used to calculate the duration of the frames.
53 If not, and frameDuration is valid , then frameDuration will be used. Otherwise duration is used.
54*/
55/*!
56 \qmlproperty real QtQuick::Sprite::frameRateVariation
57
58 The frame rate between animations can vary by up to this amount. Variation will never decrease the
59 length of the animation to less than 0.
60
61 frameRateVariation will only take effect if frameRate is
62 used to calculate the duration of frames.
63
64 Default is 0.
65*/
66
67/*!
68 \qmlproperty int QtQuick::Sprite::frameDuration
69
70 Duration of each frame of the animation in milliseconds. Values below 0 are invalid.
71
72 If frameRate is valid then it will be used to calculate the duration of the frames.
73 If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
74*/
75/*!
76 \qmlproperty int QtQuick::Sprite::frameDurationVariation
77
78 The duration of a frame in the animation can vary by up to this amount. Variation will never decrease the
79 length of the animation to less than 0.
80
81 frameDurationVariation will only take effect if frameDuration is
82 used to calculate the duration of frames.
83
84 Default is 0.
85*/
86
87/*!
88 \qmlproperty string QtQuick::Sprite::name
89
90 The name of this sprite, for use in the to property of other sprites.
91*/
92/*!
93 \qmlproperty QVariantMap QtQuick::Sprite::to
94
95 A list of other sprites and weighted transitions to them,
96 for example {"a":1, "b":2, "c":0} would specify that one-third should
97 transition to sprite "a" when this sprite is done, and two-thirds should
98 transition to sprite "b" when this sprite is done. As the transitions are
99 chosen randomly, these proportions will not be exact. With "c":0 in the list,
100 no sprites will randomly transition to "c", but it wll be a valid path if a sprite
101 goal is set.
102
103 If no list is specified, or the sum of weights in the list is zero, then the sprite
104 will repeat itself after completing.
105*/
106/*!
107 \qmlproperty int QtQuick::Sprite::frameCount
108
109 Number of frames in this sprite.
110*/
111/*!
112 \qmlproperty int QtQuick::Sprite::frameHeight
113
114 Height of a single frame in this sprite.
115*/
116/*!
117 \qmlproperty int QtQuick::Sprite::frameWidth
118
119 Width of a single frame in this sprite.
120*/
121/*!
122 \qmlproperty int QtQuick::Sprite::frameX
123
124 The X coordinate in the image file of the first frame of the sprite.
125*/
126/*!
127 \qmlproperty int QtQuick::Sprite::frameY
128
129 The Y coordinate in the image file of the first frame of the sprite.
130*/
131/*!
132 \qmlproperty url QtQuick::Sprite::source
133
134 The image source for the animation.
135
136 If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
137 Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
138
139 If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
140*/
141
142/*!
143 \qmlproperty bool QtQuick::Sprite::reverse
144
145 If true, then the animation will be played in reverse.
146
147 Default is false.
148*/
149
150/*!
151 \qmlproperty bool QtQuick::Sprite::randomStart
152
153 If true, then the animation will start its first animation with a random amount of its duration skipped.
154 This allows them to not look like they all just started when the animation begins.
155
156 This only affects the very first animation played. Transitioning to another animation, or the same
157 animation again, will not trigger this.
158
159 Default is false.
160*/
161
162/*!
163 \qmlproperty bool QtQuick::Sprite::frameSync
164
165 If true, then the animation will have no duration. Instead, the animation will advance
166 one frame each time a frame is rendered to the screen. This synchronizes it with the painting
167 rate as opposed to elapsed time.
168
169 If frameSync is set to true, it overrides all of duration, frameRate and frameDuration.
170
171 Default is false.
172*/
173
174static const int unsetDuration = -2;//-1 means perframe for duration
175QQuickSprite::QQuickSprite(QObject *parent)
176 : QQuickStochasticState(parent)
177 , m_generatedCount(0)
178 , m_framesPerRow(0)
179 , m_rowY(0)
180 , m_rowStartX(0)
181 , m_reverse(false)
182 , m_frameHeight(0)
183 , m_frameWidth(0)
184 , m_frames(1)
185 , m_frameX(0)
186 , m_frameY(0)
187 , m_frameRate(unsetDuration)
188 , m_frameRateVariation(0)
189 , m_frameDuration(unsetDuration)
190 , m_frameDurationVariation(0)
191 , m_frameSync(false)
192 , m_devicePixelRatio(1.0)
193{
194}
195
196/*! \internal */
197QQuickSprite::~QQuickSprite()
198{
199}
200
201int QQuickSprite::variedDuration() const //Deals with precedence when multiple durations are set
202{
203 if (m_frameSync)
204 return 0;
205
206 if (m_frameRate != unsetDuration) {
207 qreal fpms = (m_frameRate
208 + (m_frameRateVariation * QRandomGenerator::global()->generateDouble() * 2)
209 - m_frameRateVariation) / 1000.0;
210 return qMax(qreal(0.0) , m_frames / fpms);
211 } else if (m_frameDuration != unsetDuration) {
212 int mspf = m_frameDuration
213 + (m_frameDurationVariation * QRandomGenerator::global()->generateDouble() * 2)
214 - m_frameDurationVariation;
215 return qMax(0, m_frames * mspf);
216 } else if (duration() >= 0) {
217 qWarning() << "Sprite::duration is changing meaning to the full animation duration.";
218 qWarning() << "Use Sprite::frameDuration for the old meaning, of per frame duration.";
219 qWarning() << "As an interim measure, duration/durationVariation means the same as frameDuration/frameDurationVariation, and you'll get this warning spewed out everywhere to motivate you.";
220 //Note that the spammyness is due to this being the best location to detect, but also called once each animation loop
221 return QQuickStochasticState::variedDuration() * m_frames;
222 }
223 return 1000; //When nothing set
224}
225
226void QQuickSprite::startImageLoading()
227{
228 m_pix.clear(this);
229 if (!m_source.isEmpty()) {
230 const QQmlContext *context = qmlContext(this);
231 QQmlEngine *e = context ? context->engine() : nullptr;
232 if (!e) { //If not created in QML, you must set the QObject parent to the QML element so this can work
233 context = qmlContext(parent());
234 e = context ? context->engine() : nullptr;
235 if (!e)
236 qWarning() << "QQuickSprite: Cannot find QQmlEngine - this class is only for use in QML and may not work";
237 }
238 const QUrl resolvedUrl = context ? context->resolvedUrl(m_source) : m_source;
239 QUrl loadUrl = resolvedUrl;
240 QQuickImageBase::resolve2xLocalFile(resolvedUrl, m_devicePixelRatio, &loadUrl,
241 &m_devicePixelRatio);
242
243 m_pix.load(e, loadUrl);
244 }
245}
246
247QT_END_NAMESPACE
248
249#include "moc_qquicksprite_p.cpp"
static QT_BEGIN_NAMESPACE const int unsetDuration
\qmltype Sprite \nativetype QQuickSprite \inqmlmodule QtQuick