1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include "qquickanimationcontroller_p.h"
43 #include <QtQml/qqmlinfo.h>
44 #include <private/qqmlengine_p.h>
49 class QQuickAnimationControllerPrivate : public QObjectPrivate, QAnimationJobChangeListener
51 Q_DECLARE_PUBLIC(QQuickAnimationController)
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);
60 QQuickAbstractAnimation *animation;
61 QAbstractAnimationJob *animationInstance;
66 void QQuickAnimationControllerPrivate::animationFinished(QAbstractAnimationJob *job)
68 Q_Q(QQuickAnimationController);
69 Q_ASSERT(animationInstance && animationInstance == job);
71 animationInstance->removeAnimationChangeListener(this, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
73 if (animationInstance->direction() == QAbstractAnimationJob::Forward && progress != 1) {
75 emit q->progressChanged();
76 } else if (animationInstance->direction() == QAbstractAnimationJob::Backward && progress != 0) {
78 emit q->progressChanged();
83 void QQuickAnimationControllerPrivate::animationCurrentTimeChanged(QAbstractAnimationJob *job, int currentTime)
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();
95 \qmlclass AnimationController QQuickAnimationController
96 \inqmlmodule QtQuick 2
97 \ingroup qml-animation-transition
98 \brief Enables manual control of animations
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.
105 QQuickAnimationController::QQuickAnimationController(QObject *parent)
106 : QObject(*(new QQuickAnimationControllerPrivate), parent)
110 QQuickAnimationController::~QQuickAnimationController()
112 Q_D(QQuickAnimationController);
113 delete d->animationInstance;
117 \qmlproperty real QtQuick2::AnimationController::progress
118 This property holds the animation progress value.
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.
123 qreal QQuickAnimationController::progress() const
125 Q_D(const QQuickAnimationController);
129 void QQuickAnimationController::setProgress(qreal progress)
131 Q_D(QQuickAnimationController);
132 progress = qBound(qreal(0), progress, qreal(1));
134 if (progress != d->progress) {
135 d->progress = progress;
137 emit progressChanged();
142 \qmlproperty real QtQuick2::AnimationController::animation
145 This property holds the animation to be controlled by the AnimationController.
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).
151 QQuickAbstractAnimation *QQuickAnimationController::animation() const
153 Q_D(const QQuickAnimationController);
157 void QQuickAnimationController::classBegin()
159 QQmlEnginePrivate *engPriv = QQmlEnginePrivate::get(qmlEngine(this));
160 engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
164 void QQuickAnimationController::setAnimation(QQuickAbstractAnimation *animation)
166 Q_D(QQuickAnimationController);
168 if (animation != d->animation) {
170 if (animation->userControlDisabled()) {
171 qmlInfo(this) << "QQuickAnimationController::setAnimation: the animation is controlled by others, can't be used in AnimationController.";
174 animation->setDisableUserControl();
178 d->animation->setEnableUserControl();
180 d->animation = animation;
182 emit animationChanged();
187 \qmlmethod QtQuick2::AnimationController::reload()
188 \brief Reloads the animation properties
190 If the animation properties changed, calling this method to reload the animation definations.
192 void QQuickAnimationController::reload()
194 Q_D(QQuickAnimationController);
199 d->animationInstance = 0;
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)
207 d->animationInstance->setLoopCount(1);
208 d->animationInstance->setDisableUserControl();
209 d->animationInstance->start();
210 d->animationInstance->pause();
215 void QQuickAnimationController::updateProgress()
217 Q_D(QQuickAnimationController);
218 if (!d->animationInstance)
221 d->animationInstance->setDisableUserControl();
222 d->animationInstance->start();
223 QQmlAnimationTimer::unregisterAnimation(d->animationInstance);
224 d->animationInstance->setCurrentTime(d->progress * d->animationInstance->duration());
227 void QQuickAnimationController::componentFinalized()
229 Q_D(QQuickAnimationController);
235 \qmlmethod QtQuick2::AnimationController::completeToBeginning()
236 \brief Finishes running the controlled animation in a backwards direction.
238 After calling this method, the animation runs normally from the current progress point
239 in a backwards direction to the beginning state.
241 The animation controller's progress value will be automatically updated while the animation is running.
243 \sa completeToEnd(), progress()
245 void QQuickAnimationController::completeToBeginning()
247 Q_D(QQuickAnimationController);
248 if (!d->animationInstance)
251 if (d->progress == 0)
254 d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
255 d->animationInstance->setDirection(QAbstractAnimationJob::Backward);
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();
264 \qmlmethod QtQuick2::AnimationController::completeToEnd()
265 \brief Finishes running the controlled animation in a forwards direction.
267 After calling this method, the animation runs normally from the current progress point
268 in a forwards direction to the end state.
270 The animation controller's progress value will be automatically updated while the animation is running.
272 \sa completeToBeginning(), progress()
274 void QQuickAnimationController::completeToEnd()
276 Q_D(QQuickAnimationController);
277 if (!d->animationInstance)
280 if (d->progress == 1)
283 d->animationInstance->addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentTime);
284 d->animationInstance->setDirection(QAbstractAnimationJob::Forward);
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();