Merge master into api_changes
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickspriteengine_p.h
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 #ifndef QQUICKSPRITEENGINE_P_H
43 #define QQUICKSPRITEENGINE_P_H
44
45 #include <QObject>
46 #include <QVector>
47 #include <QTimer>
48 #include <QTime>
49 #include <QList>
50 #include <QQmlListProperty>
51 #include <QImage>
52 #include <QPair>
53 #include <QtQuick/private/qquickpixmapcache_p.h>
54
55 QT_BEGIN_HEADER
56
57 QT_BEGIN_NAMESPACE
58
59 class QQuickSprite;
60 class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup
61 {
62     Q_OBJECT
63     Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
64     Q_PROPERTY(int durationVariation READ durationVariation WRITE setDurationVariation NOTIFY durationVariationChanged)
65     //Note that manually advanced sprites need to query this variable and implement own behaviour for it
66     Q_PROPERTY(bool randomStart READ randomStart WRITE setRandomStart NOTIFY randomStartChanged)
67     Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged)
68     Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
69
70 public:
71     QQuickStochasticState(QObject* parent = 0)
72         : QObject(parent)
73         , m_duration(1000)
74         , m_durationVariation(0)
75         , m_randomStart(false)
76     {
77     }
78
79     int duration() const
80     {
81         return m_duration;
82     }
83
84     QString name() const
85     {
86         return m_name;
87     }
88
89     QVariantMap to() const
90     {
91         return m_to;
92     }
93
94     int durationVariation() const
95     {
96         return m_durationVariation;
97     }
98
99
100     virtual int variedDuration() const
101     {
102         return qMax(qreal(0.0) , m_duration
103                 + (m_durationVariation * ((qreal)qrand()/RAND_MAX) * 2)
104                 - m_durationVariation);
105     }
106
107     bool randomStart() const
108     {
109         return m_randomStart;
110     }
111
112 signals:
113     void durationChanged(int arg);
114
115     void nameChanged(QString arg);
116
117     void toChanged(QVariantMap arg);
118
119     void durationVariationChanged(int arg);
120
121     void entered();//### Just playing around - don't expect full state API
122
123     void randomStartChanged(bool arg);
124
125 public slots:
126     void setDuration(int arg)
127     {
128         if (m_duration != arg) {
129             m_duration = arg;
130             emit durationChanged(arg);
131         }
132     }
133
134     void setName(QString arg)
135     {
136         if (m_name != arg) {
137             m_name = arg;
138             emit nameChanged(arg);
139         }
140     }
141
142     void setTo(QVariantMap arg)
143     {
144         if (m_to != arg) {
145             m_to = arg;
146             emit toChanged(arg);
147         }
148     }
149
150     void setDurationVariation(int arg)
151     {
152         if (m_durationVariation != arg) {
153             m_durationVariation = arg;
154             emit durationVariationChanged(arg);
155         }
156     }
157
158     void setRandomStart(bool arg)
159     {
160         if (m_randomStart != arg) {
161             m_randomStart = arg;
162             emit randomStartChanged(arg);
163         }
164     }
165
166 private:
167     QString m_name;
168     QVariantMap m_to;
169     int m_duration;
170     int m_durationVariation;
171
172     friend class QQuickStochasticEngine;
173     bool m_randomStart;
174 };
175
176 class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject
177 {
178     Q_OBJECT
179     //TODO: Optimize single state case?
180     Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged)
181     Q_PROPERTY(QQmlListProperty<QQuickStochasticState> states READ states)
182 public:
183     explicit QQuickStochasticEngine(QObject *parent = 0);
184     QQuickStochasticEngine(QList<QQuickStochasticState*> states, QObject *parent=0);
185     ~QQuickStochasticEngine();
186
187     QQmlListProperty<QQuickStochasticState> states()
188     {
189         return QQmlListProperty<QQuickStochasticState>(this, m_states);
190     }
191
192     QString globalGoal() const
193     {
194         return m_globalGoal;
195     }
196
197     int count() const {return m_things.count();}
198     void setCount(int c);
199
200     void setGoal(int state, int sprite=0, bool jump=false);
201     void start(int index=0, int state=0);
202     virtual void restart(int index=0);
203     virtual void advance(int index=0);//Sends state to the next chosen state, unlike goal.
204     void stop(int index=0);
205     int curState(int index=0) {return m_things[index];}
206
207     QQuickStochasticState* state(int idx){return m_states[idx];}
208     int stateIndex(QQuickStochasticState* s){return m_states.indexOf(s);}
209     int stateIndex(const QString& s) {
210         for (int i=0; i<m_states.count(); i++)
211             if (m_states[i]->name() == s)
212                 return i;
213         return -1;
214     }
215
216     int stateCount() {return m_states.count();}
217 private:
218 signals:
219
220     void globalGoalChanged(QString arg);
221     void stateChanged(int idx);
222
223 public slots:
224     void setGlobalGoal(QString arg)
225     {
226         if (m_globalGoal != arg) {
227             m_globalGoal = arg;
228             emit globalGoalChanged(arg);
229         }
230     }
231
232     uint updateSprites(uint time);
233
234 protected:
235     friend class QQuickParticleSystem;
236     void addToUpdateList(uint t, int idx);
237     int nextState(int curState, int idx=0);
238     int goalSeek(int curState, int idx, int dist=-1);
239     QList<QQuickStochasticState*> m_states;
240     //### Consider struct or class for the four data variables?
241     QVector<int> m_things;//int is the index in m_states of the current state
242     QVector<int> m_goals;
243     QVector<int> m_duration;
244     QVector<int> m_startTimes;
245     QList<QPair<uint, QList<int> > > m_stateUpdates;//### This could be done faster - priority queue?
246
247     QTime m_advanceTime;
248     uint m_timeOffset;
249     QString m_globalGoal;
250     int m_maxFrames;
251     int m_imageStateCount;
252     bool m_addAdvance;
253 };
254
255 class QQuickSpriteEngine : public QQuickStochasticEngine
256 {
257     Q_OBJECT
258     Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites)
259 public:
260     explicit QQuickSpriteEngine(QObject *parent = 0);
261     QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent=0);
262     ~QQuickSpriteEngine();
263     QQmlListProperty<QQuickSprite> sprites()
264     {
265         return QQmlListProperty<QQuickSprite>(this, m_sprites);
266     }
267
268     QQuickSprite* sprite(int sprite=0);
269     int spriteState(int sprite=0);
270     int spriteStart(int sprite=0);
271     int spriteFrames(int sprite=0);
272     int spriteDuration(int sprite=0);
273     int spriteX(int sprite=0);
274     int spriteY(int sprite=0);
275     int spriteWidth(int sprite=0);
276     int spriteHeight(int sprite=0);
277     int spriteCount();//Like state count
278     int maxFrames();
279
280     virtual void restart(int index=0);
281     virtual void advance(int index=0);
282
283     //Similar API to QQuickPixmap for async loading convenience
284     bool isNull() { return status() == QQuickPixmap::Null; }
285     bool isReady() { return status() == QQuickPixmap::Ready; }
286     bool isLoading() { return status() == QQuickPixmap::Loading; }
287     bool isError() { return status() == QQuickPixmap::Error; }
288     QQuickPixmap::Status status();//Composed status of all Sprites
289     void startAssemblingImage();
290     QImage assembledImage();
291
292 private:
293     int pseudospriteProgress(int,int,int*rd=0);
294     QList<QQuickSprite*> m_sprites;
295     bool m_startedImageAssembly;
296 };
297
298 //Common use is to have your own list property which is transparently an engine
299 inline void spriteAppend(QQmlListProperty<QQuickSprite> *p, QQuickSprite* s)
300 {
301     reinterpret_cast<QList<QQuickSprite *> *>(p->data)->append(s);
302     p->object->metaObject()->invokeMethod(p->object, "createEngine");
303 }
304
305 inline QQuickSprite* spriteAt(QQmlListProperty<QQuickSprite> *p, int idx)
306 {
307     return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->at(idx);
308 }
309
310 inline void spriteClear(QQmlListProperty<QQuickSprite> *p)
311 {
312     reinterpret_cast<QList<QQuickSprite *> *>(p->data)->clear();
313     p->object->metaObject()->invokeMethod(p->object, "createEngine");
314 }
315
316 inline int spriteCount(QQmlListProperty<QQuickSprite> *p)
317 {
318     return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
319 }
320
321 QT_END_NAMESPACE
322
323 QT_END_HEADER
324
325 #endif // QQUICKSPRITEENGINE_P_H