Update to 5.0.0-beta1
[profile/ivi/qtdeclarative.git] / src / quick / items / qquicksprite.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQuick module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquicksprite_p.h"
43 #include <qqml.h>
44 #include <QDebug>
45
46 QT_BEGIN_NAMESPACE
47
48 /*!
49     \qmltype Sprite
50     \instantiates QQuickSprite
51     \inqmlmodule QtQuick 2
52     \ingroup qtquick-visual-utility
53     \brief Specifies sprite animations
54
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.
58
59     For full details, see the \l{Sprite Animation} overview.
60 */
61 /*!
62     \qmlproperty int QtQuick2::Sprite::duration
63
64     Duration of the animation. Values below 0 are invalid.
65
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.
68 */
69 /*!
70     \qmlproperty int QtQuick2::Sprite::durationVariation
71
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.
74
75     durationVariation will only take effect if duration is
76     used to calculate the duration of frames.
77
78     Default is 0.
79 */
80
81 /*!
82     \qmlproperty qreal QtQuick2::Sprite::frameRate
83
84     Frames per second to show in the animation. Values below 0 are invalid.
85
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.
88 */
89 /*!
90     \qmlproperty qreal QtQuick2::Sprite::frameRateVariation
91
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.
94
95     frameRateVariation will only take effect if frameRate is
96     used to calculate the duration of frames.
97
98     Default is 0.
99 */
100
101 /*!
102     \qmlproperty int QtQuick2::Sprite::frameDuration
103
104     Duration of each frame of the animation. Values below 0 are invalid.
105
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.
108 */
109 /*!
110     \qmlproperty int QtQuick2::Sprite::frameDurationVariation
111
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.
114
115     frameDurationVariation will only take effect if frameDuration is
116     used to calculate the duration of frames.
117
118     Default is 0.
119 */
120
121 /*!
122     \qmlproperty string QtQuick2::Sprite::name
123
124     The name of this sprite, for use in the to property of other sprites.
125 */
126 /*!
127     \qmlproperty QVariantMap QtQuick2::Sprite::to
128
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
135     goal is set.
136
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.
139 */
140 /*!
141     \qmlproperty int QtQuick2::Sprite::frameCount
142
143     Number of frames in this sprite.
144 */
145 /*!
146     \qmlproperty int QtQuick2::Sprite::frameHeight
147
148     Height of a single frame in this sprite.
149 */
150 /*!
151     \qmlproperty int QtQuick2::Sprite::frameWidth
152
153     Width of a single frame in this sprite.
154 */
155 /*!
156     \qmlproperty int QtQuick2::Sprite::frameX
157
158     The X coordinate in the image file of the first frame of the sprite.
159 */
160 /*!
161     \qmlproperty int QtQuick2::Sprite::frameY
162
163     The Y coordinate in the image file of the first frame of the sprite.
164 */
165 /*!
166     \qmlproperty url QtQuick2::Sprite::source
167
168     The image source for the animation.
169
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.
172
173     If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
174 */
175
176 /*!
177     \qmlproperty bool QtQuick2::Sprite::reverse
178
179     If true, then the animation will be played in reverse.
180
181     Default is false.
182 */
183
184 /*!
185     \qmlproperty bool QtQuick2::Sprite::randomStart
186
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.
189
190     This only affects the very first animation played. Transitioning to another animation, or the same
191     animation again, will not trigger this.
192
193     Default is false.
194 */
195
196 /*!
197     \qmlproperty bool QtQuick2::Sprite::frameSync
198
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.
202
203     If frameSync is set to true, it overrides all of duration, frameRate and frameDuration.
204
205     Default is false.
206 */
207
208 static const int unsetDuration = -2;//-1 means perframe for duration
209 QQuickSprite::QQuickSprite(QObject *parent)
210     : QQuickStochasticState(parent)
211     , m_generatedCount(0)
212     , m_framesPerRow(0)
213     , m_rowY(0)
214     , m_rowStartX(0)
215     , m_reverse(false)
216     , m_frameHeight(0)
217     , m_frameWidth(0)
218     , m_frames(1)
219     , m_frameX(0)
220     , m_frameY(0)
221     , m_frameRate(unsetDuration)
222     , m_frameRateVariation(0)
223     , m_frameDuration(unsetDuration)
224     , m_frameDurationVariation(0)
225     , m_frameSync(false)
226 {
227 }
228
229 int QQuickSprite::variedDuration() const //Deals with precedence when multiple durations are set
230 {
231     if (m_frameSync)
232         return 0;
233
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;
250     }
251     return 1000; //When nothing set
252 }
253
254 void QQuickSprite::startImageLoading()
255 {
256     m_pix.clear(this);
257     if (!m_source.isEmpty())
258         m_pix.load(qmlEngine(this), m_source);
259 }
260
261 QT_END_NAMESPACE