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 "QtQuick1/private/qdeclarativestate_p.h"
43 #include "QtQuick1/private/qdeclarativestategroup_p.h"
44 #include "QtQuick1/private/qdeclarativestate_p_p.h"
45 #include "QtQuick1/private/qdeclarativestateoperations_p.h"
46 #include "QtQuick1/private/qdeclarativeanimation_p.h"
47 #include "QtQuick1/private/qdeclarativeanimation_p_p.h"
48 #include "QtQuick1/private/qdeclarativetransitionmanager_p_p.h"
50 #include <QParallelAnimationGroup>
57 \qmlclass Transition QDeclarative1Transition
58 \inqmlmodule QtQuick 1
59 \ingroup qml-animation-transition
61 \brief The Transition element defines animated transitions that occur on state changes.
63 A Transition defines the animations to be applied when a \l State change occurs.
65 For example, the following \l Rectangle has two states: the default state, and
66 an added "moved" state. In the "moved state, the rectangle's position changes
67 to (50, 50). The added Transition specifies that when the rectangle
68 changes between the default and the "moved" state, any changes
69 to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad.
71 \snippet doc/src/snippets/qtquick1/transition.qml 0
73 Notice the example does not require \l{PropertyAnimation::}{to} and
74 \l{PropertyAnimation::}{from} values for the NumberAnimation. As a convenience,
75 these properties are automatically set to the values of \c x and \c y before
76 and after the state change; the \c from values are provided by
77 the current values of \c x and \c y, and the \c to values are provided by
78 the PropertyChanges object. If you wish, you can provide \l{PropertyAnimation::}{to} and
79 \l{PropertyAnimation::}{from} values anyway to override the default values.
81 By default, a Transition's animations are applied for any state change in the
82 parent item. The Transition \l {Transition::}{from} and \l {Transition::}{to}
83 values can be set to restrict the animations to only be applied when changing
84 from one particular state to another.
86 To define multiple transitions, specify \l Item::transitions as a list:
88 \snippet doc/src/snippets/qtquick1/transitions-list.qml list of transitions
90 If multiple Transitions are specified, only a single (best-matching) Transition will be applied for any particular
91 state change. In the example above, when changing to \c state1, the first transition will be used, rather
92 than the more generic second transition.
94 If a state change has a Transition that matches the same property as a
95 \l Behavior, the Transition animation overrides the \l Behavior for that
98 \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
101 //ParallelAnimationWrapper_1 allows us to do a "callback" when the animation finishes, rather than connecting
102 //and disconnecting signals and slots frequently
103 class ParallelAnimationWrapper_1 : public QParallelAnimationGroup
107 ParallelAnimationWrapper_1(QObject *parent = 0) : QParallelAnimationGroup(parent) {}
108 QDeclarative1TransitionPrivate *trans;
110 virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
113 class QDeclarative1TransitionPrivate : public QObjectPrivate
115 Q_DECLARE_PUBLIC(QDeclarative1Transition)
117 QDeclarative1TransitionPrivate()
118 : fromState(QLatin1String("*")), toState(QLatin1String("*")),
119 reversed(false), reversible(false), endState(0)
128 ParallelAnimationWrapper_1 group;
129 QDeclarative1TransitionManager *endState;
133 endState->complete();
135 static void append_animation(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list, QDeclarative1AbstractAnimation *a);
136 static int animation_count(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list);
137 static QDeclarative1AbstractAnimation* animation_at(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list, int pos);
138 static void clear_animations(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list);
139 QList<QDeclarative1AbstractAnimation *> animations;
142 void QDeclarative1TransitionPrivate::append_animation(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list, QDeclarative1AbstractAnimation *a)
144 QDeclarative1Transition *q = static_cast<QDeclarative1Transition *>(list->object);
145 q->d_func()->animations.append(a);
146 q->d_func()->group.addAnimation(a->qtAnimation());
147 a->setDisableUserControl();
150 int QDeclarative1TransitionPrivate::animation_count(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list)
152 QDeclarative1Transition *q = static_cast<QDeclarative1Transition *>(list->object);
153 return q->d_func()->animations.count();
156 QDeclarative1AbstractAnimation* QDeclarative1TransitionPrivate::animation_at(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list, int pos)
158 QDeclarative1Transition *q = static_cast<QDeclarative1Transition *>(list->object);
159 return q->d_func()->animations.at(pos);
162 void QDeclarative1TransitionPrivate::clear_animations(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list)
164 QDeclarative1Transition *q = static_cast<QDeclarative1Transition *>(list->object);
165 while (q->d_func()->animations.count()) {
166 QDeclarative1AbstractAnimation *firstAnim = q->d_func()->animations.at(0);
167 q->d_func()->group.removeAnimation(firstAnim->qtAnimation());
168 q->d_func()->animations.removeAll(firstAnim);
172 void ParallelAnimationWrapper_1::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
174 QParallelAnimationGroup::updateState(newState, oldState);
175 if (newState == Stopped && (duration() == -1
176 || (direction() == QAbstractAnimation::Forward && currentLoopTime() == duration())
177 || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0)))
185 QDeclarative1Transition::QDeclarative1Transition(QObject *parent)
186 : QObject(*(new QDeclarative1TransitionPrivate), parent)
190 QDeclarative1Transition::~QDeclarative1Transition()
194 void QDeclarative1Transition::stop()
196 Q_D(QDeclarative1Transition);
200 void QDeclarative1Transition::setReversed(bool r)
202 Q_D(QDeclarative1Transition);
206 void QDeclarative1Transition::prepare(QDeclarative1StateOperation::ActionList &actions,
207 QList<QDeclarativeProperty> &after,
208 QDeclarative1TransitionManager *endState)
210 Q_D(QDeclarative1Transition);
212 qmlExecuteDeferred(this);
215 for (int ii = d->animations.count() - 1; ii >= 0; --ii) {
216 d->animations.at(ii)->transition(actions, after, QDeclarative1AbstractAnimation::Backward);
219 for (int ii = 0; ii < d->animations.count(); ++ii) {
220 d->animations.at(ii)->transition(actions, after, QDeclarative1AbstractAnimation::Forward);
224 d->endState = endState;
225 d->group.setDirection(d->reversed ? QAbstractAnimation::Backward : QAbstractAnimation::Forward);
230 \qmlproperty string QtQuick1::Transition::from
231 \qmlproperty string QtQuick1::Transition::to
233 These properties indicate the state changes that trigger the transition.
235 The default values for these properties is "*" (that is, any state).
237 For example, the following transition has not set the \c to and \c from
238 properties, so the animation is always applied when changing between
239 the two states (i.e. when the mouse is pressed and released).
241 \snippet doc/src/snippets/qtquick1/transition-from-to.qml 0
243 If the transition was changed to this:
245 \snippet doc/src/snippets/qtquick1/transition-from-to-modified.qml modified transition
247 The animation would only be applied when changing from the default state to
248 the "brighter" state (i.e. when the mouse is pressed, but not on release).
250 Multiple \c to and \from values can be set by using a comma-separated string.
254 QString QDeclarative1Transition::fromState() const
256 Q_D(const QDeclarative1Transition);
260 void QDeclarative1Transition::setFromState(const QString &f)
262 Q_D(QDeclarative1Transition);
263 if (f == d->fromState)
271 \qmlproperty bool QtQuick1::Transition::reversible
272 This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
274 The default value is false.
276 By default, transitions run in parallel and are applied to all state
277 changes if the \l from and \l to states have not been set. In this
278 situation, the transition is automatically applied when a state change
279 is reversed, and it is not necessary to set this property to reverse
282 However, if a SequentialAnimation is used, or if the \l from or \l to
283 properties have been set, this property will need to be set to reverse
284 a transition when a state change is reverted. For example, the following
285 transition applies a sequential animation when the mouse is pressed,
286 and reverses the sequence of the animation when the mouse is released:
288 \snippet doc/src/snippets/qtquick1/transition-reversible.qml 0
290 If the transition did not set the \c to and \c reversible values, then
291 on the mouse release, the transition would play the PropertyAnimation
292 before the ColorAnimation instead of reversing the sequence.
294 bool QDeclarative1Transition::reversible() const
296 Q_D(const QDeclarative1Transition);
297 return d->reversible;
300 void QDeclarative1Transition::setReversible(bool r)
302 Q_D(QDeclarative1Transition);
303 if (r == d->reversible)
307 emit reversibleChanged();
310 QString QDeclarative1Transition::toState() const
312 Q_D(const QDeclarative1Transition);
316 void QDeclarative1Transition::setToState(const QString &t)
318 Q_D(QDeclarative1Transition);
327 \qmlproperty list<Animation> QtQuick1::Transition::animations
330 This property holds a list of the animations to be run for this transition.
332 \snippet examples/declarative/toys/dynamicscene/dynamicscene.qml top-level transitions
334 The top-level animations are run in parallel. To run them sequentially,
335 define them within a SequentialAnimation:
337 \snippet doc/src/snippets/qtquick1/transition-reversible.qml sequential animations
339 QDeclarativeListProperty<QDeclarative1AbstractAnimation> QDeclarative1Transition::animations()
341 Q_D(QDeclarative1Transition);
342 return QDeclarativeListProperty<QDeclarative1AbstractAnimation>(this, &d->animations, QDeclarative1TransitionPrivate::append_animation,
343 QDeclarative1TransitionPrivate::animation_count,
344 QDeclarative1TransitionPrivate::animation_at,
345 QDeclarative1TransitionPrivate::clear_animations);
352 #include <qdeclarativetransition.moc>