1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQuick module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquicksprite_p.h"
50 \instantiates QQuickSprite
51 \inqmlmodule QtQuick 2
52 \ingroup qtquick-visual-utility
53 \brief Specifies sprite animations
55 QQuickSprite renders sprites of one or more frames and animates them. The sprites
56 can be in the middle of an image file, or split along multiple rows, as long as they form
57 a contiguous line wrapping to the next row of the file from the left edge of the file.
59 For full details, see the \l{Sprite Animation} overview.
62 \qmlproperty int QtQuick2::Sprite::duration
64 Duration of the animation. Values below 0 are invalid.
66 If frameRate is valid then it will be used to calculate the duration of the frames.
67 If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
70 \qmlproperty int QtQuick2::Sprite::durationVariation
72 The duration of the animation can vary by up to this amount. Variation will never decrease the
73 length of the animation to less than 0.
75 durationVariation will only take effect if duration is
76 used to calculate the duration of frames.
82 \qmlproperty qreal QtQuick2::Sprite::frameRate
84 Frames per second to show in the animation. Values below 0 are invalid.
86 If frameRate is valid then it will be used to calculate the duration of the frames.
87 If not, and frameDuration is valid , then frameDuration will be used. Otherwise duration is used.
90 \qmlproperty qreal QtQuick2::Sprite::frameRateVariation
92 The frame rate between animations can vary by up to this amount. Variation will never decrease the
93 length of the animation to less than 0.
95 frameRateVariation will only take effect if frameRate is
96 used to calculate the duration of frames.
102 \qmlproperty int QtQuick2::Sprite::frameDuration
104 Duration of each frame of the animation. Values below 0 are invalid.
106 If frameRate is valid then it will be used to calculate the duration of the frames.
107 If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
110 \qmlproperty int QtQuick2::Sprite::frameDurationVariation
112 The duration of a frame in the animation can vary by up to this amount. Variation will never decrease the
113 length of the animation to less than 0.
115 frameDurationVariation will only take effect if frameDuration is
116 used to calculate the duration of frames.
122 \qmlproperty string QtQuick2::Sprite::name
124 The name of this sprite, for use in the to property of other sprites.
127 \qmlproperty QVariantMap QtQuick2::Sprite::to
129 A list of other sprites and weighted transitions to them,
130 for example {"a":1, "b":2, "c":0} would specify that one-third should
131 transition to sprite "a" when this sprite is done, and two-thirds should
132 transition to sprite "b" when this sprite is done. As the transitions are
133 chosen randomly, these proportions will not be exact. With "c":0 in the list,
134 no sprites will randomly transition to "c", but it wll be a valid path if a sprite
137 If no list is specified, or the sum of weights in the list is zero, then the sprite
138 will repeat itself after completing.
141 \qmlproperty int QtQuick2::Sprite::frameCount
143 Number of frames in this sprite.
146 \qmlproperty int QtQuick2::Sprite::frameHeight
148 Height of a single frame in this sprite.
151 \qmlproperty int QtQuick2::Sprite::frameWidth
153 Width of a single frame in this sprite.
156 \qmlproperty int QtQuick2::Sprite::frameX
158 The X coordinate in the image file of the first frame of the sprite.
161 \qmlproperty int QtQuick2::Sprite::frameY
163 The Y coordinate in the image file of the first frame of the sprite.
166 \qmlproperty url QtQuick2::Sprite::source
168 The image source for the animation.
170 If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
171 Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
173 If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
177 \qmlproperty bool QtQuick2::Sprite::reverse
179 If true, then the animation will be played in reverse.
185 \qmlproperty bool QtQuick2::Sprite::randomStart
187 If true, then the animation will start its first animation with a random amount of its duration skipped.
188 This allows them to not look like they all just started when the animation begins.
190 This only affects the very first animation played. Transitioning to another animation, or the same
191 animation again, will not trigger this.
197 \qmlproperty bool QtQuick2::Sprite::frameSync
199 If true, then the animation will have no duration. Instead, the animation will advance
200 one frame each time a frame is rendered to the screen. This syncronizes it with the painting
201 rate as opposed to elapsed time.
203 If frameSync is set to true, it overrides all of duration, frameRate and frameDuration.
208 static const int unsetDuration = -2;//-1 means perframe for duration
209 QQuickSprite::QQuickSprite(QObject *parent)
210 : QQuickStochasticState(parent)
211 , m_generatedCount(0)
221 , m_frameRate(unsetDuration)
222 , m_frameRateVariation(0)
223 , m_frameDuration(unsetDuration)
224 , m_frameDurationVariation(0)
229 int QQuickSprite::variedDuration() const //Deals with precedence when multiple durations are set
234 if (m_frameRate != unsetDuration) {
235 qreal fpms = (m_frameRate
236 + (m_frameRateVariation * ((qreal)qrand()/RAND_MAX) * 2)
237 - m_frameRateVariation) / 1000.0;
238 return qMax(qreal(0.0) , m_frames / fpms);
239 } else if (m_frameDuration != unsetDuration) {
240 int mspf = m_frameDuration
241 + (m_frameDurationVariation * ((qreal)qrand()/RAND_MAX) * 2)
242 - m_frameDurationVariation;
243 return qMax(0, m_frames * mspf);
244 } else if (duration() >= 0) {
245 qWarning() << "Sprite::duration is changing meaning to the full animation duration.";
246 qWarning() << "Use Sprite::frameDuration for the old meaning, of per frame duration.";
247 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.";
248 //Note that the spammyness is due to this being the best location to detect, but also called once each animation loop
249 return QQuickStochasticState::variedDuration() * m_frames;
251 return 1000; //When nothing set
254 void QQuickSprite::startImageLoading()
257 if (!m_source.isEmpty())
258 m_pix.load(qmlEngine(this), m_source);