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