Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / qtquick1 / util / qdeclarativetransition.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 QtDeclarative 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 "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"
49
50 #include <QParallelAnimationGroup>
51
52 QT_BEGIN_NAMESPACE
53
54
55
56 /*!
57     \qmlclass Transition QDeclarative1Transition
58     \inqmlmodule QtQuick 1
59     \ingroup qml-animation-transition
60     \since QtQuick 1.0
61     \brief The Transition element defines animated transitions that occur on state changes.
62
63     A Transition defines the animations to be applied when a \l State change occurs.
64
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.
70
71     \snippet doc/src/snippets/qtquick1/transition.qml 0
72
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.
80
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.
85
86     To define multiple transitions, specify \l Item::transitions as a list:
87
88     \snippet doc/src/snippets/qtquick1/transitions-list.qml list of transitions
89
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.
93
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
96     state change.
97
98     \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
99 */
100
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
104 {
105     Q_OBJECT
106 public:
107     ParallelAnimationWrapper_1(QObject *parent = 0) : QParallelAnimationGroup(parent) {}
108     QDeclarative1TransitionPrivate *trans;
109 protected:
110     virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
111 };
112
113 class QDeclarative1TransitionPrivate : public QObjectPrivate
114 {
115     Q_DECLARE_PUBLIC(QDeclarative1Transition)
116 public:
117     QDeclarative1TransitionPrivate()
118     : fromState(QLatin1String("*")), toState(QLatin1String("*")),
119       reversed(false), reversible(false), endState(0)
120     {
121         group.trans = this;
122     }
123
124     QString fromState;
125     QString toState;
126     bool reversed;
127     bool reversible;
128     ParallelAnimationWrapper_1 group;
129     QDeclarative1TransitionManager *endState;
130
131     void complete()
132     {
133         endState->complete();
134     }
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;
140 };
141
142 void QDeclarative1TransitionPrivate::append_animation(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list, QDeclarative1AbstractAnimation *a)
143 {
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();
148 }
149
150 int QDeclarative1TransitionPrivate::animation_count(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list)
151 {
152     QDeclarative1Transition *q = static_cast<QDeclarative1Transition *>(list->object);
153     return q->d_func()->animations.count();
154 }
155
156 QDeclarative1AbstractAnimation* QDeclarative1TransitionPrivate::animation_at(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list, int pos)
157 {
158     QDeclarative1Transition *q = static_cast<QDeclarative1Transition *>(list->object);
159     return q->d_func()->animations.at(pos);
160 }
161
162 void QDeclarative1TransitionPrivate::clear_animations(QDeclarativeListProperty<QDeclarative1AbstractAnimation> *list)
163 {
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);
169     }
170 }
171
172 void ParallelAnimationWrapper_1::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
173 {
174     QParallelAnimationGroup::updateState(newState, oldState);
175     if (newState == Stopped && (duration() == -1
176         || (direction() == QAbstractAnimation::Forward && currentLoopTime() == duration())
177         || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0)))
178     {
179         trans->complete();
180     }
181 }
182
183
184
185 QDeclarative1Transition::QDeclarative1Transition(QObject *parent)
186     : QObject(*(new QDeclarative1TransitionPrivate), parent)
187 {
188 }
189
190 QDeclarative1Transition::~QDeclarative1Transition()
191 {
192 }
193
194 void QDeclarative1Transition::stop()
195 {
196     Q_D(QDeclarative1Transition);
197     d->group.stop();
198 }
199
200 void QDeclarative1Transition::setReversed(bool r)
201 {
202     Q_D(QDeclarative1Transition);
203     d->reversed = r;
204 }
205
206 void QDeclarative1Transition::prepare(QDeclarative1StateOperation::ActionList &actions,
207                             QList<QDeclarativeProperty> &after,
208                             QDeclarative1TransitionManager *endState)
209 {
210     Q_D(QDeclarative1Transition);
211
212     qmlExecuteDeferred(this);
213
214     if (d->reversed) {
215         for (int ii = d->animations.count() - 1; ii >= 0; --ii) {
216             d->animations.at(ii)->transition(actions, after, QDeclarative1AbstractAnimation::Backward);
217         }
218     } else {
219         for (int ii = 0; ii < d->animations.count(); ++ii) {
220             d->animations.at(ii)->transition(actions, after, QDeclarative1AbstractAnimation::Forward);
221         }
222     }
223
224     d->endState = endState;
225     d->group.setDirection(d->reversed ? QAbstractAnimation::Backward : QAbstractAnimation::Forward);
226     d->group.start();
227 }
228
229 /*!
230     \qmlproperty string QtQuick1::Transition::from
231     \qmlproperty string QtQuick1::Transition::to
232
233     These properties indicate the state changes that trigger the transition.
234
235     The default values for these properties is "*" (that is, any state).
236
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).
240
241     \snippet doc/src/snippets/qtquick1/transition-from-to.qml 0
242
243     If the transition was changed to this:
244
245     \snippet doc/src/snippets/qtquick1/transition-from-to-modified.qml modified transition
246
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).
249
250     Multiple \c to and \from values can be set by using a comma-separated string.
251
252     \sa reversible
253 */
254 QString QDeclarative1Transition::fromState() const
255 {
256     Q_D(const QDeclarative1Transition);
257     return d->fromState;
258 }
259
260 void QDeclarative1Transition::setFromState(const QString &f)
261 {
262     Q_D(QDeclarative1Transition);
263     if (f == d->fromState)
264         return;
265
266     d->fromState = f;
267     emit fromChanged();
268 }
269
270 /*!
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.
273
274     The default value is false.
275
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
280     the transition.
281
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:
287
288     \snippet doc/src/snippets/qtquick1/transition-reversible.qml 0
289
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.
293 */
294 bool QDeclarative1Transition::reversible() const
295 {
296     Q_D(const QDeclarative1Transition);
297     return d->reversible;
298 }
299
300 void QDeclarative1Transition::setReversible(bool r)
301 {
302     Q_D(QDeclarative1Transition);
303     if (r == d->reversible)
304         return;
305
306     d->reversible = r;
307     emit reversibleChanged();
308 }
309
310 QString QDeclarative1Transition::toState() const
311 {
312     Q_D(const QDeclarative1Transition);
313     return d->toState;
314 }
315
316 void QDeclarative1Transition::setToState(const QString &t)
317 {
318     Q_D(QDeclarative1Transition);
319     if (t == d->toState)
320         return;
321
322     d->toState = t;
323     emit toChanged();
324 }
325
326 /*!
327     \qmlproperty list<Animation> QtQuick1::Transition::animations
328     \default
329
330     This property holds a list of the animations to be run for this transition.
331
332     \snippet examples/declarative/toys/dynamicscene/dynamicscene.qml top-level transitions
333
334     The top-level animations are run in parallel. To run them sequentially,
335     define them within a SequentialAnimation:
336
337     \snippet doc/src/snippets/qtquick1/transition-reversible.qml sequential animations
338 */
339 QDeclarativeListProperty<QDeclarative1AbstractAnimation> QDeclarative1Transition::animations()
340 {
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);
346 }
347
348
349
350 QT_END_NAMESPACE
351
352 #include <qdeclarativetransition.moc>