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