Doc: Sanitized QML types
[profile/ivi/qtdeclarative.git] / src / quick / util / qquickanimationcontroller.cpp
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 QtQml 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 #include "qquickanimationcontroller_p.h"
43 #include <QtQml/qqmlinfo.h>
44 #include <private/qqmlengine_p.h>
45
46 QT_BEGIN_NAMESPACE
47
48
49 class QQuickAnimationControllerPrivate : public QObjectPrivate, QAnimationJobChangeListener
50 {
51     Q_DECLARE_PUBLIC(QQuickAnimationController)
52 public:
53     QQuickAnimationControllerPrivate()
54         : progress(0.0), animation(0), animationInstance(0), finalized(false) {}
55     virtual void animationFinished(QAbstractAnimationJob *job);
56     virtual void animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime);
57
58
59     qreal progress;
60     QQuickAbstractAnimation *animation;
61     QAbstractAnimationJob *animationInstance;
62     bool finalized:1;
63
64 };
65
66 void QQuickAnimationControllerPrivate::animationFinished(QAbstractAnimationJob *job)
67 {
68     Q_Q(QQuickAnimationController);
69     Q_ASSERT(animationInstance && animationInstance == job);
70
71     animationInstance->removeAnimationChangeListener(this, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
72
73     if (animationInstance->direction() == QAbstractAnimationJob::Forward && progress != 1) {
74         progress = 1;
75         emit q->progressChanged();
76     } else if (animationInstance->direction() == QAbstractAnimationJob::Backward && progress != 0) {
77         progress = 0;
78         emit q->progressChanged();
79     }
80
81 }
82
83 void QQuickAnimationControllerPrivate::animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime)
84 {
85     Q_Q(QQuickAnimationController);
86     Q_ASSERT(animationInstance && animationInstance == job);
87     const qreal newProgress = currentTime * 1.0 / animationInstance->duration();
88     if (progress != newProgress) {
89         progress = newProgress;
90         emit q->progressChanged();
91     }
92 }
93
94 /*!
95     \qmlclass AnimationController QQuickAnimationController
96     \inqmlmodule QtQuick 2
97     \ingroup qml-animation-transition
98     \brief Enables manual control of animations
99
100     Normally animations are driven by an internal timer, but the AnimationController
101     allows the given \a animation to be driven by a \a progress value explicitly.
102 */
103
104
105 QQuickAnimationController::QQuickAnimationController(QObject *parent)
106 : QObject(*(new QQuickAnimationControllerPrivate), parent)
107 {
108 }
109
110 QQuickAnimationController::~QQuickAnimationController()
111 {
112     Q_D(QQuickAnimationController);
113     delete d->animationInstance;
114 }
115
116 /*!
117     \qmlproperty real QtQuick2::AnimationController::progress
118     This property holds the animation progress value.
119
120     The valid \c progress value is 0.0 to 1.0, setting values less than 0 will be converted to 0,
121     setting values great than 1 will be converted to 1.
122 */
123 qreal QQuickAnimationController::progress() const
124 {
125     Q_D(const QQuickAnimationController);
126     return d->progress;
127 }
128
129 void QQuickAnimationController::setProgress(qreal progress)
130 {
131     Q_D(QQuickAnimationController);
132     progress = qBound(qreal(0), progress, qreal(1));
133
134     if (progress != d->progress) {
135         d->progress = progress;
136         updateProgress();
137         emit progressChanged();
138     }
139 }
140
141 /*!
142     \qmlproperty real QtQuick2::AnimationController::animation
143     \default
144
145     This property holds the animation to be controlled by the AnimationController.
146
147     Note:An animation controlled by AnimationController will always have its
148          \c running and \c paused properties set to true. It can not be manually
149          started or stopped (much like an animation in a Behavior can not be manually started or stopped).
150 */
151 QQuickAbstractAnimation *QQuickAnimationController::animation() const
152 {
153     Q_D(const QQuickAnimationController);
154     return d->animation;
155 }
156
157 void QQuickAnimationController::classBegin()
158 {
159     QQmlEnginePrivate *engPriv = QQmlEnginePrivate::get(qmlEngine(this));
160     engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
161 }
162
163
164 void QQuickAnimationController::setAnimation(QQuickAbstractAnimation *animation)
165 {
166     Q_D(QQuickAnimationController);
167
168     if (animation != d->animation) {
169         if (animation) {
170             if (animation->userControlDisabled()) {
171                 qmlInfo(this) << "QQuickAnimationController::setAnimation: the animation is controlled by others, can't be used in AnimationController.";
172                 return;
173             }
174             animation->setDisableUserControl();
175         }
176
177         if (d->animation)
178             d->animation->setEnableUserControl();
179
180         d->animation = animation;
181         reload();
182         emit animationChanged();
183     }
184 }
185
186 /*!
187     \qmlmethod QtQuick2::AnimationController::reload()
188     \brief Reloads the animation properties
189
190     If the animation properties changed, calling this method to reload the animation definations.
191 */
192 void QQuickAnimationController::reload()
193 {
194     Q_D(QQuickAnimationController);
195     if (!d->finalized)
196         return;
197
198     if (!d->animation) {
199         d->animationInstance = 0;
200     } else {
201         QQuickStateActions actions;
202         QQmlProperties properties;
203         QAbstractAnimationJob *oldInstance = d->animationInstance;
204         d->animationInstance = d->animation->transition(actions, properties, QQuickAbstractAnimation::Forward);
205         if (oldInstance && oldInstance != d->animationInstance)
206             delete oldInstance;
207         d->animationInstance->setLoopCount(1);
208         d->animationInstance->setDisableUserControl();
209         d->animationInstance->start();
210         d->animationInstance->pause();
211         updateProgress();
212     }
213 }
214
215 void QQuickAnimationController::updateProgress()
216 {
217     Q_D(QQuickAnimationController);
218     if (!d->animationInstance)
219         return;
220
221     d->animationInstance->setDisableUserControl();
222     d->animationInstance->start();
223     QQmlAnimationTimer::unregisterAnimation(d->animationInstance);
224     d->animationInstance->setCurrentTime(d->progress * d->animationInstance->duration());
225 }
226
227 void QQuickAnimationController::componentFinalized()
228 {
229     Q_D(QQuickAnimationController);
230     d->finalized = true;
231     reload();
232 }
233
234 /*!
235     \qmlmethod QtQuick2::AnimationController::completeToBeginning()
236     \brief Finishes running the controlled animation in a backwards direction.
237
238     After calling this method, the animation runs normally from the current progress point
239     in a backwards direction to the beginning state.
240
241     The animation controller's progress value will be automatically updated while the animation is running.
242
243     \sa completeToEnd(), progress()
244 */
245 void QQuickAnimationController::completeToBeginning()
246 {
247     Q_D(QQuickAnimationController);
248     if (!d->animationInstance)
249         return;
250
251     if (d->progress == 0)
252         return;
253
254     d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
255     d->animationInstance->setDirection(QAbstractAnimationJob::Backward);
256
257     //Disable and then enable user control to trigger the animation instance's state change
258     d->animationInstance->setDisableUserControl();
259     d->animationInstance->setEnableUserControl();
260     d->animationInstance->start();
261 }
262
263 /*!
264     \qmlmethod QtQuick2::AnimationController::completeToEnd()
265     \brief Finishes running the controlled animation in a forwards direction.
266
267     After calling this method, the animation runs normally from the current progress point
268     in a forwards direction to the end state.
269
270     The animation controller's progress value will be automatically updated while the animation is running.
271
272     \sa completeToBeginning(), progress()
273 */
274 void QQuickAnimationController::completeToEnd()
275 {
276     Q_D(QQuickAnimationController);
277     if (!d->animationInstance)
278         return;
279
280     if (d->progress == 1)
281         return;
282
283     d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
284     d->animationInstance->setDirection(QAbstractAnimationJob::Forward);
285
286     //Disable and then enable user control to trigger the animation instance's state change
287     d->animationInstance->setDisableUserControl();
288     d->animationInstance->setEnableUserControl();
289     d->animationInstance->start();
290 }
291
292
293
294 QT_END_NAMESPACE
295
296