1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QDECLARATIVEANIMATION_P_H
43 #define QDECLARATIVEANIMATION_P_H
44 
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 
56 #include "private/qdeclarativeanimation_p.h"
57 
58 #include "private/qdeclarativenullablevalue_p_p.h"
59 #include "private/qdeclarativetimeline_p_p.h"
60 
61 #include <qdeclarative.h>
62 #include <qdeclarativeitem.h>
63 #include <qdeclarativecontext.h>
64 
65 #include <QtCore/QPauseAnimation>
66 #include <QtCore/QVariantAnimation>
67 #include <QtCore/QAnimationGroup>
68 #include <QtGui/QColor>
69 #include <QDebug>
70 
71 #include <private/qobject_p.h>
72 #include <private/qvariantanimation_p.h>
73 
74 QT_BEGIN_NAMESPACE
75 
76 //interface for classes that provide animation actions for QActionAnimation
77 class QAbstractAnimationAction
78 {
79 public:
~QAbstractAnimationAction()80     virtual ~QAbstractAnimationAction() {}
81     virtual void doAction() = 0;
82 };
83 
84 //templated animation action
85 //allows us to specify an action that calls a function of a class.
86 //(so that class doesn't have to inherit QDeclarativeAbstractAnimationAction)
87 template<class T, void (T::*method)()>
88 class QAnimationActionProxy : public QAbstractAnimationAction
89 {
90 public:
QAnimationActionProxy(T * p)91     QAnimationActionProxy(T *p) : m_p(p) {}
doAction()92     virtual void doAction() { (m_p->*method)(); }
93 
94 private:
95     T *m_p;
96 };
97 
98 //performs an action of type QAbstractAnimationAction
99 class Q_AUTOTEST_EXPORT QActionAnimation : public QAbstractAnimation
100 {
101     Q_OBJECT
102 public:
QAbstractAnimation(parent)103     QActionAnimation(QObject *parent = 0) : QAbstractAnimation(parent), animAction(0), policy(KeepWhenStopped) {}
104     QActionAnimation(QAbstractAnimationAction *action, QObject *parent = 0)
QAbstractAnimation(parent)105         : QAbstractAnimation(parent), animAction(action), policy(KeepWhenStopped) {}
~QActionAnimation()106     ~QActionAnimation() { if (policy == DeleteWhenStopped) { delete animAction; animAction = 0; } }
duration()107     virtual int duration() const { return 0; }
setAnimAction(QAbstractAnimationAction * action,DeletionPolicy p)108     void setAnimAction(QAbstractAnimationAction *action, DeletionPolicy p)
109     {
110         if (state() == Running)
111             stop();
112         if (policy == DeleteWhenStopped)
113             delete animAction;
114         animAction = action;
115         policy = p;
116     }
117 protected:
updateCurrentTime(int)118     virtual void updateCurrentTime(int) {}
119 
updateState(State newState,State)120     virtual void updateState(State newState, State /*oldState*/)
121     {
122         if (newState == Running) {
123             if (animAction) {
124                 animAction->doAction();
125                 if (state() == Stopped && policy == DeleteWhenStopped) {
126                     delete animAction;
127                     animAction = 0;
128                 }
129             }
130         }
131     }
132 
133 private:
134     QAbstractAnimationAction *animAction;
135     DeletionPolicy policy;
136 };
137 
138 class QDeclarativeBulkValueUpdater
139 {
140 public:
~QDeclarativeBulkValueUpdater()141     virtual ~QDeclarativeBulkValueUpdater() {}
142     virtual void setValue(qreal value) = 0;
143 };
144 
145 //animates QDeclarativeBulkValueUpdater (assumes start and end values will be reals or compatible)
146 class Q_AUTOTEST_EXPORT QDeclarativeBulkValueAnimator : public QVariantAnimation
147 {
148     Q_OBJECT
149 public:
QVariantAnimation(parent)150     QDeclarativeBulkValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {}
~QDeclarativeBulkValueAnimator()151     ~QDeclarativeBulkValueAnimator() { if (policy == DeleteWhenStopped) { delete animValue; animValue = 0; } }
setAnimValue(QDeclarativeBulkValueUpdater * value,DeletionPolicy p)152     void setAnimValue(QDeclarativeBulkValueUpdater *value, DeletionPolicy p)
153     {
154         if (state() == Running)
155             stop();
156         if (policy == DeleteWhenStopped)
157             delete animValue;
158         animValue = value;
159         policy = p;
160     }
setFromSourcedValue(bool * value)161     void setFromSourcedValue(bool *value)
162     {
163         fromSourced = value;
164     }
165 protected:
updateCurrentValue(const QVariant & value)166     virtual void updateCurrentValue(const QVariant &value)
167     {
168         if (state() == QAbstractAnimation::Stopped)
169             return;
170 
171         if (animValue)
172             animValue->setValue(value.toReal());
173     }
updateState(State newState,State oldState)174     virtual void updateState(State newState, State oldState)
175     {
176         QVariantAnimation::updateState(newState, oldState);
177         if (newState == Running) {
178             //check for new from every loop
179             if (fromSourced)
180                 *fromSourced = false;
181         }
182     }
183 
184 private:
185     QDeclarativeBulkValueUpdater *animValue;
186     bool *fromSourced;
187     DeletionPolicy policy;
188 };
189 
190 //an animation that just gives a tick
191 template<class T, void (T::*method)(int)>
192 class QTickAnimationProxy : public QAbstractAnimation
193 {
194     //Q_OBJECT //doesn't work with templating
195 public:
QAbstractAnimation(parent)196     QTickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {}
duration()197     virtual int duration() const { return -1; }
198 protected:
updateCurrentTime(int msec)199     virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); }
200 
201 private:
202     T *m_p;
203 };
204 
205 class QDeclarativeAbstractAnimationPrivate : public QObjectPrivate
206 {
Q_DECLARE_PUBLIC(QDeclarativeAbstractAnimation)207     Q_DECLARE_PUBLIC(QDeclarativeAbstractAnimation)
208 public:
209     QDeclarativeAbstractAnimationPrivate()
210     : running(false), paused(false), alwaysRunToEnd(false),
211       connectedTimeLine(false), componentComplete(true),
212       avoidPropertyValueSourceStart(false), disableUserControl(false),
213       registered(false), loopCount(1), group(0) {}
214 
215     bool running:1;
216     bool paused:1;
217     bool alwaysRunToEnd:1;
218     bool connectedTimeLine:1;
219     bool componentComplete:1;
220     bool avoidPropertyValueSourceStart:1;
221     bool disableUserControl:1;
222     bool registered:1;
223 
224     int loopCount;
225 
226     void commence();
227 
228     QDeclarativeProperty defaultProperty;
229 
230     QDeclarativeAnimationGroup *group;
231 
232     static QDeclarativeProperty createProperty(QObject *obj, const QString &str, QObject *infoObj);
233 };
234 
235 class QDeclarativePauseAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
236 {
Q_DECLARE_PUBLIC(QDeclarativePauseAnimation)237     Q_DECLARE_PUBLIC(QDeclarativePauseAnimation)
238 public:
239     QDeclarativePauseAnimationPrivate()
240     : QDeclarativeAbstractAnimationPrivate(), pa(0) {}
241 
242     void init();
243 
244     QPauseAnimation *pa;
245 };
246 
247 class QDeclarativeScriptActionPrivate : public QDeclarativeAbstractAnimationPrivate
248 {
249     Q_DECLARE_PUBLIC(QDeclarativeScriptAction)
250 public:
251     QDeclarativeScriptActionPrivate();
252 
253     void init();
254 
255     QDeclarativeScriptString script;
256     QString name;
257     QDeclarativeScriptString runScriptScript;
258     bool hasRunScriptScript;
259     bool reversing;
260 
261     void execute();
262 
263     QAnimationActionProxy<QDeclarativeScriptActionPrivate,
264                   &QDeclarativeScriptActionPrivate::execute> proxy;
265     QActionAnimation *rsa;
266 };
267 
268 class QDeclarativePropertyActionPrivate : public QDeclarativeAbstractAnimationPrivate
269 {
Q_DECLARE_PUBLIC(QDeclarativePropertyAction)270     Q_DECLARE_PUBLIC(QDeclarativePropertyAction)
271 public:
272     QDeclarativePropertyActionPrivate()
273     : QDeclarativeAbstractAnimationPrivate(), target(0), spa(0) {}
274 
275     void init();
276 
277     QObject *target;
278     QString propertyName;
279     QString properties;
280     QList<QObject *> targets;
281     QList<QObject *> exclude;
282 
283     QDeclarativeNullableValue<QVariant> value;
284 
285     QActionAnimation *spa;
286 };
287 
288 class QDeclarativeAnimationGroupPrivate : public QDeclarativeAbstractAnimationPrivate
289 {
Q_DECLARE_PUBLIC(QDeclarativeAnimationGroup)290     Q_DECLARE_PUBLIC(QDeclarativeAnimationGroup)
291 public:
292     QDeclarativeAnimationGroupPrivate()
293     : QDeclarativeAbstractAnimationPrivate(), ag(0) {}
294 
295     static void append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *role);
296     static void clear_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list);
297     QList<QDeclarativeAbstractAnimation *> animations;
298     QAnimationGroup *ag;
299 };
300 
301 class QDeclarativePropertyAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
302 {
Q_DECLARE_PUBLIC(QDeclarativePropertyAnimation)303     Q_DECLARE_PUBLIC(QDeclarativePropertyAnimation)
304 public:
305     QDeclarativePropertyAnimationPrivate()
306     : QDeclarativeAbstractAnimationPrivate(), target(0), fromSourced(false), fromIsDefined(false), toIsDefined(false),
307       rangeIsSet(false), defaultToInterpolatorType(0), interpolatorType(0), interpolator(0), va(0), actions(0) {}
308 
309     void init();
310 
311     QVariant from;
312     QVariant to;
313 
314     QObject *target;
315     QString propertyName;
316     QString properties;
317     QList<QObject *> targets;
318     QList<QObject *> exclude;
319     QString defaultProperties;
320 
321     bool fromSourced;
322     bool fromIsDefined:1;
323     bool toIsDefined:1;
324     bool rangeIsSet:1;
325     bool defaultToInterpolatorType:1;
326     int interpolatorType;
327     QVariantAnimation::Interpolator interpolator;
328 
329     QDeclarativeBulkValueAnimator *va;
330 
331     // for animations that don't use the QDeclarativeBulkValueAnimator
332     QDeclarativeStateActions *actions;
333 
334     static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress);
335     static void convertVariant(QVariant &variant, int type);
336 };
337 
338 class QDeclarativeRotationAnimationPrivate : public QDeclarativePropertyAnimationPrivate
339 {
Q_DECLARE_PUBLIC(QDeclarativeRotationAnimation)340     Q_DECLARE_PUBLIC(QDeclarativeRotationAnimation)
341 public:
342     QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Numerical) {}
343 
344     QDeclarativeRotationAnimation::RotationDirection direction;
345 };
346 
347 class QDeclarativeParentAnimationPrivate : public QDeclarativeAnimationGroupPrivate
348 {
Q_DECLARE_PUBLIC(QDeclarativeParentAnimation)349     Q_DECLARE_PUBLIC(QDeclarativeParentAnimation)
350 public:
351     QDeclarativeParentAnimationPrivate()
352     : QDeclarativeAnimationGroupPrivate(), target(0), newParent(0),
353        via(0), topLevelGroup(0), startAction(0), endAction(0) {}
354 
355     QDeclarativeItem *target;
356     QDeclarativeItem *newParent;
357     QDeclarativeItem *via;
358 
359     QSequentialAnimationGroup *topLevelGroup;
360     QActionAnimation *startAction;
361     QActionAnimation *endAction;
362 
363     QPointF computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const;
364 };
365 
366 class QDeclarativeAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
367 {
Q_DECLARE_PUBLIC(QDeclarativeAnchorAnimation)368     Q_DECLARE_PUBLIC(QDeclarativeAnchorAnimation)
369 public:
370     QDeclarativeAnchorAnimationPrivate() : rangeIsSet(false), va(0),
371         interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {}
372 
373     bool rangeIsSet;
374     QDeclarativeBulkValueAnimator *va;
375     QVariantAnimation::Interpolator interpolator;
376     QList<QDeclarativeItem*> targets;
377 };
378 
379 class Q_AUTOTEST_EXPORT QDeclarativeAnimationPropertyUpdater : public QDeclarativeBulkValueUpdater
380 {
381 public:
382     QDeclarativeStateActions actions;
383     int interpolatorType;       //for Number/ColorAnimation
384     int prevInterpolatorType;   //for generic
385     QVariantAnimation::Interpolator interpolator;
386     bool reverse;
387     bool fromSourced;
388     bool fromDefined;
389     bool *wasDeleted;
QDeclarativeAnimationPropertyUpdater()390     QDeclarativeAnimationPropertyUpdater() : prevInterpolatorType(0), wasDeleted(0) {}
~QDeclarativeAnimationPropertyUpdater()391     ~QDeclarativeAnimationPropertyUpdater() { if (wasDeleted) *wasDeleted = true; }
392     void setValue(qreal v);
393 };
394 
395 QT_END_NAMESPACE
396 
397 #endif // QDECLARATIVEANIMATION_P_H
398