1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativestate_p.h"
43 #include "private/qdeclarativestategroup_p.h"
44 #include "private/qdeclarativestate_p_p.h"
45 #include "private/qdeclarativestateoperations_p.h"
46 #include "private/qdeclarativeanimation_p.h"
47 #include "private/qdeclarativeanimation_p_p.h"
48 #include "private/qdeclarativetransitionmanager_p_p.h"
50 #include <QParallelAnimationGroup>
55 \qmlclass Transition QDeclarativeTransition
56 \ingroup qml-animation-transition
58 \brief The Transition element defines animated transitions that occur on state changes.
60 A Transition defines the animations to be applied when a \l State change occurs.
62 For example, the following \l Rectangle has two states: the default state, and
63 an added "moved" state. In the "moved state, the rectangle's position changes
64 to (50, 50). The added Transition specifies that when the rectangle
65 changes between the default and the "moved" state, any changes
66 to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad.
68 \snippet doc/src/snippets/declarative/transition.qml 0
70 Notice the example does not require \l{PropertyAnimation::}{to} and
71 \l{PropertyAnimation::}{from} values for the NumberAnimation. As a convenience,
72 these properties are automatically set to the values of \c x and \c y before
73 and after the state change; the \c from values are provided by
74 the current values of \c x and \c y, and the \c to values are provided by
75 the PropertyChanges object. If you wish, you can provide \l{PropertyAnimation::}{to} and
76 \l{PropertyAnimation::}{from} values anyway to override the default values.
78 By default, a Transition's animations are applied for any state change in the
79 parent item. The Transition \l {Transition::}{from} and \l {Transition::}{to}
80 values can be set to restrict the animations to only be applied when changing
81 from one particular state to another.
83 To define multiple transitions, specify \l Item::transitions as a list:
85 \snippet doc/src/snippets/declarative/transitions-list.qml list of transitions
87 If multiple Transitions are specified, only a single (best-matching) Transition will be applied for any particular
88 state change. In the example above, when changing to \c state1, the first transition will be used, rather
89 than the more generic second transition.
91 If a state change has a Transition that matches the same property as a
92 \l Behavior, the Transition animation overrides the \l Behavior for that
95 \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
98 //ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
99 //and disconnecting signals and slots frequently
100 class ParallelAnimationWrapper : public QParallelAnimationGroup
104 ParallelAnimationWrapper(QObject *parent = 0) : QParallelAnimationGroup(parent) {}
105 QDeclarativeTransitionPrivate *trans;
107 virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
110 class QDeclarativeTransitionPrivate : public QObjectPrivate
112 Q_DECLARE_PUBLIC(QDeclarativeTransition)
114 QDeclarativeTransitionPrivate()
115 : fromState(QLatin1String("*")), toState(QLatin1String("*")),
116 reversed(false), reversible(false), endState(0)
125 ParallelAnimationWrapper group;
126 QDeclarativeTransitionManager *endState;
130 endState->complete();
132 static void append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a);
133 QList<QDeclarativeAbstractAnimation *> animations;
136 void QDeclarativeTransitionPrivate::append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a)
138 QDeclarativeTransition *q = static_cast<QDeclarativeTransition *>(list->object);
139 q->d_func()->animations.append(a);
140 q->d_func()->group.addAnimation(a->qtAnimation());
141 a->setDisableUserControl();
144 void ParallelAnimationWrapper::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
146 QParallelAnimationGroup::updateState(newState, oldState);
147 if (newState == Stopped && (duration() == -1
148 || (direction() == QAbstractAnimation::Forward && currentLoopTime() == duration())
149 || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0)))
157 QDeclarativeTransition::QDeclarativeTransition(QObject *parent)
158 : QObject(*(new QDeclarativeTransitionPrivate), parent)
162 QDeclarativeTransition::~QDeclarativeTransition()
166 void QDeclarativeTransition::stop()
168 Q_D(QDeclarativeTransition);
172 void QDeclarativeTransition::setReversed(bool r)
174 Q_D(QDeclarativeTransition);
178 void QDeclarativeTransition::prepare(QDeclarativeStateOperation::ActionList &actions,
179 QList<QDeclarativeProperty> &after,
180 QDeclarativeTransitionManager *endState)
182 Q_D(QDeclarativeTransition);
184 qmlExecuteDeferred(this);
187 for (int ii = d->animations.count() - 1; ii >= 0; --ii) {
188 d->animations.at(ii)->transition(actions, after, QDeclarativeAbstractAnimation::Backward);
191 for (int ii = 0; ii < d->animations.count(); ++ii) {
192 d->animations.at(ii)->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
196 d->endState = endState;
197 d->group.setDirection(d->reversed ? QAbstractAnimation::Backward : QAbstractAnimation::Forward);
202 \qmlproperty string Transition::from
203 \qmlproperty string Transition::to
205 These properties indicate the state changes that trigger the transition.
207 The default values for these properties is "*" (that is, any state).
209 For example, the following transition has not set the \c to and \c from
210 properties, so the animation is always applied when changing between
211 the two states (i.e. when the mouse is pressed and released).
213 \snippet doc/src/snippets/declarative/transition-from-to.qml 0
215 If the transition was changed to this:
217 \snippet doc/src/snippets/declarative/transition-from-to-modified.qml modified transition
219 The animation would only be applied when changing from the default state to
220 the "brighter" state (i.e. when the mouse is pressed, but not on release).
224 QString QDeclarativeTransition::fromState() const
226 Q_D(const QDeclarativeTransition);
230 void QDeclarativeTransition::setFromState(const QString &f)
232 Q_D(QDeclarativeTransition);
233 if (f == d->fromState)
241 \qmlproperty bool Transition::reversible
242 This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
244 The default value is false.
246 By default, transitions run in parallel and are applied to all state
247 changes if the \l from and \l to states have not been set. In this
248 situation, the transition is automatically applied when a state change
249 is reversed, and it is not necessary to set this property to reverse
252 However, if a SequentialAnimation is used, or if the \l from or \l to
253 properties have been set, this property will need to be set to reverse
254 a transition when a state change is reverted. For example, the following
255 transition applies a sequential animation when the mouse is pressed,
256 and reverses the sequence of the animation when the mouse is released:
258 \snippet doc/src/snippets/declarative/transition-reversible.qml 0
260 If the transition did not set the \c to and \c reversible values, then
261 on the mouse release, the transition would play the PropertyAnimation
262 before the ColorAnimation instead of reversing the sequence.
264 bool QDeclarativeTransition::reversible() const
266 Q_D(const QDeclarativeTransition);
267 return d->reversible;
270 void QDeclarativeTransition::setReversible(bool r)
272 Q_D(QDeclarativeTransition);
273 if (r == d->reversible)
277 emit reversibleChanged();
280 QString QDeclarativeTransition::toState() const
282 Q_D(const QDeclarativeTransition);
286 void QDeclarativeTransition::setToState(const QString &t)
288 Q_D(QDeclarativeTransition);
297 \qmlproperty list<Animation> Transition::animations
300 This property holds a list of the animations to be run for this transition.
302 \snippet examples/declarative/toys/dynamicscene/dynamicscene.qml top-level transitions
304 The top-level animations are run in parallel. To run them sequentially,
305 define them within a SequentialAnimation:
307 \snippet doc/src/snippets/declarative/transition-reversible.qml sequential animations
309 QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeTransition::animations()
311 Q_D(QDeclarativeTransition);
312 return QDeclarativeListProperty<QDeclarativeAbstractAnimation>(this, &d->animations, QDeclarativeTransitionPrivate::append_animation);
317 #include <qdeclarativetransition.moc>