632ee7f8c96d60708c2ce167c76a580f4c17dbb7
[profile/ivi/qtdeclarative.git] / src / quick / items / qquicksprite.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the Declarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquicksprite_p.h"
43 #include <QDebug>
44
45 QT_BEGIN_NAMESPACE
46
47 /*!
48     \qmlclass Sprite QQuickSprite
49     \inqmlmodule QtQuick 2
50     \brief The Sprite element represents a sprite animation
51
52     QQuickSprite renders sprites of one or more frames and animates them. The sprites
53     can be in the middle of an image file, or split along multiple rows, as long as they form
54     a contiguous line wrapping to the next row of the file from the left edge of the file.
55
56     Sprites within one animation must be the same size, however sprites within the same file
57     do not. Sprites without a frameCount specified assume that they take the entire file.
58
59     There are several software tools to help turn images into sprite sheets, here are some examples:
60     Photoshop plugin:
61     http://www.personal.psu.edu/zez1/blogs/my_blog/2011/05/scripts-4-photoshop-file-sequence-to-layers-to-sprite-sheet.html
62     Gimp plugin:
63     http://registry.gimp.org/node/20943
64     Cmd-line tool:
65     http://www.imagemagick.org/script/montage.php
66 */
67 /*!
68     \qmlproperty int QtQuick2::Sprite::duration
69
70     Duration of the animation. 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 QtQuick2::Sprite::durationVariation
77
78     The duration of 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     durationVariation will only take effect if duration is
82     used to calculate the duration of frames.
83
84     Default is 0.
85 */
86
87 /*!
88     \qmlproperty qreal QtQuick2::Sprite::frameRate
89
90     Frames per second to show in the animation. Values below 0 are invalid.
91
92     If frameRate is valid  then it will be used to calculate the duration of the frames.
93     If not, and frameDuration is valid , then frameDuration will be used. Otherwise duration is used.
94 */
95 /*!
96     \qmlproperty qreal QtQuick2::Sprite::frameRateVariation
97
98     The frame rate between animations can vary by up to this amount. Variation will never decrease the
99     length of the animation to less than 0.
100
101     frameRateVariation will only take effect if frameRate is
102     used to calculate the duration of frames.
103
104     Default is 0.
105 */
106
107 /*!
108     \qmlproperty int QtQuick2::Sprite::frameDuration
109
110     Duration of each frame of the animation. Values below 0 are invalid.
111
112     If frameRate is valid then it will be used to calculate the duration of the frames.
113     If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
114 */
115 /*!
116     \qmlproperty int QtQuick2::Sprite::frameDurationVariation
117
118     The duration of a frame in the animation can vary by up to this amount. Variation will never decrease the
119     length of the animation to less than 0.
120
121     frameDurationVariation will only take effect if frameDuration is
122     used to calculate the duration of frames.
123
124     Default is 0.
125 */
126
127 /*!
128     \qmlproperty string QtQuick2::Sprite::name
129
130     The name of this sprite, for use in the to property of other sprites.
131 */
132 /*!
133     \qmlproperty QVariantMap QtQuick2::Sprite::to
134
135     A list of other sprites and weighted transitions to them,
136     for example {"a":1, "b":2, "c":0} would specify that one-third should
137     transition to sprite "a" when this sprite is done, and two-thirds should
138     transition to sprite "b" when this sprite is done. As the transitions are
139     chosen randomly, these proportions will not be exact. With "c":0 in the list,
140     no sprites will randomly transition to "c", but it wll be a valid path if a sprite
141     goal is set.
142
143     If no list is specified, or the sum of weights in the list is zero, then the sprite
144     will repeat itself after completing.
145 */
146 /*!
147     \qmlproperty int QtQuick2::Sprite::frames
148
149     Number of frames in this sprite.
150 */
151 /*!
152     \qmlproperty int QtQuick2::Sprite::frameHeight
153
154     Height of a single frame in this sprite.
155 */
156 /*!
157     \qmlproperty int QtQuick2::Sprite::frameWidth
158
159     Width of a single frame in this sprite.
160 */
161 /*!
162     \qmlproperty int QtQuick2::Sprite::frameX
163
164     The X coordinate in the image file of the first frame of the sprite.
165 */
166 /*!
167     \qmlproperty int QtQuick2::Sprite::frameY
168
169     The Y coordinate in the image file of the first frame of the sprite.
170 */
171 /*!
172     \qmlproperty url QtQuick2::Sprite::source
173
174     The image source for the animation.
175
176     If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
177     Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
178
179     If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
180 */
181
182 /*!
183     \qmlproperty bool QtQuick2::Sprite::reverse
184
185     If true, then the animation will be played in reverse.
186
187     Default is false.
188 */
189
190 /*!
191     \qmlproperty bool QtQuick2::Sprite::randomStart
192
193     If true, then the animation will start its first animation with a random amount of its duration skipped.
194     This allows them to not look like they all just started when the animation begins.
195
196     This only affects the very first animation played. Transitioning to another animation, or the same
197     animation again, will not trigger this.
198
199     Default is false.
200 */
201
202 /*!
203     \qmlproperty bool QtQuick2::Sprite::frameSync
204
205     If true, then the animation will have no duration. Instead, the animation will advance
206     one frame each time a frame is rendered to the screen. This syncronizes it with the painting
207     rate as opposed to elapsed time.
208
209     If frameSync is set to true, it overrides all of duration, frameRate and frameDuration.
210
211     Default is false.
212 */
213
214 static const int unsetDuration = -2;//-1 means perframe for duration
215 QQuickSprite::QQuickSprite(QObject *parent)
216     : QQuickStochasticState(parent)
217     , m_generatedCount(0)
218     , m_framesPerRow(0)
219     , m_rowY(0)
220     , m_rowStartX(0)
221     , m_reverse(false)
222     , m_frameHeight(0)
223     , m_frameWidth(0)
224     , m_frames(1)
225     , m_frameX(0)
226     , m_frameY(0)
227     , m_frameRate(unsetDuration)
228     , m_frameRateVariation(0)
229     , m_frameDuration(unsetDuration)
230     , m_frameDurationVariation(0)
231     , m_frameSync(false)
232 {
233 }
234
235 int QQuickSprite::variedDuration() const //Deals with precedence when multiple durations are set
236 {
237     if (m_frameSync)
238         return 0;
239
240     if (m_frameRate != unsetDuration) {
241         qreal fpms = (m_frameRate
242                 + (m_frameRateVariation * ((qreal)qrand()/RAND_MAX) * 2)
243                 - m_frameRateVariation) / 1000.0;
244         return qMax(qreal(0.0) , m_frames / fpms);
245     } else if (m_frameDuration != unsetDuration) {
246         int mspf = m_frameDuration
247                 + (m_frameDurationVariation * ((qreal)qrand()/RAND_MAX) * 2)
248                 - m_frameDurationVariation;
249         return qMax(0, m_frames * mspf);
250     }
251     qWarning() << "Sprite::duration is changing meaning to the full animation duration.";
252     qWarning() << "Use Sprite::frameDuration for the old meaning, of per frame duration.";
253     qWarning() << "As an interim measure, duration/durationVariation means the same as frameDuration/frameDurationVariation, and you'll get this warning spewed out everywhere to movtivate you.";
254     //Note that the spammyness is due to this being the best location to detect, but also called once each animation loop
255     return QQuickStochasticState::variedDuration() * m_frames;
256 }
257
258 QT_END_NAMESPACE