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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "private/qdeclarativeanimation_p.h"
43 #include "private/qdeclarativeanimation_p_p.h"
45 #include "private/qdeclarativebehavior_p.h"
46 #include "private/qdeclarativestateoperations_p.h"
47 #include "private/qdeclarativecontext_p.h"
49 #include <qdeclarativepropertyvaluesource.h>
50 #include <qdeclarative.h>
51 #include <qdeclarativeinfo.h>
52 #include <qdeclarativeexpression.h>
53 #include <qdeclarativestringconverters_p.h>
54 #include <qdeclarativeglobal_p.h>
55 #include <qdeclarativemetatype_p.h>
56 #include <qdeclarativevaluetype_p.h>
57 #include <qdeclarativeproperty_p.h>
58 #include <qdeclarativeengine_p.h>
63 #include <QParallelAnimationGroup>
64 #include <QSequentialAnimationGroup>
65 #include <QtCore/qset.h>
66 #include <QtCore/qrect.h>
67 #include <QtCore/qpoint.h>
68 #include <QtCore/qsize.h>
69 #include <QtCore/qmath.h>
71 #include <private/qvariantanimation_p.h>
76 \qmlclass Animation QDeclarativeAbstractAnimation
77 \ingroup qml-animation-transition
79 \brief The Animation element is the base of all QML animations.
81 The Animation element cannot be used directly in a QML file. It exists
82 to provide a set of common properties and methods, available across all the
83 other animation types that inherit from it. Attempting to use the Animation
84 element directly will result in an error.
87 QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QObject *parent)
88 : QObject(*(new QDeclarativeAbstractAnimationPrivate), parent)
92 QDeclarativeAbstractAnimation::~QDeclarativeAbstractAnimation()
96 QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QDeclarativeAbstractAnimationPrivate &dd, QObject *parent)
102 \qmlproperty bool Animation::running
103 This property holds whether the animation is currently running.
105 The \c running property can be set to declaratively control whether or not
106 an animation is running. The following example will animate a rectangle
107 whenever the \l MouseArea is pressed.
111 width: 100; height: 100
112 NumberAnimation on x {
113 running: myMouse.pressed
116 MouseArea { id: myMouse }
120 Likewise, the \c running property can be read to determine if the animation
121 is running. In the following example the text element will indicate whether
122 or not the animation is running.
125 NumberAnimation { id: myAnimation }
126 Text { text: myAnimation.running ? "Animation is running" : "Animation is not running" }
129 Animations can also be started and stopped imperatively from JavaScript
130 using the \c start() and \c stop() methods.
132 By default, animations are not running. Though, when the animations are assigned to properties,
133 as property value sources using the \e on syntax, they are set to running by default.
135 bool QDeclarativeAbstractAnimation::isRunning() const
137 Q_D(const QDeclarativeAbstractAnimation);
141 // the behavior calls this function
142 void QDeclarativeAbstractAnimation::notifyRunningChanged(bool running)
144 Q_D(QDeclarativeAbstractAnimation);
145 if (d->disableUserControl && d->running != running) {
146 d->running = running;
147 emit runningChanged(running);
151 //commence is called to start an animation when it is used as a
152 //simple animation, and not as part of a transition
153 void QDeclarativeAbstractAnimationPrivate::commence()
155 Q_Q(QDeclarativeAbstractAnimation);
157 QDeclarativeStateActions actions;
158 QDeclarativeProperties properties;
159 q->transition(actions, properties, QDeclarativeAbstractAnimation::Forward);
161 q->qtAnimation()->start();
162 if (q->qtAnimation()->state() != QAbstractAnimation::Running) {
168 QDeclarativeProperty QDeclarativeAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj)
170 QDeclarativeProperty prop(obj, str, qmlContext(infoObj));
171 if (!prop.isValid()) {
172 qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate non-existent property \"%1\"").arg(str);
173 return QDeclarativeProperty();
174 } else if (!prop.isWritable()) {
175 qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str);
176 return QDeclarativeProperty();
181 void QDeclarativeAbstractAnimation::setRunning(bool r)
183 Q_D(QDeclarativeAbstractAnimation);
184 if (!d->componentComplete) {
187 d->avoidPropertyValueSourceStart = true;
188 else if (!d->registered) {
189 d->registered = true;
190 QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
191 engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
199 if (d->group || d->disableUserControl) {
200 qmlInfo(this) << "setRunning() cannot be used on non-root animation nodes.";
206 bool supressStart = false;
207 if (d->alwaysRunToEnd && d->loopCount != 1
208 && qtAnimation()->state() == QAbstractAnimation::Running) {
209 //we've restarted before the final loop finished; restore proper loop count
210 if (d->loopCount == -1)
211 qtAnimation()->setLoopCount(d->loopCount);
213 qtAnimation()->setLoopCount(qtAnimation()->currentLoop() + d->loopCount);
214 supressStart = true; //we want the animation to continue, rather than restart
217 if (!d->connectedTimeLine) {
218 QObject::connect(qtAnimation(), SIGNAL(finished()),
219 this, SLOT(timelineComplete()));
220 d->connectedTimeLine = true;
226 if (d->alwaysRunToEnd) {
227 if (d->loopCount != 1)
228 qtAnimation()->setLoopCount(qtAnimation()->currentLoop()+1); //finish the current loop
230 qtAnimation()->stop();
235 emit runningChanged(d->running);
239 \qmlproperty bool Animation::paused
240 This property holds whether the animation is currently paused.
242 The \c paused property can be set to declaratively control whether or not
243 an animation is paused.
245 Animations can also be paused and resumed imperatively from JavaScript
246 using the \c pause() and \c resume() methods.
248 By default, animations are not paused.
250 bool QDeclarativeAbstractAnimation::isPaused() const
252 Q_D(const QDeclarativeAbstractAnimation);
256 void QDeclarativeAbstractAnimation::setPaused(bool p)
258 Q_D(QDeclarativeAbstractAnimation);
262 if (d->group || d->disableUserControl) {
263 qmlInfo(this) << "setPaused() cannot be used on non-root animation nodes.";
269 qtAnimation()->pause();
271 qtAnimation()->resume();
273 emit pausedChanged(d->paused);
276 void QDeclarativeAbstractAnimation::classBegin()
278 Q_D(QDeclarativeAbstractAnimation);
279 d->componentComplete = false;
282 void QDeclarativeAbstractAnimation::componentComplete()
284 Q_D(QDeclarativeAbstractAnimation);
285 d->componentComplete = true;
288 void QDeclarativeAbstractAnimation::componentFinalized()
290 Q_D(QDeclarativeAbstractAnimation);
298 \qmlproperty bool Animation::alwaysRunToEnd
299 This property holds whether the animation should run to completion when it is stopped.
301 If this true the animation will complete its current iteration when it
302 is stopped - either by setting the \c running property to false, or by
303 calling the \c stop() method. The \c complete() method is not effected
306 This behavior is most useful when the \c repeat property is set, as the
307 animation will finish playing normally but not restart.
309 By default, the alwaysRunToEnd property is not set.
311 \note alwaysRunToEnd has no effect on animations in a Transition.
313 bool QDeclarativeAbstractAnimation::alwaysRunToEnd() const
315 Q_D(const QDeclarativeAbstractAnimation);
316 return d->alwaysRunToEnd;
319 void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f)
321 Q_D(QDeclarativeAbstractAnimation);
322 if (d->alwaysRunToEnd == f)
325 d->alwaysRunToEnd = f;
326 emit alwaysRunToEndChanged(f);
330 \qmlproperty int Animation::loops
331 This property holds the number of times the animation should play.
333 By default, \c loops is 1: the animation will play through once and then stop.
335 If set to Animation.Infinite, the animation will continuously repeat until it is explicitly
336 stopped - either by setting the \c running property to false, or by calling
337 the \c stop() method.
339 In the following example, the rectangle will spin indefinitely.
343 width: 100; height: 100; color: "green"
344 RotationAnimation on rotation {
345 loops: Animation.Infinite
352 int QDeclarativeAbstractAnimation::loops() const
354 Q_D(const QDeclarativeAbstractAnimation);
358 void QDeclarativeAbstractAnimation::setLoops(int loops)
360 Q_D(QDeclarativeAbstractAnimation);
364 if (loops == d->loopCount)
367 d->loopCount = loops;
368 qtAnimation()->setLoopCount(loops);
369 emit loopCountChanged(loops);
373 int QDeclarativeAbstractAnimation::currentTime()
375 return qtAnimation()->currentLoopTime();
378 void QDeclarativeAbstractAnimation::setCurrentTime(int time)
380 qtAnimation()->setCurrentTime(time);
383 QDeclarativeAnimationGroup *QDeclarativeAbstractAnimation::group() const
385 Q_D(const QDeclarativeAbstractAnimation);
389 void QDeclarativeAbstractAnimation::setGroup(QDeclarativeAnimationGroup *g)
391 Q_D(QDeclarativeAbstractAnimation);
395 static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.removeAll(this);
399 if (d->group && !static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.contains(this))
400 static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.append(this);
402 //if (g) //if removed from a group, then the group should no longer be the parent
407 \qmlmethod Animation::start()
408 \brief Starts the animation.
410 If the animation is already running, calling this method has no effect. The
411 \c running property will be true following a call to \c start().
413 void QDeclarativeAbstractAnimation::start()
419 \qmlmethod Animation::pause()
420 \brief Pauses the animation.
422 If the animation is already paused, calling this method has no effect. The
423 \c paused property will be true following a call to \c pause().
425 void QDeclarativeAbstractAnimation::pause()
431 \qmlmethod Animation::resume()
432 \brief Resumes a paused animation.
434 If the animation is not paused, calling this method has no effect. The
435 \c paused property will be false following a call to \c resume().
437 void QDeclarativeAbstractAnimation::resume()
443 \qmlmethod Animation::stop()
444 \brief Stops the animation.
446 If the animation is not running, calling this method has no effect. The
447 \c running property will be false following a call to \c stop().
449 Normally \c stop() stops the animation immediately, and the animation has
450 no further influence on property values. In this example animation
453 NumberAnimation on x { from: 0; to: 100; duration: 500 }
456 was stopped at time 250ms, the \c x property will have a value of 50.
458 However, if the \c alwaysRunToEnd property is set, the animation will
459 continue running until it completes and then stop. The \c running property
460 will still become false immediately.
462 void QDeclarativeAbstractAnimation::stop()
468 \qmlmethod Animation::restart()
469 \brief Restarts the animation.
471 This is a convenience method, and is equivalent to calling \c stop() and
474 void QDeclarativeAbstractAnimation::restart()
481 \qmlmethod Animation::complete()
482 \brief Stops the animation, jumping to the final property values.
484 If the animation is not running, calling this method has no effect. The
485 \c running property will be false following a call to \c complete().
487 Unlike \c stop(), \c complete() immediately fast-forwards the animation to
488 its end. In the following example,
491 NumberAnimation on x { from: 0; to: 100; duration: 500 }
494 calling \c stop() at time 250ms will result in the \c x property having
495 a value of 50, while calling \c complete() will set the \c x property to
496 100, exactly as though the animation had played the whole way through.
498 void QDeclarativeAbstractAnimation::complete()
501 qtAnimation()->setCurrentTime(qtAnimation()->duration());
505 void QDeclarativeAbstractAnimation::setTarget(const QDeclarativeProperty &p)
507 Q_D(QDeclarativeAbstractAnimation);
508 d->defaultProperty = p;
510 if (!d->avoidPropertyValueSourceStart)
515 we rely on setTarget only being called when used as a value source
516 so this function allows us to do the same thing as setTarget without
519 void QDeclarativeAbstractAnimation::setDefaultTarget(const QDeclarativeProperty &p)
521 Q_D(QDeclarativeAbstractAnimation);
522 d->defaultProperty = p;
526 don't allow start/stop/pause/resume to be manually invoked,
527 because something else (like a Behavior) already has control
530 void QDeclarativeAbstractAnimation::setDisableUserControl()
532 Q_D(QDeclarativeAbstractAnimation);
533 d->disableUserControl = true;
536 void QDeclarativeAbstractAnimation::transition(QDeclarativeStateActions &actions,
537 QDeclarativeProperties &modified,
538 TransitionDirection direction)
545 void QDeclarativeAbstractAnimation::timelineComplete()
547 Q_D(QDeclarativeAbstractAnimation);
549 if (d->alwaysRunToEnd && d->loopCount != 1) {
550 //restore the proper loopCount for the next run
551 qtAnimation()->setLoopCount(d->loopCount);
556 \qmlclass PauseAnimation QDeclarativePauseAnimation
557 \ingroup qml-animation-transition
560 \brief The PauseAnimation element provides a pause for an animation.
562 When used in a SequentialAnimation, PauseAnimation is a step when
563 nothing happens, for a specified duration.
565 A 500ms animation sequence, with a 100ms pause between two animations:
567 SequentialAnimation {
568 NumberAnimation { ... duration: 200 }
569 PauseAnimation { duration: 100 }
570 NumberAnimation { ... duration: 200 }
574 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
576 QDeclarativePauseAnimation::QDeclarativePauseAnimation(QObject *parent)
577 : QDeclarativeAbstractAnimation(*(new QDeclarativePauseAnimationPrivate), parent)
579 Q_D(QDeclarativePauseAnimation);
583 QDeclarativePauseAnimation::~QDeclarativePauseAnimation()
587 void QDeclarativePauseAnimationPrivate::init()
589 Q_Q(QDeclarativePauseAnimation);
590 pa = new QPauseAnimation;
591 QDeclarative_setParent_noEvent(pa, q);
595 \qmlproperty int PauseAnimation::duration
596 This property holds the duration of the pause in milliseconds
598 The default value is 250.
600 int QDeclarativePauseAnimation::duration() const
602 Q_D(const QDeclarativePauseAnimation);
603 return d->pa->duration();
606 void QDeclarativePauseAnimation::setDuration(int duration)
609 qmlInfo(this) << tr("Cannot set a duration of < 0");
613 Q_D(QDeclarativePauseAnimation);
614 if (d->pa->duration() == duration)
616 d->pa->setDuration(duration);
617 emit durationChanged(duration);
620 QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation()
622 Q_D(QDeclarativePauseAnimation);
627 \qmlclass ColorAnimation QDeclarativeColorAnimation
628 \ingroup qml-animation-transition
630 \inherits PropertyAnimation
631 \brief The ColorAnimation element animates changes in color values.
633 ColorAnimation is a specialized PropertyAnimation that defines an
634 animation to be applied when a color value changes.
636 Here is a ColorAnimation applied to the \c color property of a \l Rectangle
637 as a property value source. It animates the \c color property's value from
638 its current value to a value of "red", over 1000 milliseconds:
640 \snippet doc/src/snippets/declarative/coloranimation.qml 0
642 Like any other animation element, a ColorAnimation can be applied in a
643 number of ways, including transitions, behaviors and property value
644 sources. The \l {QML Animation and Transitions} documentation shows a
645 variety of methods for creating animations.
647 For convenience, when a ColorAnimation is used in a \l Transition, it will
648 animate any \c color properties that have been modified during the state
649 change. If a \l{PropertyAnimation::}{property} or
650 \l{PropertyAnimation::}{properties} are explicitly set for the animation,
651 then those are used instead.
653 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
655 QDeclarativeColorAnimation::QDeclarativeColorAnimation(QObject *parent)
656 : QDeclarativePropertyAnimation(parent)
658 Q_D(QDeclarativePropertyAnimation);
659 d->interpolatorType = QMetaType::QColor;
660 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
661 d->defaultToInterpolatorType = true;
664 QDeclarativeColorAnimation::~QDeclarativeColorAnimation()
669 \qmlproperty color ColorAnimation::from
670 This property holds the color value at which the animation should begin.
672 For example, the following animation is not applied until a color value
673 has reached "#c0c0c0":
678 // States are defined here...
681 transition: Transition {
682 NumberAnimation { from: "#c0c0c0"; duration: 2000 }
687 If the ColorAnimation is defined within a \l Transition or \l Behavior,
688 this value defaults to the value defined in the starting state of the
689 \l Transition, or the current value of the property at the moment the
690 \l Behavior is triggered.
692 \sa {QML Animation and Transitions}
694 QColor QDeclarativeColorAnimation::from() const
696 Q_D(const QDeclarativePropertyAnimation);
697 return d->from.value<QColor>();
700 void QDeclarativeColorAnimation::setFrom(const QColor &f)
702 QDeclarativePropertyAnimation::setFrom(f);
706 \qmlproperty color ColorAnimation::to
708 This property holds the color value at which the animation should end.
710 If the ColorAnimation is defined within a \l Transition or \l Behavior,
711 this value defaults to the value defined in the end state of the
712 \l Transition, or the value of the property change that triggered the
715 \sa {QML Animation and Transitions}
717 QColor QDeclarativeColorAnimation::to() const
719 Q_D(const QDeclarativePropertyAnimation);
720 return d->to.value<QColor>();
723 void QDeclarativeColorAnimation::setTo(const QColor &t)
725 QDeclarativePropertyAnimation::setTo(t);
731 \qmlclass ScriptAction QDeclarativeScriptAction
732 \ingroup qml-animation-transition
735 \brief The ScriptAction element allows scripts to be run during an animation.
737 ScriptAction can be used to run a script at a specific point in an animation.
740 SequentialAnimation {
744 ScriptAction { script: doSomething(); }
751 When used as part of a Transition, you can also target a specific
752 StateChangeScript to run using the \c scriptName property.
754 \snippet doc/src/snippets/declarative/states/statechangescript.qml state and transition
756 \sa StateChangeScript
758 QDeclarativeScriptAction::QDeclarativeScriptAction(QObject *parent)
759 :QDeclarativeAbstractAnimation(*(new QDeclarativeScriptActionPrivate), parent)
761 Q_D(QDeclarativeScriptAction);
765 QDeclarativeScriptAction::~QDeclarativeScriptAction()
769 void QDeclarativeScriptActionPrivate::init()
771 Q_Q(QDeclarativeScriptAction);
772 rsa = new QActionAnimation(&proxy);
773 QDeclarative_setParent_noEvent(rsa, q);
777 \qmlproperty script ScriptAction::script
778 This property holds the script to run.
780 QDeclarativeScriptString QDeclarativeScriptAction::script() const
782 Q_D(const QDeclarativeScriptAction);
786 void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script)
788 Q_D(QDeclarativeScriptAction);
793 \qmlproperty string ScriptAction::scriptName
794 This property holds the the name of the StateChangeScript to run.
796 This property is only valid when ScriptAction is used as part of a transition.
797 If both script and scriptName are set, scriptName will be used.
799 \note When using scriptName in a reversible transition, the script will only
800 be run when the transition is being run forwards.
802 QString QDeclarativeScriptAction::stateChangeScriptName() const
804 Q_D(const QDeclarativeScriptAction);
808 void QDeclarativeScriptAction::setStateChangeScriptName(const QString &name)
810 Q_D(QDeclarativeScriptAction);
814 void QDeclarativeScriptActionPrivate::execute()
816 Q_Q(QDeclarativeScriptAction);
817 if (hasRunScriptScript && reversing)
820 QDeclarativeScriptString scriptStr = hasRunScriptScript ? runScriptScript : script;
822 const QString &str = scriptStr.script();
823 if (!str.isEmpty()) {
824 QDeclarativeExpression expr(scriptStr.context(), scriptStr.scopeObject(), str);
825 QDeclarativeData *ddata = QDeclarativeData::get(q);
826 if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
827 expr.setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
830 qmlInfo(q) << expr.error();
834 void QDeclarativeScriptAction::transition(QDeclarativeStateActions &actions,
835 QDeclarativeProperties &modified,
836 TransitionDirection direction)
838 Q_D(QDeclarativeScriptAction);
841 d->hasRunScriptScript = false;
842 d->reversing = (direction == Backward);
843 for (int ii = 0; ii < actions.count(); ++ii) {
844 QDeclarativeAction &action = actions[ii];
846 if (action.event && action.event->typeName() == QLatin1String("StateChangeScript")
847 && static_cast<QDeclarativeStateChangeScript*>(action.event)->name() == d->name) {
848 d->runScriptScript = static_cast<QDeclarativeStateChangeScript*>(action.event)->script();
849 d->hasRunScriptScript = true;
850 action.actionDone = true;
851 break; //only match one (names should be unique)
856 QAbstractAnimation *QDeclarativeScriptAction::qtAnimation()
858 Q_D(QDeclarativeScriptAction);
865 \qmlclass PropertyAction QDeclarativePropertyAction
866 \ingroup qml-animation-transition
869 \brief The PropertyAction element allows immediate property changes during animation.
871 PropertyAction is used to specify an immediate property change during an
872 animation. The property change is not animated.
874 It is useful for setting non-animated property values during an animation.
876 For example, here is a SequentialAnimation that sets the image's
877 \l {Image::}{smooth} property to \c true, animates the width of the image,
878 then sets \l {Image::}{smooth} back to \c false:
880 \snippet doc/src/snippets/declarative/propertyaction.qml standalone
882 PropertyAction is also useful for setting the exact point at which a property
883 change should occur during a \l Transition. For example, if PropertyChanges
884 was used in a \l State to rotate an item around a particular
885 \l {Item::}{transformOrigin}, it might be implemented like this:
887 \snippet doc/src/snippets/declarative/propertyaction.qml transition
889 However, with this code, the \c transformOrigin is not set until \e after
890 the animation, as a \l State is taken to define the values at the \e end of
891 a transition. The animation would rotate at the default \c transformOrigin,
892 then jump to \c Item.BottomRight. To fix this, insert a PropertyAction
893 before the RotationAnimation begins:
895 \snippet doc/src/snippets/declarative/propertyaction-sequential.qml sequential
897 This immediately sets the \c transformOrigin property to the value defined
898 in the end state of the \l Transition (i.e. the value defined in the
899 PropertyAction object) so that the rotation animation begins with the
900 correct transform origin.
902 \sa {QML Animation and Transitions}, QtDeclarative
904 QDeclarativePropertyAction::QDeclarativePropertyAction(QObject *parent)
905 : QDeclarativeAbstractAnimation(*(new QDeclarativePropertyActionPrivate), parent)
907 Q_D(QDeclarativePropertyAction);
911 QDeclarativePropertyAction::~QDeclarativePropertyAction()
915 void QDeclarativePropertyActionPrivate::init()
917 Q_Q(QDeclarativePropertyAction);
918 spa = new QActionAnimation;
919 QDeclarative_setParent_noEvent(spa, q);
922 QObject *QDeclarativePropertyAction::target() const
924 Q_D(const QDeclarativePropertyAction);
928 void QDeclarativePropertyAction::setTarget(QObject *o)
930 Q_D(QDeclarativePropertyAction);
934 emit targetChanged();
937 QString QDeclarativePropertyAction::property() const
939 Q_D(const QDeclarativePropertyAction);
940 return d->propertyName;
943 void QDeclarativePropertyAction::setProperty(const QString &n)
945 Q_D(QDeclarativePropertyAction);
946 if (d->propertyName == n)
949 emit propertyChanged();
953 \qmlproperty Object PropertyAction::target
954 \qmlproperty list<Object> PropertyAction::targets
955 \qmlproperty string PropertyAction::property
956 \qmlproperty string PropertyAction::properties
958 These properties determine the items and their properties that are
959 affected by this action.
961 The details of how these properties are interpreted in different situations
962 is covered in the \l{PropertyAnimation::properties}{corresponding} PropertyAnimation
967 QString QDeclarativePropertyAction::properties() const
969 Q_D(const QDeclarativePropertyAction);
970 return d->properties;
973 void QDeclarativePropertyAction::setProperties(const QString &p)
975 Q_D(QDeclarativePropertyAction);
976 if (d->properties == p)
979 emit propertiesChanged(p);
982 QDeclarativeListProperty<QObject> QDeclarativePropertyAction::targets()
984 Q_D(QDeclarativePropertyAction);
985 return QDeclarativeListProperty<QObject>(this, d->targets);
989 \qmlproperty list<Object> PropertyAction::exclude
990 This property holds the objects that should not be affected by this action.
994 QDeclarativeListProperty<QObject> QDeclarativePropertyAction::exclude()
996 Q_D(QDeclarativePropertyAction);
997 return QDeclarativeListProperty<QObject>(this, d->exclude);
1001 \qmlproperty any PropertyAction::value
1002 This property holds the value to be set on the property.
1004 If the PropertyAction is defined within a \l Transition or \l Behavior,
1005 this value defaults to the value defined in the end state of the
1006 \l Transition, or the value of the property change that triggered the
1009 QVariant QDeclarativePropertyAction::value() const
1011 Q_D(const QDeclarativePropertyAction);
1015 void QDeclarativePropertyAction::setValue(const QVariant &v)
1017 Q_D(QDeclarativePropertyAction);
1018 if (d->value.isNull || d->value != v) {
1020 emit valueChanged(v);
1024 QAbstractAnimation *QDeclarativePropertyAction::qtAnimation()
1026 Q_D(QDeclarativePropertyAction);
1030 void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions,
1031 QDeclarativeProperties &modified,
1032 TransitionDirection direction)
1034 Q_D(QDeclarativePropertyAction);
1035 Q_UNUSED(direction);
1037 struct QDeclarativeSetPropertyAnimationAction : public QAbstractAnimationAction
1039 QDeclarativeStateActions actions;
1040 virtual void doAction()
1042 for (int ii = 0; ii < actions.count(); ++ii) {
1043 const QDeclarativeAction &action = actions.at(ii);
1044 QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
1049 QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
1050 for (int ii = 0; ii < props.count(); ++ii)
1051 props[ii] = props.at(ii).trimmed();
1052 if (!d->propertyName.isEmpty())
1053 props << d->propertyName;
1055 QList<QObject*> targets = d->targets;
1057 targets.append(d->target);
1059 bool hasSelectors = !props.isEmpty() || !targets.isEmpty() || !d->exclude.isEmpty();
1061 if (d->defaultProperty.isValid() && !hasSelectors) {
1062 props << d->defaultProperty.name();
1063 targets << d->defaultProperty.object();
1066 QDeclarativeSetPropertyAnimationAction *data = new QDeclarativeSetPropertyAnimationAction;
1068 bool hasExplicit = false;
1069 //an explicit animation has been specified
1070 if (d->value.isValid()) {
1071 for (int i = 0; i < props.count(); ++i) {
1072 for (int j = 0; j < targets.count(); ++j) {
1073 QDeclarativeAction myAction;
1074 myAction.property = d->createProperty(targets.at(j), props.at(i), this);
1075 if (myAction.property.isValid()) {
1076 myAction.toValue = d->value;
1077 QDeclarativePropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType());
1078 data->actions << myAction;
1080 for (int ii = 0; ii < actions.count(); ++ii) {
1081 QDeclarativeAction &action = actions[ii];
1082 if (action.property.object() == myAction.property.object() &&
1083 myAction.property.name() == action.property.name()) {
1084 modified << action.property;
1085 break; //### any chance there could be multiples?
1094 for (int ii = 0; ii < actions.count(); ++ii) {
1095 QDeclarativeAction &action = actions[ii];
1097 QObject *obj = action.property.object();
1098 QString propertyName = action.property.name();
1099 QObject *sObj = action.specifiedObject;
1100 QString sPropertyName = action.specifiedProperty;
1101 bool same = (obj == sObj);
1103 if ((targets.isEmpty() || targets.contains(obj) || (!same && targets.contains(sObj))) &&
1104 (!d->exclude.contains(obj)) && (same || (!d->exclude.contains(sObj))) &&
1105 (props.contains(propertyName) || (!same && props.contains(sPropertyName)))) {
1106 QDeclarativeAction myAction = action;
1108 if (d->value.isValid())
1109 myAction.toValue = d->value;
1110 QDeclarativePropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType());
1112 modified << action.property;
1113 data->actions << myAction;
1114 action.fromValue = myAction.toValue;
1118 if (data->actions.count()) {
1119 d->spa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped);
1126 \qmlclass NumberAnimation QDeclarativeNumberAnimation
1127 \ingroup qml-animation-transition
1129 \inherits PropertyAnimation
1130 \brief The NumberAnimation element animates changes in qreal-type values.
1132 NumberAnimation is a specialized PropertyAnimation that defines an
1133 animation to be applied when a numerical value changes.
1135 Here is a NumberAnimation applied to the \c x property of a \l Rectangle
1136 as a property value source. It animates the \c x value from its current
1137 value to a value of 50, over 1000 milliseconds:
1139 \snippet doc/src/snippets/declarative/numberanimation.qml 0
1141 Like any other animation element, a NumberAnimation can be applied in a
1142 number of ways, including transitions, behaviors and property value
1143 sources. The \l {QML Animation and Transitions} documentation shows a
1144 variety of methods for creating animations.
1146 Note that NumberAnimation may not animate smoothly if there are irregular
1147 changes in the number value that it is tracking. If this is the case, use
1148 SmoothedAnimation instead.
1150 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1152 QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QObject *parent)
1153 : QDeclarativePropertyAnimation(parent)
1158 QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent)
1159 : QDeclarativePropertyAnimation(dd, parent)
1164 QDeclarativeNumberAnimation::~QDeclarativeNumberAnimation()
1168 void QDeclarativeNumberAnimation::init()
1170 Q_D(QDeclarativePropertyAnimation);
1171 d->interpolatorType = QMetaType::QReal;
1172 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1176 \qmlproperty real NumberAnimation::from
1177 This property holds the starting value for the animation.
1179 For example, the following animation is not applied until the \c x value
1188 transition: Transition {
1189 NumberAnimation { properties: "x"; from: 100; duration: 200 }
1194 If the NumberAnimation is defined within a \l Transition or \l Behavior,
1195 this value defaults to the value defined in the starting state of the
1196 \l Transition, or the current value of the property at the moment the
1197 \l Behavior is triggered.
1199 \sa {QML Animation and Transitions}
1202 qreal QDeclarativeNumberAnimation::from() const
1204 Q_D(const QDeclarativePropertyAnimation);
1205 return d->from.toReal();
1208 void QDeclarativeNumberAnimation::setFrom(qreal f)
1210 QDeclarativePropertyAnimation::setFrom(f);
1214 \qmlproperty real NumberAnimation::to
1215 This property holds the end value for the animation.
1217 If the NumberAnimation is defined within a \l Transition or \l Behavior,
1218 this value defaults to the value defined in the end state of the
1219 \l Transition, or the value of the property change that triggered the
1222 \sa {QML Animation and Transitions}
1224 qreal QDeclarativeNumberAnimation::to() const
1226 Q_D(const QDeclarativePropertyAnimation);
1227 return d->to.toReal();
1230 void QDeclarativeNumberAnimation::setTo(qreal t)
1232 QDeclarativePropertyAnimation::setTo(t);
1238 \qmlclass Vector3dAnimation QDeclarativeVector3dAnimation
1239 \ingroup qml-animation-transition
1241 \inherits PropertyAnimation
1242 \brief The Vector3dAnimation element animates changes in QVector3d values.
1244 Vector3dAnimation is a specialized PropertyAnimation that defines an
1245 animation to be applied when a Vector3d value changes.
1247 Like any other animation element, a Vector3dAnimation can be applied in a
1248 number of ways, including transitions, behaviors and property value
1249 sources. The \l {QML Animation and Transitions} documentation shows a
1250 variety of methods for creating animations.
1252 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1254 QDeclarativeVector3dAnimation::QDeclarativeVector3dAnimation(QObject *parent)
1255 : QDeclarativePropertyAnimation(parent)
1257 Q_D(QDeclarativePropertyAnimation);
1258 d->interpolatorType = QMetaType::QVector3D;
1259 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1260 d->defaultToInterpolatorType = true;
1263 QDeclarativeVector3dAnimation::~QDeclarativeVector3dAnimation()
1268 \qmlproperty real Vector3dAnimation::from
1269 This property holds the starting value for the animation.
1271 If the Vector3dAnimation is defined within a \l Transition or \l Behavior,
1272 this value defaults to the value defined in the starting state of the
1273 \l Transition, or the current value of the property at the moment the
1274 \l Behavior is triggered.
1276 \sa {QML Animation and Transitions}
1278 QVector3D QDeclarativeVector3dAnimation::from() const
1280 Q_D(const QDeclarativePropertyAnimation);
1281 return d->from.value<QVector3D>();
1284 void QDeclarativeVector3dAnimation::setFrom(QVector3D f)
1286 QDeclarativePropertyAnimation::setFrom(f);
1290 \qmlproperty real Vector3dAnimation::to
1291 This property holds the end value for the animation.
1293 If the Vector3dAnimation is defined within a \l Transition or \l Behavior,
1294 this value defaults to the value defined in the end state of the
1295 \l Transition, or the value of the property change that triggered the
1298 \sa {QML Animation and Transitions}
1300 QVector3D QDeclarativeVector3dAnimation::to() const
1302 Q_D(const QDeclarativePropertyAnimation);
1303 return d->to.value<QVector3D>();
1306 void QDeclarativeVector3dAnimation::setTo(QVector3D t)
1308 QDeclarativePropertyAnimation::setTo(t);
1314 \qmlclass RotationAnimation QDeclarativeRotationAnimation
1315 \ingroup qml-animation-transition
1317 \inherits PropertyAnimation
1318 \brief The RotationAnimation element animates changes in rotation values.
1320 RotationAnimation is a specialized PropertyAnimation that gives control
1321 over the direction of rotation during an animation.
1323 By default, it rotates in the direction
1324 of the numerical change; a rotation from 0 to 240 will rotate 240 degrees
1325 clockwise, while a rotation from 240 to 0 will rotate 240 degrees
1326 counterclockwise. The \l direction property can be set to specify the
1327 direction in which the rotation should occur.
1329 In the following example we use RotationAnimation to animate the rotation
1330 between states via the shortest path:
1332 \snippet doc/src/snippets/declarative/rotationanimation.qml 0
1334 Notice the RotationAnimation did not need to set a \l target
1335 value. As a convenience, when used in a transition, RotationAnimation will rotate all
1336 properties named "rotation" or "angle". You can override this by providing
1337 your own properties via \l {PropertyAnimation::properties}{properties} or
1338 \l {PropertyAnimation::property}{property}.
1340 Also, note the \l Rectangle will be rotated around its default
1341 \l {Item::}{transformOrigin} (which is \c Item.Center). To use a different
1342 transform origin, set the origin in the PropertyChanges object and apply
1343 the change at the start of the animation using PropertyAction. See the
1344 PropertyAction documentation for more details.
1346 Like any other animation element, a RotationAnimation can be applied in a
1347 number of ways, including transitions, behaviors and property value
1348 sources. The \l {QML Animation and Transitions} documentation shows a
1349 variety of methods for creating animations.
1351 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1353 QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress)
1357 while(diff > 180.0){
1361 while(diff < -180.0){
1365 return QVariant(f + (newt - f) * progress);
1368 QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress)
1376 return QVariant(f + (newt - f) * progress);
1379 QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress)
1387 return QVariant(f + (newt - f) * progress);
1390 QDeclarativeRotationAnimation::QDeclarativeRotationAnimation(QObject *parent)
1391 : QDeclarativePropertyAnimation(*(new QDeclarativeRotationAnimationPrivate), parent)
1393 Q_D(QDeclarativeRotationAnimation);
1394 d->interpolatorType = QMetaType::QReal;
1395 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1396 d->defaultProperties = QLatin1String("rotation,angle");
1399 QDeclarativeRotationAnimation::~QDeclarativeRotationAnimation()
1404 \qmlproperty real RotationAnimation::from
1405 This property holds the starting value for the animation.
1407 For example, the following animation is not applied until the \c angle value
1416 transition: Transition {
1417 RotationAnimation { properties: "angle"; from: 100; duration: 2000 }
1422 If the RotationAnimation is defined within a \l Transition or \l Behavior,
1423 this value defaults to the value defined in the starting state of the
1424 \l Transition, or the current value of the property at the moment the
1425 \l Behavior is triggered.
1427 \sa {QML Animation and Transitions}
1429 qreal QDeclarativeRotationAnimation::from() const
1431 Q_D(const QDeclarativeRotationAnimation);
1432 return d->from.toReal();
1435 void QDeclarativeRotationAnimation::setFrom(qreal f)
1437 QDeclarativePropertyAnimation::setFrom(f);
1441 \qmlproperty real RotationAnimation::to
1442 This property holds the end value for the animation..
1444 If the RotationAnimation is defined within a \l Transition or \l Behavior,
1445 this value defaults to the value defined in the end state of the
1446 \l Transition, or the value of the property change that triggered the
1449 \sa {QML Animation and Transitions}
1451 qreal QDeclarativeRotationAnimation::to() const
1453 Q_D(const QDeclarativeRotationAnimation);
1454 return d->to.toReal();
1457 void QDeclarativeRotationAnimation::setTo(qreal t)
1459 QDeclarativePropertyAnimation::setTo(t);
1463 \qmlproperty enumeration RotationAnimation::direction
1464 This property holds the direction of the rotation.
1466 Possible values are:
1469 \o RotationAnimation.Numerical (default) - Rotate by linearly interpolating between the two numbers.
1470 A rotation from 10 to 350 will rotate 340 degrees clockwise.
1471 \o RotationAnimation.Clockwise - Rotate clockwise between the two values
1472 \o RotationAnimation.Counterclockwise - Rotate counterclockwise between the two values
1473 \o RotationAnimation.Shortest - Rotate in the direction that produces the shortest animation path.
1474 A rotation from 10 to 350 will rotate 20 degrees counterclockwise.
1477 QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const
1479 Q_D(const QDeclarativeRotationAnimation);
1480 return d->direction;
1483 void QDeclarativeRotationAnimation::setDirection(QDeclarativeRotationAnimation::RotationDirection direction)
1485 Q_D(QDeclarativeRotationAnimation);
1486 if (d->direction == direction)
1489 d->direction = direction;
1490 switch(d->direction) {
1492 d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateClockwiseRotation);
1494 case Counterclockwise:
1495 d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateCounterclockwiseRotation);
1498 d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateShortestRotation);
1501 d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1505 emit directionChanged();
1510 QDeclarativeAnimationGroup::QDeclarativeAnimationGroup(QObject *parent)
1511 : QDeclarativeAbstractAnimation(*(new QDeclarativeAnimationGroupPrivate), parent)
1515 QDeclarativeAnimationGroup::QDeclarativeAnimationGroup(QDeclarativeAnimationGroupPrivate &dd, QObject *parent)
1516 : QDeclarativeAbstractAnimation(dd, parent)
1520 void QDeclarativeAnimationGroupPrivate::append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a)
1522 QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object);
1525 // This is an optimization for the parenting that already occurs via addAnimation
1526 QDeclarative_setParent_noEvent(a->qtAnimation(), q->d_func()->ag);
1527 q->d_func()->ag->addAnimation(a->qtAnimation());
1531 void QDeclarativeAnimationGroupPrivate::clear_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list)
1533 QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object);
1535 while (q->d_func()->animations.count()) {
1536 QDeclarativeAbstractAnimation *firstAnim = q->d_func()->animations.at(0);
1537 QDeclarative_setParent_noEvent(firstAnim->qtAnimation(), 0);
1538 q->d_func()->ag->removeAnimation(firstAnim->qtAnimation());
1539 firstAnim->setGroup(0);
1544 QDeclarativeAnimationGroup::~QDeclarativeAnimationGroup()
1548 QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeAnimationGroup::animations()
1550 Q_D(QDeclarativeAnimationGroup);
1551 QDeclarativeListProperty<QDeclarativeAbstractAnimation> list(this, d->animations);
1552 list.append = &QDeclarativeAnimationGroupPrivate::append_animation;
1553 list.clear = &QDeclarativeAnimationGroupPrivate::clear_animation;
1558 \qmlclass SequentialAnimation QDeclarativeSequentialAnimation
1559 \ingroup qml-animation-transition
1562 \brief The SequentialAnimation element allows animations to be run sequentially.
1564 The SequentialAnimation and ParallelAnimation elements allow multiple
1565 animations to be run together. Animations defined in a SequentialAnimation
1566 are run one after the other, while animations defined in a ParallelAnimation
1567 are run at the same time.
1569 The following example runs two number animations in a sequence. The \l Rectangle
1570 animates to a \c x position of 50, then to a \c y position of 50.
1572 \snippet doc/src/snippets/declarative/sequentialanimation.qml 0
1574 Animations defined within a \l Transition are automatically run in parallel,
1575 so SequentialAnimation can be used to enclose the animations in a \l Transition
1576 if this is the preferred behavior.
1578 Like any other animation element, a SequentialAnimation can be applied in a
1579 number of ways, including transitions, behaviors and property value
1580 sources. The \l {QML Animation and Transitions} documentation shows a
1581 variety of methods for creating animations.
1583 \note Once an animation has been grouped into a SequentialAnimation or
1584 ParallelAnimation, it cannot be individually started and stopped; the
1585 SequentialAnimation or ParallelAnimation must be started and stopped as a group.
1587 \sa ParallelAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1590 QDeclarativeSequentialAnimation::QDeclarativeSequentialAnimation(QObject *parent) :
1591 QDeclarativeAnimationGroup(parent)
1593 Q_D(QDeclarativeAnimationGroup);
1594 d->ag = new QSequentialAnimationGroup;
1595 QDeclarative_setParent_noEvent(d->ag, this);
1598 QDeclarativeSequentialAnimation::~QDeclarativeSequentialAnimation()
1602 QAbstractAnimation *QDeclarativeSequentialAnimation::qtAnimation()
1604 Q_D(QDeclarativeAnimationGroup);
1608 void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actions,
1609 QDeclarativeProperties &modified,
1610 TransitionDirection direction)
1612 Q_D(QDeclarativeAnimationGroup);
1616 if (direction == Backward) {
1618 from = d->animations.count() - 1;
1621 bool valid = d->defaultProperty.isValid();
1622 for (int ii = from; ii < d->animations.count() && ii >= 0; ii += inc) {
1624 d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
1625 d->animations.at(ii)->transition(actions, modified, direction);
1632 \qmlclass ParallelAnimation QDeclarativeParallelAnimation
1633 \ingroup qml-animation-transition
1636 \brief The ParallelAnimation element allows animations to be run in parallel.
1638 The SequentialAnimation and ParallelAnimation elements allow multiple
1639 animations to be run together. Animations defined in a SequentialAnimation
1640 are run one after the other, while animations defined in a ParallelAnimation
1641 are run at the same time.
1643 The following animation runs two number animations in parallel. The \l Rectangle
1644 moves to (50,50) by animating its \c x and \c y properties at the same time.
1646 \snippet doc/src/snippets/declarative/parallelanimation.qml 0
1648 Like any other animation element, a ParallelAnimation can be applied in a
1649 number of ways, including transitions, behaviors and property value
1650 sources. The \l {QML Animation and Transitions} documentation shows a
1651 variety of methods for creating animations.
1653 \note Once an animation has been grouped into a SequentialAnimation or
1654 ParallelAnimation, it cannot be individually started and stopped; the
1655 SequentialAnimation or ParallelAnimation must be started and stopped as a group.
1657 \sa SequentialAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1659 QDeclarativeParallelAnimation::QDeclarativeParallelAnimation(QObject *parent) :
1660 QDeclarativeAnimationGroup(parent)
1662 Q_D(QDeclarativeAnimationGroup);
1663 d->ag = new QParallelAnimationGroup;
1664 QDeclarative_setParent_noEvent(d->ag, this);
1667 QDeclarativeParallelAnimation::~QDeclarativeParallelAnimation()
1671 QAbstractAnimation *QDeclarativeParallelAnimation::qtAnimation()
1673 Q_D(QDeclarativeAnimationGroup);
1677 void QDeclarativeParallelAnimation::transition(QDeclarativeStateActions &actions,
1678 QDeclarativeProperties &modified,
1679 TransitionDirection direction)
1681 Q_D(QDeclarativeAnimationGroup);
1682 bool valid = d->defaultProperty.isValid();
1683 for (int ii = 0; ii < d->animations.count(); ++ii) {
1685 d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
1686 d->animations.at(ii)->transition(actions, modified, direction);
1692 //convert a variant from string type to another animatable type
1693 void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
1695 if (variant.userType() != QVariant::String) {
1696 variant.convert((QVariant::Type)type);
1701 case QVariant::Rect: {
1702 variant.setValue(QDeclarativeStringConverters::rectFFromString(variant.toString()).toRect());
1705 case QVariant::RectF: {
1706 variant.setValue(QDeclarativeStringConverters::rectFFromString(variant.toString()));
1709 case QVariant::Point: {
1710 variant.setValue(QDeclarativeStringConverters::pointFFromString(variant.toString()).toPoint());
1713 case QVariant::PointF: {
1714 variant.setValue(QDeclarativeStringConverters::pointFFromString(variant.toString()));
1717 case QVariant::Size: {
1718 variant.setValue(QDeclarativeStringConverters::sizeFFromString(variant.toString()).toSize());
1721 case QVariant::SizeF: {
1722 variant.setValue(QDeclarativeStringConverters::sizeFFromString(variant.toString()));
1725 case QVariant::Color: {
1726 variant.setValue(QDeclarativeStringConverters::colorFromString(variant.toString()));
1729 case QVariant::Vector3D: {
1730 variant.setValue(QDeclarativeStringConverters::vector3DFromString(variant.toString()));
1734 if (QDeclarativeValueTypeFactory::isValueType((uint)type)) {
1735 variant.convert((QVariant::Type)type);
1737 QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
1739 variant = converter(variant.toString());
1746 \qmlclass PropertyAnimation QDeclarativePropertyAnimation
1747 \ingroup qml-animation-transition
1750 \brief The PropertyAnimation element animates changes in property values.
1752 PropertyAnimation provides a way to animate changes to a property's value.
1754 It can be used to define animations in a number of ways:
1757 \o In a \l Transition
1759 For example, to animate any objects that have changed their \c x or \c y properties
1760 as a result of a state change, using an \c InOutQuad easing curve:
1762 \snippet doc/src/snippets/declarative/propertyanimation.qml transition
1767 For example, to animate all changes to a rectangle's \c x property:
1769 \snippet doc/src/snippets/declarative/propertyanimation.qml behavior
1772 \o As a property value source
1774 For example, to repeatedly animate the rectangle's \c x property:
1776 \snippet doc/src/snippets/declarative/propertyanimation.qml propertyvaluesource
1779 \o In a signal handler
1781 For example, to fade out \c theObject when clicked:
1784 anchors.fill: theObject
1785 onClicked: PropertyAnimation { target: theObject; property: "opacity"; to: 0 }
1791 For example, to animate \c rect's \c width property over 500ms, from its current width to 30:
1793 \snippet doc/src/snippets/declarative/propertyanimation.qml standalone
1797 Depending on how the animation is used, the set of properties normally used will be
1798 different. For more information see the individual property documentation, as well
1799 as the \l{QML Animation and Transitions} introduction.
1801 Note that PropertyAnimation inherits the abstract \l Animation element.
1802 This includes additional properties and methods for controlling the animation.
1804 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1807 QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QObject *parent)
1808 : QDeclarativeAbstractAnimation(*(new QDeclarativePropertyAnimationPrivate), parent)
1810 Q_D(QDeclarativePropertyAnimation);
1814 QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent)
1815 : QDeclarativeAbstractAnimation(dd, parent)
1817 Q_D(QDeclarativePropertyAnimation);
1821 QDeclarativePropertyAnimation::~QDeclarativePropertyAnimation()
1825 void QDeclarativePropertyAnimationPrivate::init()
1827 Q_Q(QDeclarativePropertyAnimation);
1828 va = new QDeclarativeBulkValueAnimator;
1829 QDeclarative_setParent_noEvent(va, q);
1833 \qmlproperty int PropertyAnimation::duration
1834 This property holds the duration of the animation, in milliseconds.
1836 The default value is 250.
1838 int QDeclarativePropertyAnimation::duration() const
1840 Q_D(const QDeclarativePropertyAnimation);
1841 return d->va->duration();
1844 void QDeclarativePropertyAnimation::setDuration(int duration)
1847 qmlInfo(this) << tr("Cannot set a duration of < 0");
1851 Q_D(QDeclarativePropertyAnimation);
1852 if (d->va->duration() == duration)
1854 d->va->setDuration(duration);
1855 emit durationChanged(duration);
1859 \qmlproperty real PropertyAnimation::from
1860 This property holds the starting value for the animation.
1862 If the PropertyAnimation is defined within a \l Transition or \l Behavior,
1863 this value defaults to the value defined in the starting state of the
1864 \l Transition, or the current value of the property at the moment the
1865 \l Behavior is triggered.
1867 \sa {QML Animation and Transitions}
1869 QVariant QDeclarativePropertyAnimation::from() const
1871 Q_D(const QDeclarativePropertyAnimation);
1875 void QDeclarativePropertyAnimation::setFrom(const QVariant &f)
1877 Q_D(QDeclarativePropertyAnimation);
1878 if (d->fromIsDefined && f == d->from)
1881 d->fromIsDefined = f.isValid();
1882 emit fromChanged(f);
1886 \qmlproperty real PropertyAnimation::to
1887 This property holds the end value for the animation.
1889 If the PropertyAnimation is defined within a \l Transition or \l Behavior,
1890 this value defaults to the value defined in the end state of the
1891 \l Transition, or the value of the property change that triggered the
1894 \sa {QML Animation and Transitions}
1896 QVariant QDeclarativePropertyAnimation::to() const
1898 Q_D(const QDeclarativePropertyAnimation);
1902 void QDeclarativePropertyAnimation::setTo(const QVariant &t)
1904 Q_D(QDeclarativePropertyAnimation);
1905 if (d->toIsDefined && t == d->to)
1908 d->toIsDefined = t.isValid();
1913 \qmlproperty enumeration PropertyAnimation::easing.type
1914 \qmlproperty real PropertyAnimation::easing.amplitude
1915 \qmlproperty real PropertyAnimation::easing.overshoot
1916 \qmlproperty real PropertyAnimation::easing.period
1917 \brief the easing curve used for the animation.
1919 To specify an easing curve you need to specify at least the type. For some curves you can also specify
1920 amplitude, period and/or overshoot (more details provided after the table). The default easing curve is
1924 PropertyAnimation { properties: "y"; easing.type: Easing.InOutElastic; easing.amplitude: 2.0; easing.period: 1.5 }
1927 Available types are:
1932 \o Easing curve for a linear (t) function: velocity is constant.
1933 \o \inlineimage qeasingcurve-linear.png
1936 \o Easing curve for a quadratic (t^2) function: accelerating from zero velocity.
1937 \o \inlineimage qeasingcurve-inquad.png
1939 \o \c Easing.OutQuad
1940 \o Easing curve for a quadratic (t^2) function: decelerating to zero velocity.
1941 \o \inlineimage qeasingcurve-outquad.png
1943 \o \c Easing.InOutQuad
1944 \o Easing curve for a quadratic (t^2) function: acceleration until halfway, then deceleration.
1945 \o \inlineimage qeasingcurve-inoutquad.png
1947 \o \c Easing.OutInQuad
1948 \o Easing curve for a quadratic (t^2) function: deceleration until halfway, then acceleration.
1949 \o \inlineimage qeasingcurve-outinquad.png
1951 \o \c Easing.InCubic
1952 \o Easing curve for a cubic (t^3) function: accelerating from zero velocity.
1953 \o \inlineimage qeasingcurve-incubic.png
1955 \o \c Easing.OutCubic
1956 \o Easing curve for a cubic (t^3) function: decelerating from zero velocity.
1957 \o \inlineimage qeasingcurve-outcubic.png
1959 \o \c Easing.InOutCubic
1960 \o Easing curve for a cubic (t^3) function: acceleration until halfway, then deceleration.
1961 \o \inlineimage qeasingcurve-inoutcubic.png
1963 \o \c Easing.OutInCubic
1964 \o Easing curve for a cubic (t^3) function: deceleration until halfway, then acceleration.
1965 \o \inlineimage qeasingcurve-outincubic.png
1967 \o \c Easing.InQuart
1968 \o Easing curve for a quartic (t^4) function: accelerating from zero velocity.
1969 \o \inlineimage qeasingcurve-inquart.png
1971 \o \c Easing.OutQuart
1972 \o Easing curve for a quartic (t^4) function: decelerating from zero velocity.
1973 \o \inlineimage qeasingcurve-outquart.png
1975 \o \c Easing.InOutQuart
1976 \o Easing curve for a quartic (t^4) function: acceleration until halfway, then deceleration.
1977 \o \inlineimage qeasingcurve-inoutquart.png
1979 \o \c Easing.OutInQuart
1980 \o Easing curve for a quartic (t^4) function: deceleration until halfway, then acceleration.
1981 \o \inlineimage qeasingcurve-outinquart.png
1983 \o \c Easing.InQuint
1984 \o Easing curve for a quintic (t^5) function: accelerating from zero velocity.
1985 \o \inlineimage qeasingcurve-inquint.png
1987 \o \c Easing.OutQuint
1988 \o Easing curve for a quintic (t^5) function: decelerating from zero velocity.
1989 \o \inlineimage qeasingcurve-outquint.png
1991 \o \c Easing.InOutQuint
1992 \o Easing curve for a quintic (t^5) function: acceleration until halfway, then deceleration.
1993 \o \inlineimage qeasingcurve-inoutquint.png
1995 \o \c Easing.OutInQuint
1996 \o Easing curve for a quintic (t^5) function: deceleration until halfway, then acceleration.
1997 \o \inlineimage qeasingcurve-outinquint.png
2000 \o Easing curve for a sinusoidal (sin(t)) function: accelerating from zero velocity.
2001 \o \inlineimage qeasingcurve-insine.png
2003 \o \c Easing.OutSine
2004 \o Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity.
2005 \o \inlineimage qeasingcurve-outsine.png
2007 \o \c Easing.InOutSine
2008 \o Easing curve for a sinusoidal (sin(t)) function: acceleration until halfway, then deceleration.
2009 \o \inlineimage qeasingcurve-inoutsine.png
2011 \o \c Easing.OutInSine
2012 \o Easing curve for a sinusoidal (sin(t)) function: deceleration until halfway, then acceleration.
2013 \o \inlineimage qeasingcurve-outinsine.png
2016 \o Easing curve for an exponential (2^t) function: accelerating from zero velocity.
2017 \o \inlineimage qeasingcurve-inexpo.png
2019 \o \c Easing.OutExpo
2020 \o Easing curve for an exponential (2^t) function: decelerating from zero velocity.
2021 \o \inlineimage qeasingcurve-outexpo.png
2023 \o \c Easing.InOutExpo
2024 \o Easing curve for an exponential (2^t) function: acceleration until halfway, then deceleration.
2025 \o \inlineimage qeasingcurve-inoutexpo.png
2027 \o \c Easing.OutInExpo
2028 \o Easing curve for an exponential (2^t) function: deceleration until halfway, then acceleration.
2029 \o \inlineimage qeasingcurve-outinexpo.png
2032 \o Easing curve for a circular (sqrt(1-t^2)) function: accelerating from zero velocity.
2033 \o \inlineimage qeasingcurve-incirc.png
2035 \o \c Easing.OutCirc
2036 \o Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity.
2037 \o \inlineimage qeasingcurve-outcirc.png
2039 \o \c Easing.InOutCirc
2040 \o Easing curve for a circular (sqrt(1-t^2)) function: acceleration until halfway, then deceleration.
2041 \o \inlineimage qeasingcurve-inoutcirc.png
2043 \o \c Easing.OutInCirc
2044 \o Easing curve for a circular (sqrt(1-t^2)) function: deceleration until halfway, then acceleration.
2045 \o \inlineimage qeasingcurve-outincirc.png
2047 \o \c Easing.InElastic
2048 \o Easing curve for an elastic (exponentially decaying sine wave) function: accelerating from zero velocity.
2049 \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter.
2050 \o \inlineimage qeasingcurve-inelastic.png
2052 \o \c Easing.OutElastic
2053 \o Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity.
2054 \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter.
2055 \o \inlineimage qeasingcurve-outelastic.png
2057 \o \c Easing.InOutElastic
2058 \o Easing curve for an elastic (exponentially decaying sine wave) function: acceleration until halfway, then deceleration.
2059 \o \inlineimage qeasingcurve-inoutelastic.png
2061 \o \c Easing.OutInElastic
2062 \o Easing curve for an elastic (exponentially decaying sine wave) function: deceleration until halfway, then acceleration.
2063 \o \inlineimage qeasingcurve-outinelastic.png
2066 \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity.
2067 \o \inlineimage qeasingcurve-inback.png
2069 \o \c Easing.OutBack
2070 \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity.
2071 \o \inlineimage qeasingcurve-outback.png
2073 \o \c Easing.InOutBack
2074 \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration.
2075 \o \inlineimage qeasingcurve-inoutback.png
2077 \o \c Easing.OutInBack
2078 \o Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration.
2079 \o \inlineimage qeasingcurve-outinback.png
2081 \o \c Easing.InBounce
2082 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: accelerating from zero velocity.
2083 \o \inlineimage qeasingcurve-inbounce.png
2085 \o \c Easing.OutBounce
2086 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity.
2087 \o \inlineimage qeasingcurve-outbounce.png
2089 \o \c Easing.InOutBounce
2090 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration.
2091 \o \inlineimage qeasingcurve-inoutbounce.png
2093 \o \c Easing.OutInBounce
2094 \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration.
2095 \o \inlineimage qeasingcurve-outinbounce.png
2098 \c easing.amplitude is only applicable for bounce and elastic curves (curves of type
2099 \c Easing.InBounce, \c Easing.OutBounce, \c Easing.InOutBounce, \c Easing.OutInBounce, \c Easing.InElastic,
2100 \c Easing.OutElastic, \c Easing.InOutElastic or \c Easing.OutInElastic).
2102 \c easing.overshoot is only applicable if \c easing.type is: \c Easing.InBack, \c Easing.OutBack,
2103 \c Easing.InOutBack or \c Easing.OutInBack.
2105 \c easing.period is only applicable if easing.type is: \c Easing.InElastic, \c Easing.OutElastic,
2106 \c Easing.InOutElastic or \c Easing.OutInElastic.
2108 See the \l {declarative/animation/easing}{easing} example for a demonstration of
2109 the different easing settings.
2111 QEasingCurve QDeclarativePropertyAnimation::easing() const
2113 Q_D(const QDeclarativePropertyAnimation);
2114 return d->va->easingCurve();
2117 void QDeclarativePropertyAnimation::setEasing(const QEasingCurve &e)
2119 Q_D(QDeclarativePropertyAnimation);
2120 if (d->va->easingCurve() == e)
2123 d->va->setEasingCurve(e);
2124 emit easingChanged(e);
2127 QObject *QDeclarativePropertyAnimation::target() const
2129 Q_D(const QDeclarativePropertyAnimation);
2133 void QDeclarativePropertyAnimation::setTarget(QObject *o)
2135 Q_D(QDeclarativePropertyAnimation);
2139 emit targetChanged();
2142 QString QDeclarativePropertyAnimation::property() const
2144 Q_D(const QDeclarativePropertyAnimation);
2145 return d->propertyName;
2148 void QDeclarativePropertyAnimation::setProperty(const QString &n)
2150 Q_D(QDeclarativePropertyAnimation);
2151 if (d->propertyName == n)
2153 d->propertyName = n;
2154 emit propertyChanged();
2157 QString QDeclarativePropertyAnimation::properties() const
2159 Q_D(const QDeclarativePropertyAnimation);
2160 return d->properties;
2163 void QDeclarativePropertyAnimation::setProperties(const QString &prop)
2165 Q_D(QDeclarativePropertyAnimation);
2166 if (d->properties == prop)
2169 d->properties = prop;
2170 emit propertiesChanged(prop);
2174 \qmlproperty string PropertyAnimation::properties
2175 \qmlproperty list<Object> PropertyAnimation::targets
2176 \qmlproperty string PropertyAnimation::property
2177 \qmlproperty Object PropertyAnimation::target
2179 These properties are used as a set to determine which properties should be animated.
2180 The singular and plural forms are functionally identical, e.g.
2182 NumberAnimation { target: theItem; property: "x"; to: 500 }
2184 has the same meaning as
2186 NumberAnimation { targets: theItem; properties: "x"; to: 500 }
2188 The singular forms are slightly optimized, so if you do have only a single target/property
2189 to animate you should try to use them.
2191 The \c targets property allows multiple targets to be set. For example, this animates the
2192 \c x property of both \c itemA and \c itemB:
2195 NumberAnimation { targets: [itemA, itemB]; properties: "x"; to: 500 }
2198 In many cases these properties do not need to be explicitly specified, as they can be
2199 inferred from the animation framework:
2203 \o Value Source / Behavior
2204 \o When an animation is used as a value source or in a Behavior, the default target and property
2205 name to be animated can both be inferred.
2209 width: 100; height: 100
2210 color: Qt.rgba(0,0,1)
2211 NumberAnimation on x { to: 500; loops: Animation.Infinite } //animate theRect's x property
2212 Behavior on y { NumberAnimation {} } //animate theRect's y property
2217 \o When used in a transition, a property animation is assumed to match \e all targets
2218 but \e no properties. In practice, that means you need to specify at least the properties
2219 in order for the animation to do anything.
2223 width: 100; height: 100
2224 color: Qt.rgba(0,0,1)
2225 Item { id: uselessItem }
2228 PropertyChanges { target: theRect; x: 200; y: 200; z: 4 }
2229 PropertyChanges { target: uselessItem; x: 10; y: 10; z: 2 }
2231 transitions: Transition {
2232 //animate both theRect's and uselessItem's x and y to their final values
2233 NumberAnimation { properties: "x,y" }
2235 //animate theRect's z to its final value
2236 NumberAnimation { target: theRect; property: "z" }
2242 \o When an animation is used standalone, both the target and property need to be
2243 explicitly specified.
2247 width: 100; height: 100
2248 color: Qt.rgba(0,0,1)
2249 //need to explicitly specify target and property
2250 NumberAnimation { id: theAnim; target: theRect; property: "x"; to: 500 }
2252 anchors.fill: parent
2253 onClicked: theAnim.start()
2259 As seen in the above example, properties is specified as a comma-separated string of property names to animate.
2261 \sa exclude, {QML Animation and Transitions}
2263 QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::targets()
2265 Q_D(QDeclarativePropertyAnimation);
2266 return QDeclarativeListProperty<QObject>(this, d->targets);
2270 \qmlproperty list<Object> PropertyAnimation::exclude
2271 This property holds the items not to be affected by this animation.
2272 \sa PropertyAnimation::targets
2274 QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::exclude()
2276 Q_D(QDeclarativePropertyAnimation);
2277 return QDeclarativeListProperty<QObject>(this, d->exclude);
2280 QAbstractAnimation *QDeclarativePropertyAnimation::qtAnimation()
2282 Q_D(QDeclarativePropertyAnimation);
2286 void QDeclarativeAnimationPropertyUpdater::setValue(qreal v)
2288 bool deleted = false;
2289 wasDeleted = &deleted;
2290 if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1
2292 for (int ii = 0; ii < actions.count(); ++ii) {
2293 QDeclarativeAction &action = actions[ii];
2296 QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
2298 if (!fromSourced && !fromDefined) {
2299 action.fromValue = action.property.read();
2300 if (interpolatorType)
2301 QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType);
2303 if (!interpolatorType) {
2304 int propType = action.property.propertyType();
2305 if (!prevInterpolatorType || prevInterpolatorType != propType) {
2306 prevInterpolatorType = propType;
2307 interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType);
2311 QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
2320 void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions,
2321 QDeclarativeProperties &modified,
2322 TransitionDirection direction)
2324 Q_D(QDeclarativePropertyAnimation);
2326 QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
2327 for (int ii = 0; ii < props.count(); ++ii)
2328 props[ii] = props.at(ii).trimmed();
2329 if (!d->propertyName.isEmpty())
2330 props << d->propertyName;
2332 QList<QObject*> targets = d->targets;
2334 targets.append(d->target);
2336 bool hasSelectors = !props.isEmpty() || !targets.isEmpty() || !d->exclude.isEmpty();
2337 bool useType = (props.isEmpty() && d->defaultToInterpolatorType) ? true : false;
2339 if (d->defaultProperty.isValid() && !hasSelectors) {
2340 props << d->defaultProperty.name();
2341 targets << d->defaultProperty.object();
2344 if (props.isEmpty() && !d->defaultProperties.isEmpty()) {
2345 props << d->defaultProperties.split(QLatin1Char(','));
2348 QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater;
2349 data->interpolatorType = d->interpolatorType;
2350 data->interpolator = d->interpolator;
2351 data->reverse = direction == Backward ? true : false;
2352 data->fromSourced = false;
2353 data->fromDefined = d->fromIsDefined;
2355 bool hasExplicit = false;
2356 //an explicit animation has been specified
2357 if (d->toIsDefined) {
2358 for (int i = 0; i < props.count(); ++i) {
2359 for (int j = 0; j < targets.count(); ++j) {
2360 QDeclarativeAction myAction;
2361 myAction.property = d->createProperty(targets.at(j), props.at(i), this);
2362 if (myAction.property.isValid()) {
2363 if (d->fromIsDefined) {
2364 myAction.fromValue = d->from;
2365 d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2367 myAction.toValue = d->to;
2368 d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2369 data->actions << myAction;
2371 for (int ii = 0; ii < actions.count(); ++ii) {
2372 QDeclarativeAction &action = actions[ii];
2373 if (action.property.object() == myAction.property.object() &&
2374 myAction.property.name() == action.property.name()) {
2375 modified << action.property;
2376 break; //### any chance there could be multiples?
2385 for (int ii = 0; ii < actions.count(); ++ii) {
2386 QDeclarativeAction &action = actions[ii];
2388 QObject *obj = action.property.object();
2389 QString propertyName = action.property.name();
2390 QObject *sObj = action.specifiedObject;
2391 QString sPropertyName = action.specifiedProperty;
2392 bool same = (obj == sObj);
2394 if ((targets.isEmpty() || targets.contains(obj) || (!same && targets.contains(sObj))) &&
2395 (!d->exclude.contains(obj)) && (same || (!d->exclude.contains(sObj))) &&
2396 (props.contains(propertyName) || (!same && props.contains(sPropertyName))
2397 || (useType && action.property.propertyType() == d->interpolatorType))) {
2398 QDeclarativeAction myAction = action;
2400 if (d->fromIsDefined)
2401 myAction.fromValue = d->from;
2403 myAction.fromValue = QVariant();
2405 myAction.toValue = d->to;
2407 d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2408 d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2410 modified << action.property;
2412 data->actions << myAction;
2413 action.fromValue = myAction.toValue;
2417 if (data->actions.count()) {
2418 if (!d->rangeIsSet) {
2419 d->va->setStartValue(qreal(0));
2420 d->va->setEndValue(qreal(1));
2421 d->rangeIsSet = true;
2423 d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
2424 d->va->setFromSourcedValue(&data->fromSourced);
2425 d->actions = &data->actions;
2428 d->va->setFromSourcedValue(0); //clear previous data
2429 d->va->setAnimValue(0, QAbstractAnimation::DeleteWhenStopped); //clear previous data
2435 \qmlclass ParentAnimation QDeclarativeParentAnimation
2436 \ingroup qml-animation-transition
2439 \brief The ParentAnimation element animates changes in parent values.
2441 ParentAnimation is used to animate a parent change for an \l Item.
2443 For example, the following ParentChange changes \c blueRect to become
2444 a child of \c redRect when it is clicked. The inclusion of the
2445 ParentAnimation, which defines a NumberAnimation to be applied during
2446 the transition, ensures the item animates smoothly as it moves to
2449 \snippet doc/src/snippets/declarative/parentanimation.qml 0
2451 A ParentAnimation can contain any number of animations. These animations will
2452 be run in parallel; to run them sequentially, define them within a
2453 SequentialAnimation.
2455 In some cases, such as when reparenting between items with clipping enabled, it is useful
2456 to animate the parent change via another item that does not have clipping
2457 enabled. Such an item can be set using the \l via property.
2459 For convenience, when a ParentAnimation is used in a \l Transition, it will
2460 animate any ParentChange that has occurred during the state change.
2461 This can be overridden by setting a specific target item using the
2464 Like any other animation element, a ParentAnimation can be applied in a
2465 number of ways, including transitions, behaviors and property value
2466 sources. The \l {QML Animation and Transitions} documentation shows a
2467 variety of methods for creating animations.
2469 \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
2471 QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent)
2472 : QDeclarativeAnimationGroup(*(new QDeclarativeParentAnimationPrivate), parent)
2474 Q_D(QDeclarativeParentAnimation);
2475 d->topLevelGroup = new QSequentialAnimationGroup;
2476 QDeclarative_setParent_noEvent(d->topLevelGroup, this);
2478 d->startAction = new QActionAnimation;
2479 QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup);
2480 d->topLevelGroup->addAnimation(d->startAction);
2482 d->ag = new QParallelAnimationGroup;
2483 QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup);
2484 d->topLevelGroup->addAnimation(d->ag);
2486 d->endAction = new QActionAnimation;
2487 QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup);
2488 d->topLevelGroup->addAnimation(d->endAction);
2491 QDeclarativeParentAnimation::~QDeclarativeParentAnimation()
2496 \qmlproperty Item ParentAnimation::target
2497 The item to reparent.
2499 When used in a transition, if no target is specified, all
2500 ParentChange occurrences are animated by the ParentAnimation.
2502 QDeclarativeItem *QDeclarativeParentAnimation::target() const
2504 Q_D(const QDeclarativeParentAnimation);
2508 void QDeclarativeParentAnimation::setTarget(QDeclarativeItem *target)
2510 Q_D(QDeclarativeParentAnimation);
2511 if (target == d->target)
2515 emit targetChanged();
2519 \qmlproperty Item ParentAnimation::newParent
2520 The new parent to animate to.
2522 If the ParentAnimation is defined within a \l Transition or \l Behavior,
2523 this value defaults to the value defined in the end state of the
2524 \l Transition, or the value of the property change that triggered the
2527 QDeclarativeItem *QDeclarativeParentAnimation::newParent() const
2529 Q_D(const QDeclarativeParentAnimation);
2530 return d->newParent;
2533 void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent)
2535 Q_D(QDeclarativeParentAnimation);
2536 if (newParent == d->newParent)
2539 d->newParent = newParent;
2540 emit newParentChanged();
2544 \qmlproperty Item ParentAnimation::via
2545 The item to reparent via. This provides a way to do an unclipped animation
2546 when both the old parent and new parent are clipped.
2556 QDeclarativeItem *QDeclarativeParentAnimation::via() const
2558 Q_D(const QDeclarativeParentAnimation);
2562 void QDeclarativeParentAnimation::setVia(QDeclarativeItem *via)
2564 Q_D(QDeclarativeParentAnimation);
2572 //### mirrors same-named function in QDeclarativeItem
2573 QPointF QDeclarativeParentAnimationPrivate::computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const
2577 case QDeclarativeItem::TopLeft:
2578 return QPointF(0, 0);
2579 case QDeclarativeItem::Top:
2580 return QPointF(width / 2., 0);
2581 case QDeclarativeItem::TopRight:
2582 return QPointF(width, 0);
2583 case QDeclarativeItem::Left:
2584 return QPointF(0, height / 2.);
2585 case QDeclarativeItem::Center:
2586 return QPointF(width / 2., height / 2.);
2587 case QDeclarativeItem::Right:
2588 return QPointF(width, height / 2.);
2589 case QDeclarativeItem::BottomLeft:
2590 return QPointF(0, height);
2591 case QDeclarativeItem::Bottom:
2592 return QPointF(width / 2., height);
2593 case QDeclarativeItem::BottomRight:
2594 return QPointF(width, height);
2598 void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions,
2599 QDeclarativeProperties &modified,
2600 TransitionDirection direction)
2602 Q_D(QDeclarativeParentAnimation);
2604 struct QDeclarativeParentAnimationData : public QAbstractAnimationAction
2606 QDeclarativeParentAnimationData() {}
2607 ~QDeclarativeParentAnimationData() { qDeleteAll(pc); }
2609 QDeclarativeStateActions actions;
2610 //### reverse should probably apply on a per-action basis
2612 QList<QDeclarativeParentChange *> pc;
2613 virtual void doAction()
2615 for (int ii = 0; ii < actions.count(); ++ii) {
2616 const QDeclarativeAction &action = actions.at(ii);
2618 action.event->reverse();
2620 action.event->execute();
2625 QDeclarativeParentAnimationData *data = new QDeclarativeParentAnimationData;
2626 QDeclarativeParentAnimationData *viaData = new QDeclarativeParentAnimationData;
2628 bool hasExplicit = false;
2629 if (d->target && d->newParent) {
2630 data->reverse = false;
2631 QDeclarativeAction myAction;
2632 QDeclarativeParentChange *pc = new QDeclarativeParentChange;
2633 pc->setObject(d->target);
2634 pc->setParent(d->newParent);
2635 myAction.event = pc;
2637 data->actions << myAction;
2640 viaData->reverse = false;
2641 QDeclarativeAction myVAction;
2642 QDeclarativeParentChange *vpc = new QDeclarativeParentChange;
2643 vpc->setObject(d->target);
2644 vpc->setParent(d->via);
2645 myVAction.event = vpc;
2647 viaData->actions << myVAction;
2649 //### once actions have concept of modified,
2650 // loop to match appropriate ParentChanges and mark as modified
2654 for (int i = 0; i < actions.size(); ++i) {
2655 QDeclarativeAction &action = actions[i];
2656 if (action.event && action.event->typeName() == QLatin1String("ParentChange")
2657 && (!d->target || static_cast<QDeclarativeParentChange*>(action.event)->object() == d->target)) {
2659 QDeclarativeParentChange *pc = static_cast<QDeclarativeParentChange*>(action.event);
2660 QDeclarativeAction myAction = action;
2661 data->reverse = action.reverseEvent;
2663 //### this logic differs from PropertyAnimation
2664 // (probably a result of modified vs. done)
2666 QDeclarativeParentChange *epc = new QDeclarativeParentChange;
2667 epc->setObject(static_cast<QDeclarativeParentChange*>(action.event)->object());
2668 epc->setParent(d->newParent);
2669 myAction.event = epc;
2671 data->actions << myAction;
2674 action.actionDone = true;
2675 data->actions << myAction;
2679 viaData->reverse = false;
2680 QDeclarativeAction myAction;
2681 QDeclarativeParentChange *vpc = new QDeclarativeParentChange;
2682 vpc->setObject(pc->object());
2683 vpc->setParent(d->via);
2684 myAction.event = vpc;
2686 viaData->actions << myAction;
2687 QDeclarativeAction dummyAction;
2688 QDeclarativeAction &xAction = pc->xIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
2689 QDeclarativeAction &yAction = pc->yIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
2690 QDeclarativeAction &sAction = pc->scaleIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
2691 QDeclarativeAction &rAction = pc->rotationIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
2692 QDeclarativeItem *target = pc->object();
2693 QDeclarativeItem *targetParent = action.reverseEvent ? pc->originalParent() : pc->parent();
2695 //### this mirrors the logic in QDeclarativeParentChange.
2697 const QTransform &transform = targetParent->itemTransform(d->via, &ok);
2698 if (transform.type() >= QTransform::TxShear || !ok) {
2699 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under complex transform");
2705 bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
2706 if (ok && !isRotate) {
2707 if (transform.m11() == transform.m22())
2708 scale = transform.m11();
2710 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
2713 } else if (ok && isRotate) {
2714 if (transform.m11() == transform.m22())
2715 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
2717 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
2722 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
2724 qmlInfo(this) << QDeclarativeParentAnimation::tr("Unable to preserve appearance under scale of 0");
2729 const QPointF &point = transform.map(QPointF(xAction.toValue.toReal(),yAction.toValue.toReal()));
2730 qreal x = point.x();
2731 qreal y = point.y();
2732 if (ok && target->transformOrigin() != QDeclarativeItem::TopLeft) {
2733 qreal w = target->width();
2734 qreal h = target->height();
2735 if (pc->widthIsSet() && i < actions.size() - 1)
2736 w = actions[++i].toValue.toReal();
2737 if (pc->heightIsSet() && i < actions.size() - 1)
2738 h = actions[++i].toValue.toReal();
2739 const QPointF &transformOrigin
2740 = d->computeTransformOrigin(target->transformOrigin(), w,h);
2741 qreal tempxt = transformOrigin.x();
2742 qreal tempyt = transformOrigin.y();
2744 t.translate(-tempxt, -tempyt);
2746 t.scale(scale, scale);
2747 t.translate(tempxt, tempyt);
2748 const QPointF &offset = t.map(QPointF(0,0));
2754 //qDebug() << x << y << rotation << scale;
2755 xAction.toValue = x;
2756 yAction.toValue = y;
2757 sAction.toValue = sAction.toValue.toReal() * scale;
2758 rAction.toValue = rAction.toValue.toReal() + rotation;
2764 if (data->actions.count()) {
2765 if (direction == QDeclarativeAbstractAnimation::Forward) {
2766 d->startAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
2767 d->endAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
2769 d->endAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
2770 d->startAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
2779 //take care of any child animations
2780 bool valid = d->defaultProperty.isValid();
2781 for (int ii = 0; ii < d->animations.count(); ++ii) {
2783 d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
2784 d->animations.at(ii)->transition(actions, modified, direction);
2789 QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation()
2791 Q_D(QDeclarativeParentAnimation);
2792 return d->topLevelGroup;
2796 \qmlclass AnchorAnimation QDeclarativeAnchorAnimation
2797 \ingroup qml-animation-transition
2800 \brief The AnchorAnimation element animates changes in anchor values.
2802 AnchorAnimation is used to animate an anchor change.
2804 In the following snippet we animate the addition of a right anchor to a \l Rectangle:
2806 \snippet doc/src/snippets/declarative/anchoranimation.qml 0
2808 For convenience, when an AnchorAnimation is used in a \l Transition, it will
2809 animate any AnchorChanges that have occurred during the state change.
2810 This can be overridden by setting a specific target item using the
2813 Like any other animation element, an AnchorAnimation can be applied in a
2814 number of ways, including transitions, behaviors and property value
2815 sources. The \l {QML Animation and Transitions} documentation shows a
2816 variety of methods for creating animations.
2818 \sa {QML Animation and Transitions}, AnchorChanges
2821 QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent)
2822 : QDeclarativeAbstractAnimation(*(new QDeclarativeAnchorAnimationPrivate), parent)
2824 Q_D(QDeclarativeAnchorAnimation);
2825 d->va = new QDeclarativeBulkValueAnimator;
2826 QDeclarative_setParent_noEvent(d->va, this);
2829 QDeclarativeAnchorAnimation::~QDeclarativeAnchorAnimation()
2833 QAbstractAnimation *QDeclarativeAnchorAnimation::qtAnimation()
2835 Q_D(QDeclarativeAnchorAnimation);
2840 \qmlproperty list<Item> AnchorAnimation::targets
2841 The items to reanchor.
2843 If no targets are specified all AnchorChanges will be
2844 animated by the AnchorAnimation.
2846 QDeclarativeListProperty<QDeclarativeItem> QDeclarativeAnchorAnimation::targets()
2848 Q_D(QDeclarativeAnchorAnimation);
2849 return QDeclarativeListProperty<QDeclarativeItem>(this, d->targets);
2853 \qmlproperty int AnchorAnimation::duration
2854 This property holds the duration of the animation, in milliseconds.
2856 The default value is 250.
2858 int QDeclarativeAnchorAnimation::duration() const
2860 Q_D(const QDeclarativeAnchorAnimation);
2861 return d->va->duration();
2864 void QDeclarativeAnchorAnimation::setDuration(int duration)
2867 qmlInfo(this) << tr("Cannot set a duration of < 0");
2871 Q_D(QDeclarativeAnchorAnimation);
2872 if (d->va->duration() == duration)
2874 d->va->setDuration(duration);
2875 emit durationChanged(duration);
2879 \qmlproperty enumeration AnchorAnimation::easing.type
2880 \qmlproperty real AnchorAnimation::easing.amplitude
2881 \qmlproperty real AnchorAnimation::easing.overshoot
2882 \qmlproperty real AnchorAnimation::easing.period
2883 \brief the easing curve used for the animation.
2885 To specify an easing curve you need to specify at least the type. For some curves you can also specify
2886 amplitude, period and/or overshoot. The default easing curve is
2890 AnchorAnimation { easing.type: Easing.InOutQuad }
2893 See the \l{PropertyAnimation::easing.type} documentation for information
2894 about the different types of easing curves.
2897 QEasingCurve QDeclarativeAnchorAnimation::easing() const
2899 Q_D(const QDeclarativeAnchorAnimation);
2900 return d->va->easingCurve();
2903 void QDeclarativeAnchorAnimation::setEasing(const QEasingCurve &e)
2905 Q_D(QDeclarativeAnchorAnimation);
2906 if (d->va->easingCurve() == e)
2909 d->va->setEasingCurve(e);
2910 emit easingChanged(e);
2913 void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions,
2914 QDeclarativeProperties &modified,
2915 TransitionDirection direction)
2918 Q_D(QDeclarativeAnchorAnimation);
2919 QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater;
2920 data->interpolatorType = QMetaType::QReal;
2921 data->interpolator = d->interpolator;
2923 data->reverse = direction == Backward ? true : false;
2924 data->fromSourced = false;
2925 data->fromDefined = false;
2927 for (int ii = 0; ii < actions.count(); ++ii) {
2928 QDeclarativeAction &action = actions[ii];
2929 if (action.event && action.event->typeName() == QLatin1String("AnchorChanges")
2930 && (d->targets.isEmpty() || d->targets.contains(static_cast<QDeclarativeAnchorChanges*>(action.event)->object()))) {
2931 data->actions << static_cast<QDeclarativeAnchorChanges*>(action.event)->additionalActions();
2935 if (data->actions.count()) {
2936 if (!d->rangeIsSet) {
2937 d->va->setStartValue(qreal(0));
2938 d->va->setEndValue(qreal(1));
2939 d->rangeIsSet = true;
2941 d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
2942 d->va->setFromSourcedValue(&data->fromSourced);
2948 QDeclarativeScriptActionPrivate::QDeclarativeScriptActionPrivate()
2949 : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {}