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 QtDeclarative 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 "qdeclarativetransition_p.h"
44 #include "qdeclarativestate_p.h"
45 #include "qdeclarativestate_p_p.h"
46 #include "qdeclarativestateoperations_p.h"
47 #include "qdeclarativeanimation_p.h"
48 #include "qdeclarativeanimation_p_p.h"
49 #include "qdeclarativetransitionmanager_p_p.h"
51 #include <QParallelAnimationGroup>
56 \qmlclass Transition QDeclarativeTransition
57 \inqmlmodule QtQuick 2
58 \ingroup qml-animation-transition
59 \brief The Transition element defines animated transitions that occur on state changes.
61 A Transition defines the animations to be applied when a \l State change occurs.
63 For example, the following \l Rectangle has two states: the default state, and
64 an added "moved" state. In the "moved state, the rectangle's position changes
65 to (50, 50). The added Transition specifies that when the rectangle
66 changes between the default and the "moved" state, any changes
67 to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad.
69 \snippet doc/src/snippets/declarative/transition.qml 0
71 Notice the example does not require \l{PropertyAnimation::}{to} and
72 \l{PropertyAnimation::}{from} values for the NumberAnimation. As a convenience,
73 these properties are automatically set to the values of \c x and \c y before
74 and after the state change; the \c from values are provided by
75 the current values of \c x and \c y, and the \c to values are provided by
76 the PropertyChanges object. If you wish, you can provide \l{PropertyAnimation::}{to} and
77 \l{PropertyAnimation::}{from} values anyway to override the default values.
79 By default, a Transition's animations are applied for any state change in the
80 parent item. The Transition \l {Transition::}{from} and \l {Transition::}{to}
81 values can be set to restrict the animations to only be applied when changing
82 from one particular state to another.
84 To define multiple transitions, specify \l Item::transitions as a list:
86 \snippet doc/src/snippets/declarative/transitions-list.qml list of transitions
88 If multiple Transitions are specified, only a single (best-matching) Transition will be applied for any particular
89 state change. In the example above, when changing to \c state1, the first transition will be used, rather
90 than the more generic second transition.
92 If a state change has a Transition that matches the same property as a
93 \l Behavior, the Transition animation overrides the \l Behavior for that
96 \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
99 //ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
100 //and disconnecting signals and slots frequently
101 class ParallelAnimationWrapper : public QParallelAnimationGroup
105 ParallelAnimationWrapper(QObject *parent = 0) : QParallelAnimationGroup(parent) {}
106 QDeclarativeTransitionPrivate *trans;
108 virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
111 class QDeclarativeTransitionPrivate : public QObjectPrivate
113 Q_DECLARE_PUBLIC(QDeclarativeTransition)
115 QDeclarativeTransitionPrivate()
116 : fromState(QLatin1String("*")), toState(QLatin1String("*")),
117 reversed(false), reversible(false), enabled(true), manager(0)
127 ParallelAnimationWrapper group;
128 QDeclarativeTransitionManager *manager;
134 static void append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a);
135 static int animation_count(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list);
136 static QDeclarativeAbstractAnimation* animation_at(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, int pos);
137 static void clear_animations(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list);
138 QList<QDeclarativeAbstractAnimation *> animations;
141 void QDeclarativeTransitionPrivate::append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a)
143 QDeclarativeTransition *q = static_cast<QDeclarativeTransition *>(list->object);
144 q->d_func()->animations.append(a);
145 q->d_func()->group.addAnimation(a->qtAnimation());
146 a->setDisableUserControl();
149 int QDeclarativeTransitionPrivate::animation_count(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list)
151 QDeclarativeTransition *q = static_cast<QDeclarativeTransition *>(list->object);
152 return q->d_func()->animations.count();
155 QDeclarativeAbstractAnimation* QDeclarativeTransitionPrivate::animation_at(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, int pos)
157 QDeclarativeTransition *q = static_cast<QDeclarativeTransition *>(list->object);
158 return q->d_func()->animations.at(pos);
161 void QDeclarativeTransitionPrivate::clear_animations(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list)
163 QDeclarativeTransition *q = static_cast<QDeclarativeTransition *>(list->object);
164 while (q->d_func()->animations.count()) {
165 QDeclarativeAbstractAnimation *firstAnim = q->d_func()->animations.at(0);
166 q->d_func()->group.removeAnimation(firstAnim->qtAnimation());
167 q->d_func()->animations.removeAll(firstAnim);
171 void ParallelAnimationWrapper::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
173 QParallelAnimationGroup::updateState(newState, oldState);
174 if (newState == Stopped && (duration() == -1
175 || (direction() == QAbstractAnimation::Forward && currentLoopTime() == duration())
176 || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0)))
184 QDeclarativeTransition::QDeclarativeTransition(QObject *parent)
185 : QObject(*(new QDeclarativeTransitionPrivate), parent)
189 QDeclarativeTransition::~QDeclarativeTransition()
193 void QDeclarativeTransition::stop()
195 Q_D(QDeclarativeTransition);
199 void QDeclarativeTransition::setReversed(bool r)
201 Q_D(QDeclarativeTransition);
205 void QDeclarativeTransition::prepare(QDeclarativeStateOperation::ActionList &actions,
206 QList<QDeclarativeProperty> &after,
207 QDeclarativeTransitionManager *manager)
209 Q_D(QDeclarativeTransition);
211 qmlExecuteDeferred(this);
214 for (int ii = d->animations.count() - 1; ii >= 0; --ii) {
215 d->animations.at(ii)->transition(actions, after, QDeclarativeAbstractAnimation::Backward);
218 for (int ii = 0; ii < d->animations.count(); ++ii) {
219 d->animations.at(ii)->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
223 d->manager = manager;
224 d->group.setDirection(d->reversed ? QAbstractAnimation::Backward : QAbstractAnimation::Forward);
229 \qmlproperty string QtQuick2::Transition::from
230 \qmlproperty string QtQuick2::Transition::to
232 These properties indicate the state changes that trigger the transition.
234 The default values for these properties is "*" (that is, any state).
236 For example, the following transition has not set the \c to and \c from
237 properties, so the animation is always applied when changing between
238 the two states (i.e. when the mouse is pressed and released).
240 \snippet doc/src/snippets/declarative/transition-from-to.qml 0
242 If the transition was changed to this:
244 \snippet doc/src/snippets/declarative/transition-from-to-modified.qml modified transition
246 The animation would only be applied when changing from the default state to
247 the "brighter" state (i.e. when the mouse is pressed, but not on release).
249 Multiple \c to and \from values can be set by using a comma-separated string.
253 QString QDeclarativeTransition::fromState() const
255 Q_D(const QDeclarativeTransition);
259 void QDeclarativeTransition::setFromState(const QString &f)
261 Q_D(QDeclarativeTransition);
262 if (f == d->fromState)
270 \qmlproperty bool QtQuick2::Transition::reversible
271 This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
273 The default value is false.
275 By default, transitions run in parallel and are applied to all state
276 changes if the \l from and \l to states have not been set. In this
277 situation, the transition is automatically applied when a state change
278 is reversed, and it is not necessary to set this property to reverse
281 However, if a SequentialAnimation is used, or if the \l from or \l to
282 properties have been set, this property will need to be set to reverse
283 a transition when a state change is reverted. For example, the following
284 transition applies a sequential animation when the mouse is pressed,
285 and reverses the sequence of the animation when the mouse is released:
287 \snippet doc/src/snippets/declarative/transition-reversible.qml 0
289 If the transition did not set the \c to and \c reversible values, then
290 on the mouse release, the transition would play the PropertyAnimation
291 before the ColorAnimation instead of reversing the sequence.
293 bool QDeclarativeTransition::reversible() const
295 Q_D(const QDeclarativeTransition);
296 return d->reversible;
299 void QDeclarativeTransition::setReversible(bool r)
301 Q_D(QDeclarativeTransition);
302 if (r == d->reversible)
306 emit reversibleChanged();
309 QString QDeclarativeTransition::toState() const
311 Q_D(const QDeclarativeTransition);
315 void QDeclarativeTransition::setToState(const QString &t)
317 Q_D(QDeclarativeTransition);
326 \qmlproperty bool QtQuick2::Transition::enabled
328 This property holds whether the Transition will be run when moving
329 from the \c from state to the \c to state.
331 By default a Transition is enabled.
333 Note that in some circumstances disabling a Transition may cause an
334 alternative Transition to be used in its place. In the following
335 example, the generic Transition will be used to animate the change
336 from \c state1 to \c state2, as the more specific Transition has
342 State { name: "state1" ... }
343 State { name: "state2" ... }
346 Transition { from: "state1"; to: "state2"; enabled: false ... }
353 bool QDeclarativeTransition::enabled() const
355 Q_D(const QDeclarativeTransition);
359 void QDeclarativeTransition::setEnabled(bool enabled)
361 Q_D(QDeclarativeTransition);
362 if (d->enabled == enabled)
364 d->enabled = enabled;
365 emit enabledChanged();
369 \qmlproperty list<Animation> QtQuick2::Transition::animations
372 This property holds a list of the animations to be run for this transition.
374 \snippet examples/declarative/toys/dynamicscene/dynamicscene.qml top-level transitions
376 The top-level animations are run in parallel. To run them sequentially,
377 define them within a SequentialAnimation:
379 \snippet doc/src/snippets/declarative/transition-reversible.qml sequential animations
381 QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeTransition::animations()
383 Q_D(QDeclarativeTransition);
384 return QDeclarativeListProperty<QDeclarativeAbstractAnimation>(this, &d->animations, QDeclarativeTransitionPrivate::append_animation,
385 QDeclarativeTransitionPrivate::animation_count,
386 QDeclarativeTransitionPrivate::animation_at,
387 QDeclarativeTransitionPrivate::clear_animations);
392 #include <qdeclarativetransition.moc>