source: trunk/src/declarative/util/qdeclarativetransition.cpp@ 918

Last change on this file since 918 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 11.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
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.
23**
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.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
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"
49
50#include <QParallelAnimationGroup>
51
52QT_BEGIN_NAMESPACE
53
54/*!
55 \qmlclass Transition QDeclarativeTransition
56 \ingroup qml-animation-transition
57 \since 4.7
58 \brief The Transition element defines animated transitions that occur on state changes.
59
60 A Transition defines the animations to be applied when a \l State change occurs.
61
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.
67
68 \snippet doc/src/snippets/declarative/transition.qml 0
69
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.
77
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.
82
83 To define multiple transitions, specify \l Item::transitions as a list:
84
85 \qml
86 Item {
87 ...
88 transitions: [
89 Transition { to: "state1" ... },
90 Transition { ... }
91 ]
92 }
93 \endqml
94
95 If multiple Transitions are specified, only a single (best-matching) Transition will be applied for any particular
96 state change. In the example above, when changing to \c state1, the first transition will be used, rather
97 than the more generic second transition.
98
99 If a state change has a Transition that matches the same property as a
100 \l Behavior, the Transition animation overrides the \l Behavior for that
101 state change.
102
103 \sa {QML Animation}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtDeclarative}
104*/
105
106//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
107//and disconnecting signals and slots frequently
108class ParallelAnimationWrapper : public QParallelAnimationGroup
109{
110 Q_OBJECT
111public:
112 ParallelAnimationWrapper(QObject *parent = 0) : QParallelAnimationGroup(parent) {}
113 QDeclarativeTransitionPrivate *trans;
114protected:
115 virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
116};
117
118class QDeclarativeTransitionPrivate : public QObjectPrivate
119{
120 Q_DECLARE_PUBLIC(QDeclarativeTransition)
121public:
122 QDeclarativeTransitionPrivate()
123 : fromState(QLatin1String("*")), toState(QLatin1String("*")),
124 reversed(false), reversible(false), endState(0)
125 {
126 group.trans = this;
127 }
128
129 QString fromState;
130 QString toState;
131 bool reversed;
132 bool reversible;
133 ParallelAnimationWrapper group;
134 QDeclarativeTransitionManager *endState;
135
136 void complete()
137 {
138 endState->complete();
139 }
140 static void append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a);
141 QList<QDeclarativeAbstractAnimation *> animations;
142};
143
144void QDeclarativeTransitionPrivate::append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a)
145{
146 QDeclarativeTransition *q = static_cast<QDeclarativeTransition *>(list->object);
147 q->d_func()->animations.append(a);
148 q->d_func()->group.addAnimation(a->qtAnimation());
149 a->setDisableUserControl();
150}
151
152void ParallelAnimationWrapper::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
153{
154 QParallelAnimationGroup::updateState(newState, oldState);
155 if (newState == Stopped && (duration() == -1
156 || (direction() == QAbstractAnimation::Forward && currentLoopTime() == duration())
157 || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0)))
158 {
159 trans->complete();
160 }
161}
162
163
164
165QDeclarativeTransition::QDeclarativeTransition(QObject *parent)
166 : QObject(*(new QDeclarativeTransitionPrivate), parent)
167{
168}
169
170QDeclarativeTransition::~QDeclarativeTransition()
171{
172}
173
174void QDeclarativeTransition::stop()
175{
176 Q_D(QDeclarativeTransition);
177 d->group.stop();
178}
179
180void QDeclarativeTransition::setReversed(bool r)
181{
182 Q_D(QDeclarativeTransition);
183 d->reversed = r;
184}
185
186void QDeclarativeTransition::prepare(QDeclarativeStateOperation::ActionList &actions,
187 QList<QDeclarativeProperty> &after,
188 QDeclarativeTransitionManager *endState)
189{
190 Q_D(QDeclarativeTransition);
191
192 qmlExecuteDeferred(this);
193
194 if (d->reversed) {
195 for (int ii = d->animations.count() - 1; ii >= 0; --ii) {
196 d->animations.at(ii)->transition(actions, after, QDeclarativeAbstractAnimation::Backward);
197 }
198 } else {
199 for (int ii = 0; ii < d->animations.count(); ++ii) {
200 d->animations.at(ii)->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
201 }
202 }
203
204 d->endState = endState;
205 d->group.setDirection(d->reversed ? QAbstractAnimation::Backward : QAbstractAnimation::Forward);
206 d->group.start();
207}
208
209/*!
210 \qmlproperty string Transition::from
211 \qmlproperty string Transition::to
212
213 These properties indicate the state changes that trigger the transition.
214
215 The default values for these properties is "*" (that is, any state).
216
217 For example, the following transition has not set the \c to and \c from
218 properties, so the animation is always applied when changing between
219 the two states (i.e. when the mouse is pressed and released).
220
221 \snippet doc/src/snippets/declarative/transition-from-to.qml 0
222
223 If the transition was changed to this:
224
225 \qml
226 transitions: Transition {
227 to: "brighter"
228 ColorAnimation { duration: 1000 }
229 }
230 }
231 \endqml
232
233 The animation would only be applied when changing from the default state to
234 the "brighter" state (i.e. when the mouse is pressed, but not on release).
235
236 \sa reversible
237*/
238QString QDeclarativeTransition::fromState() const
239{
240 Q_D(const QDeclarativeTransition);
241 return d->fromState;
242}
243
244void QDeclarativeTransition::setFromState(const QString &f)
245{
246 Q_D(QDeclarativeTransition);
247 if (f == d->fromState)
248 return;
249
250 d->fromState = f;
251 emit fromChanged();
252}
253
254/*!
255 \qmlproperty bool Transition::reversible
256 This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
257
258 The default value is false.
259
260 By default, transitions run in parallel and are applied to all state
261 changes if the \l from and \l to states have not been set. In this
262 situation, the transition is automatically applied when a state change
263 is reversed, and it is not necessary to set this property to reverse
264 the transition.
265
266 However, if a SequentialAnimation is used, or if the \l from or \l to
267 properties have been set, this property will need to be set to reverse
268 a transition when a state change is reverted. For example, the following
269 transition applies a sequential animation when the mouse is pressed,
270 and reverses the sequence of the animation when the mouse is released:
271
272 \snippet doc/src/snippets/declarative/transition-reversible.qml 0
273
274 If the transition did not set the \c to and \c reversible values, then
275 on the mouse release, the transition would play the PropertyAnimation
276 before the ColorAnimation instead of reversing the sequence.
277*/
278bool QDeclarativeTransition::reversible() const
279{
280 Q_D(const QDeclarativeTransition);
281 return d->reversible;
282}
283
284void QDeclarativeTransition::setReversible(bool r)
285{
286 Q_D(QDeclarativeTransition);
287 if (r == d->reversible)
288 return;
289
290 d->reversible = r;
291 emit reversibleChanged();
292}
293
294QString QDeclarativeTransition::toState() const
295{
296 Q_D(const QDeclarativeTransition);
297 return d->toState;
298}
299
300void QDeclarativeTransition::setToState(const QString &t)
301{
302 Q_D(QDeclarativeTransition);
303 if (t == d->toState)
304 return;
305
306 d->toState = t;
307 emit toChanged();
308}
309
310/*!
311 \qmlproperty list<Animation> Transition::animations
312 \default
313
314 This property holds a list of the animations to be run for this transition.
315
316 \qml
317 Transition {
318 PropertyAnimation { ... }
319 NumberAnimation { ... }
320 }
321 \endqml
322
323 The top-level animations are run in parallel. To run them sequentially,
324 define them within a SequentialAnimation:
325
326 \qml
327 Transition {
328 SequentialAnimation {
329 PropertyAnimation { ... }
330 NumberAnimation { ... }
331 }
332 }
333 \endqml
334*/
335QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeTransition::animations()
336{
337 Q_D(QDeclarativeTransition);
338 return QDeclarativeListProperty<QDeclarativeAbstractAnimation>(this, &d->animations, QDeclarativeTransitionPrivate::append_animation);
339}
340
341QT_END_NAMESPACE
342
343#include <qdeclarativetransition.moc>
Note: See TracBrowser for help on using the repository browser.