4e59626075317a45e7a6f57f73cf63164ab09412
[profile/ivi/qtdeclarative.git] / src / quick / util / qdeclarativeanimation.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdeclarativeanimation_p.h"
43 #include "qdeclarativeanimation_p_p.h"
44
45 #include <private/qdeclarativestateoperations_p.h>
46 #include <private/qdeclarativecontext_p.h>
47
48 #include <qdeclarativepropertyvaluesource.h>
49 #include <qdeclarative.h>
50 #include <qdeclarativeinfo.h>
51 #include <qdeclarativeexpression.h>
52 #include <private/qdeclarativestringconverters_p.h>
53 #include <private/qdeclarativeglobal_p.h>
54 #include <private/qdeclarativemetatype_p.h>
55 #include <private/qdeclarativevaluetype_p.h>
56 #include <private/qdeclarativeproperty_p.h>
57 #include <private/qdeclarativeengine_p.h>
58
59 #include <qvariant.h>
60 #include <qcolor.h>
61 #include <qfile.h>
62 #include <QParallelAnimationGroup>
63 #include <QSequentialAnimationGroup>
64 #include <QtCore/qset.h>
65 #include <QtCore/qrect.h>
66 #include <QtCore/qpoint.h>
67 #include <QtCore/qsize.h>
68 #include <QtCore/qmath.h>
69
70 #include <private/qvariantanimation_p.h>
71
72 QT_BEGIN_NAMESPACE
73
74 /*!
75     \qmlclass Animation QDeclarativeAbstractAnimation
76     \inqmlmodule QtQuick 2
77     \ingroup qml-animation-transition
78     \brief The Animation element is the base of all QML animations.
79
80     The Animation element cannot be used directly in a QML file.  It exists
81     to provide a set of common properties and methods, available across all the
82     other animation types that inherit from it.  Attempting to use the Animation
83     element directly will result in an error.
84 */
85
86 QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QObject *parent)
87 : QObject(*(new QDeclarativeAbstractAnimationPrivate), parent)
88 {
89 }
90
91 QDeclarativeAbstractAnimation::~QDeclarativeAbstractAnimation()
92 {
93 }
94
95 QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QDeclarativeAbstractAnimationPrivate &dd, QObject *parent)
96 : QObject(dd, parent)
97 {
98 }
99
100 /*!
101     \qmlproperty bool QtQuick2::Animation::running
102     This property holds whether the animation is currently running.
103
104     The \c running property can be set to declaratively control whether or not
105     an animation is running.  The following example will animate a rectangle
106     whenever the \l MouseArea is pressed.
107
108     \code
109     Rectangle {
110         width: 100; height: 100
111         NumberAnimation on x {
112             running: myMouse.pressed
113             from: 0; to: 100
114         }
115         MouseArea { id: myMouse }
116     }
117     \endcode
118
119     Likewise, the \c running property can be read to determine if the animation
120     is running.  In the following example the text element will indicate whether
121     or not the animation is running.
122
123     \code
124     NumberAnimation { id: myAnimation }
125     Text { text: myAnimation.running ? "Animation is running" : "Animation is not running" }
126     \endcode
127
128     Animations can also be started and stopped imperatively from JavaScript
129     using the \c start() and \c stop() methods.
130
131     By default, animations are not running. Though, when the animations are assigned to properties,
132     as property value sources using the \e on syntax, they are set to running by default.
133 */
134 bool QDeclarativeAbstractAnimation::isRunning() const
135 {
136     Q_D(const QDeclarativeAbstractAnimation);
137     return d->running;
138 }
139
140 // the behavior calls this function
141 void QDeclarativeAbstractAnimation::notifyRunningChanged(bool running)
142 {
143     Q_D(QDeclarativeAbstractAnimation);
144     if (d->disableUserControl && d->running != running) {
145         d->running = running;
146         emit runningChanged(running);
147     }
148 }
149
150 //commence is called to start an animation when it is used as a
151 //simple animation, and not as part of a transition
152 void QDeclarativeAbstractAnimationPrivate::commence()
153 {
154     Q_Q(QDeclarativeAbstractAnimation);
155
156     QDeclarativeStateActions actions;
157     QDeclarativeProperties properties;
158     q->transition(actions, properties, QDeclarativeAbstractAnimation::Forward);
159
160     q->qtAnimation()->start();
161     if (q->qtAnimation()->state() == QAbstractAnimation::Stopped) {
162         running = false;
163         emit q->completed();
164     }
165 }
166
167 QDeclarativeProperty QDeclarativeAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj)
168 {
169     QDeclarativeProperty prop(obj, str, qmlContext(infoObj));
170     if (!prop.isValid()) {
171         qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate non-existent property \"%1\"").arg(str);
172         return QDeclarativeProperty();
173     } else if (!prop.isWritable()) {
174         qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str);
175         return QDeclarativeProperty();
176     }
177     return prop;
178 }
179
180 void QDeclarativeAbstractAnimation::setRunning(bool r)
181 {
182     Q_D(QDeclarativeAbstractAnimation);
183     if (!d->componentComplete) {
184         d->running = r;
185         if (r == false)
186             d->avoidPropertyValueSourceStart = true;
187         else if (!d->registered) {
188             d->registered = true;
189             QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
190             engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
191         }
192         return;
193     }
194
195     if (d->running == r)
196         return;
197
198     if (d->group || d->disableUserControl) {
199         qmlInfo(this) << "setRunning() cannot be used on non-root animation nodes.";
200         return;
201     }
202
203     d->running = r;
204     if (d->running) {
205         bool supressStart = false;
206         if (d->alwaysRunToEnd && d->loopCount != 1
207             && qtAnimation()->state() == QAbstractAnimation::Running) {
208             //we've restarted before the final loop finished; restore proper loop count
209             if (d->loopCount == -1)
210                 qtAnimation()->setLoopCount(d->loopCount);
211             else
212                 qtAnimation()->setLoopCount(qtAnimation()->currentLoop() + d->loopCount);
213             supressStart = true;    //we want the animation to continue, rather than restart
214         }
215
216         if (!d->connectedTimeLine) {
217             FAST_CONNECT(qtAnimation(), SIGNAL(finished()), this, SLOT(timelineComplete()))
218             d->connectedTimeLine = true;
219         }
220         if (!supressStart)
221             d->commence();
222         emit started();
223     } else {
224         if (d->alwaysRunToEnd) {
225             if (d->loopCount != 1)
226                 qtAnimation()->setLoopCount(qtAnimation()->currentLoop()+1);    //finish the current loop
227         } else
228             qtAnimation()->stop();
229
230         emit completed();
231     }
232
233     emit runningChanged(d->running);
234 }
235
236 /*!
237     \qmlproperty bool QtQuick2::Animation::paused
238     This property holds whether the animation is currently paused.
239
240     The \c paused property can be set to declaratively control whether or not
241     an animation is paused.
242
243     Animations can also be paused and resumed imperatively from JavaScript
244     using the \c pause() and \c resume() methods.
245
246     By default, animations are not paused.
247 */
248 bool QDeclarativeAbstractAnimation::isPaused() const
249 {
250     Q_D(const QDeclarativeAbstractAnimation);
251     return d->paused;
252 }
253
254 void QDeclarativeAbstractAnimation::setPaused(bool p)
255 {
256     Q_D(QDeclarativeAbstractAnimation);
257     if (d->paused == p)
258         return;
259
260     if (d->group || d->disableUserControl) {
261         qmlInfo(this) << "setPaused() cannot be used on non-root animation nodes.";
262         return;
263     }
264
265     d->paused = p;
266
267     if (!d->componentComplete)
268         return;
269
270     if (d->paused)
271         qtAnimation()->pause();
272     else
273         qtAnimation()->resume();
274
275     emit pausedChanged(d->paused);
276 }
277
278 void QDeclarativeAbstractAnimation::classBegin()
279 {
280     Q_D(QDeclarativeAbstractAnimation);
281     d->componentComplete = false;
282 }
283
284 void QDeclarativeAbstractAnimation::componentComplete()
285 {
286     Q_D(QDeclarativeAbstractAnimation);
287     d->componentComplete = true;
288 }
289
290 void QDeclarativeAbstractAnimation::componentFinalized()
291 {
292     Q_D(QDeclarativeAbstractAnimation);
293     if (d->running) {
294         d->running = false;
295         setRunning(true);
296     }
297     if (d->paused) {
298         d->paused = false;
299         setPaused(true);
300     }
301 }
302
303 /*!
304     \qmlproperty bool QtQuick2::Animation::alwaysRunToEnd
305     This property holds whether the animation should run to completion when it is stopped.
306
307     If this true the animation will complete its current iteration when it
308     is stopped - either by setting the \c running property to false, or by
309     calling the \c stop() method.  The \c complete() method is not effected
310     by this value.
311
312     This behavior is most useful when the \c repeat property is set, as the
313     animation will finish playing normally but not restart.
314
315     By default, the alwaysRunToEnd property is not set.
316
317     \note alwaysRunToEnd has no effect on animations in a Transition.
318 */
319 bool QDeclarativeAbstractAnimation::alwaysRunToEnd() const
320 {
321     Q_D(const QDeclarativeAbstractAnimation);
322     return d->alwaysRunToEnd;
323 }
324
325 void QDeclarativeAbstractAnimation::setAlwaysRunToEnd(bool f)
326 {
327     Q_D(QDeclarativeAbstractAnimation);
328     if (d->alwaysRunToEnd == f)
329         return;
330
331     d->alwaysRunToEnd = f;
332     emit alwaysRunToEndChanged(f);
333 }
334
335 /*!
336     \qmlproperty int QtQuick2::Animation::loops
337     This property holds the number of times the animation should play.
338
339     By default, \c loops is 1: the animation will play through once and then stop.
340
341     If set to Animation.Infinite, the animation will continuously repeat until it is explicitly
342     stopped - either by setting the \c running property to false, or by calling
343     the \c stop() method.
344
345     In the following example, the rectangle will spin indefinitely.
346
347     \code
348     Rectangle {
349         width: 100; height: 100; color: "green"
350         RotationAnimation on rotation {
351             loops: Animation.Infinite
352             from: 0
353             to: 360
354         }
355     }
356     \endcode
357 */
358 int QDeclarativeAbstractAnimation::loops() const
359 {
360     Q_D(const QDeclarativeAbstractAnimation);
361     return d->loopCount;
362 }
363
364 void QDeclarativeAbstractAnimation::setLoops(int loops)
365 {
366     Q_D(QDeclarativeAbstractAnimation);
367     if (loops < 0)
368         loops = -1;
369
370     if (loops == d->loopCount)
371         return;
372
373     d->loopCount = loops;
374     qtAnimation()->setLoopCount(loops);
375     emit loopCountChanged(loops);
376 }
377
378
379 int QDeclarativeAbstractAnimation::currentTime()
380 {
381     return qtAnimation()->currentLoopTime();
382 }
383
384 void QDeclarativeAbstractAnimation::setCurrentTime(int time)
385 {
386     qtAnimation()->setCurrentTime(time);
387 }
388
389 QDeclarativeAnimationGroup *QDeclarativeAbstractAnimation::group() const
390 {
391     Q_D(const QDeclarativeAbstractAnimation);
392     return d->group;
393 }
394
395 void QDeclarativeAbstractAnimation::setGroup(QDeclarativeAnimationGroup *g)
396 {
397     Q_D(QDeclarativeAbstractAnimation);
398     if (d->group == g)
399         return;
400     if (d->group)
401         static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.removeAll(this);
402
403     d->group = g;
404
405     if (d->group && !static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.contains(this))
406         static_cast<QDeclarativeAnimationGroupPrivate *>(d->group->d_func())->animations.append(this);
407
408     //if (g) //if removed from a group, then the group should no longer be the parent
409         setParent(g);
410 }
411
412 /*!
413     \qmlmethod QtQuick2::Animation::start()
414     \brief Starts the animation.
415
416     If the animation is already running, calling this method has no effect.  The
417     \c running property will be true following a call to \c start().
418 */
419 void QDeclarativeAbstractAnimation::start()
420 {
421     setRunning(true);
422 }
423
424 /*!
425     \qmlmethod QtQuick2::Animation::pause()
426     \brief Pauses the animation.
427
428     If the animation is already paused, calling this method has no effect.  The
429     \c paused property will be true following a call to \c pause().
430 */
431 void QDeclarativeAbstractAnimation::pause()
432 {
433     setPaused(true);
434 }
435
436 /*!
437     \qmlmethod QtQuick2::Animation::resume()
438     \brief Resumes a paused animation.
439
440     If the animation is not paused, calling this method has no effect.  The
441     \c paused property will be false following a call to \c resume().
442 */
443 void QDeclarativeAbstractAnimation::resume()
444 {
445     setPaused(false);
446 }
447
448 /*!
449     \qmlmethod QtQuick2::Animation::stop()
450     \brief Stops the animation.
451
452     If the animation is not running, calling this method has no effect.  The
453     \c running property will be false following a call to \c stop().
454
455     Normally \c stop() stops the animation immediately, and the animation has
456     no further influence on property values.  In this example animation
457     \code
458     Rectangle {
459         NumberAnimation on x { from: 0; to: 100; duration: 500 }
460     }
461     \endcode
462     was stopped at time 250ms, the \c x property will have a value of 50.
463
464     However, if the \c alwaysRunToEnd property is set, the animation will
465     continue running until it completes and then stop.  The \c running property
466     will still become false immediately.
467 */
468 void QDeclarativeAbstractAnimation::stop()
469 {
470     setRunning(false);
471 }
472
473 /*!
474     \qmlmethod QtQuick2::Animation::restart()
475     \brief Restarts the animation.
476
477     This is a convenience method, and is equivalent to calling \c stop() and
478     then \c start().
479 */
480 void QDeclarativeAbstractAnimation::restart()
481 {
482     stop();
483     start();
484 }
485
486 /*!
487     \qmlmethod QtQuick2::Animation::complete()
488     \brief Stops the animation, jumping to the final property values.
489
490     If the animation is not running, calling this method has no effect.  The
491     \c running property will be false following a call to \c complete().
492
493     Unlike \c stop(), \c complete() immediately fast-forwards the animation to
494     its end.  In the following example,
495     \code
496     Rectangle {
497         NumberAnimation on x { from: 0; to: 100; duration: 500 }
498     }
499     \endcode
500     calling \c stop() at time 250ms will result in the \c x property having
501     a value of 50, while calling \c complete() will set the \c x property to
502     100, exactly as though the animation had played the whole way through.
503 */
504 void QDeclarativeAbstractAnimation::complete()
505 {
506     if (isRunning()) {
507          qtAnimation()->setCurrentTime(qtAnimation()->duration());
508     }
509 }
510
511 void QDeclarativeAbstractAnimation::setTarget(const QDeclarativeProperty &p)
512 {
513     Q_D(QDeclarativeAbstractAnimation);
514     d->defaultProperty = p;
515
516     if (!d->avoidPropertyValueSourceStart)
517         setRunning(true);
518 }
519
520 /*
521     we rely on setTarget only being called when used as a value source
522     so this function allows us to do the same thing as setTarget without
523     that assumption
524 */
525 void QDeclarativeAbstractAnimation::setDefaultTarget(const QDeclarativeProperty &p)
526 {
527     Q_D(QDeclarativeAbstractAnimation);
528     d->defaultProperty = p;
529 }
530
531 /*
532     don't allow start/stop/pause/resume to be manually invoked,
533     because something else (like a Behavior) already has control
534     over the animation.
535 */
536 void QDeclarativeAbstractAnimation::setDisableUserControl()
537 {
538     Q_D(QDeclarativeAbstractAnimation);
539     d->disableUserControl = true;
540 }
541
542 void QDeclarativeAbstractAnimation::transition(QDeclarativeStateActions &actions,
543                                       QDeclarativeProperties &modified,
544                                       TransitionDirection direction)
545 {
546     Q_UNUSED(actions);
547     Q_UNUSED(modified);
548     Q_UNUSED(direction);
549 }
550
551 void QDeclarativeAbstractAnimation::timelineComplete()
552 {
553     Q_D(QDeclarativeAbstractAnimation);
554     setRunning(false);
555     if (d->alwaysRunToEnd && d->loopCount != 1) {
556         //restore the proper loopCount for the next run
557         qtAnimation()->setLoopCount(d->loopCount);
558     }
559 }
560
561 /*!
562     \qmlclass PauseAnimation QDeclarativePauseAnimation
563     \inqmlmodule QtQuick 2
564     \ingroup qml-animation-transition
565     \inherits Animation
566     \brief The PauseAnimation element provides a pause for an animation.
567
568     When used in a SequentialAnimation, PauseAnimation is a step when
569     nothing happens, for a specified duration.
570
571     A 500ms animation sequence, with a 100ms pause between two animations:
572     \code
573     SequentialAnimation {
574         NumberAnimation { ... duration: 200 }
575         PauseAnimation { duration: 100 }
576         NumberAnimation { ... duration: 200 }
577     }
578     \endcode
579
580     \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
581 */
582 QDeclarativePauseAnimation::QDeclarativePauseAnimation(QObject *parent)
583 : QDeclarativeAbstractAnimation(*(new QDeclarativePauseAnimationPrivate), parent)
584 {
585     Q_D(QDeclarativePauseAnimation);
586     d->init();
587 }
588
589 QDeclarativePauseAnimation::~QDeclarativePauseAnimation()
590 {
591 }
592
593 void QDeclarativePauseAnimationPrivate::init()
594 {
595     Q_Q(QDeclarativePauseAnimation);
596     pa = new QPauseAnimation;
597     QDeclarative_setParent_noEvent(pa, q);
598 }
599
600 /*!
601     \qmlproperty int QtQuick2::PauseAnimation::duration
602     This property holds the duration of the pause in milliseconds
603
604     The default value is 250.
605 */
606 int QDeclarativePauseAnimation::duration() const
607 {
608     Q_D(const QDeclarativePauseAnimation);
609     return d->pa->duration();
610 }
611
612 void QDeclarativePauseAnimation::setDuration(int duration)
613 {
614     if (duration < 0) {
615         qmlInfo(this) << tr("Cannot set a duration of < 0");
616         return;
617     }
618
619     Q_D(QDeclarativePauseAnimation);
620     if (d->pa->duration() == duration)
621         return;
622     d->pa->setDuration(duration);
623     emit durationChanged(duration);
624 }
625
626 QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation()
627 {
628     Q_D(QDeclarativePauseAnimation);
629     return d->pa;
630 }
631
632 /*!
633     \qmlclass ColorAnimation QDeclarativeColorAnimation
634     \inqmlmodule QtQuick 2
635   \ingroup qml-animation-transition
636     \inherits PropertyAnimation
637     \brief The ColorAnimation element animates changes in color values.
638
639     ColorAnimation is a specialized PropertyAnimation that defines an
640     animation to be applied when a color value changes.
641
642     Here is a ColorAnimation applied to the \c color property of a \l Rectangle
643     as a property value source. It animates the \c color property's value from
644     its current value to a value of "red", over 1000 milliseconds:
645
646     \snippet doc/src/snippets/declarative/coloranimation.qml 0
647
648     Like any other animation element, a ColorAnimation can be applied in a
649     number of ways, including transitions, behaviors and property value
650     sources. The \l {QML Animation and Transitions} documentation shows a
651     variety of methods for creating animations.
652
653     For convenience, when a ColorAnimation is used in a \l Transition, it will
654     animate any \c color properties that have been modified during the state
655     change. If a \l{PropertyAnimation::}{property} or
656     \l{PropertyAnimation::}{properties} are explicitly set for the animation,
657     then those are used instead.
658
659     \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
660 */
661 QDeclarativeColorAnimation::QDeclarativeColorAnimation(QObject *parent)
662 : QDeclarativePropertyAnimation(parent)
663 {
664     Q_D(QDeclarativePropertyAnimation);
665     d->interpolatorType = QMetaType::QColor;
666     d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
667     d->defaultToInterpolatorType = true;
668 }
669
670 QDeclarativeColorAnimation::~QDeclarativeColorAnimation()
671 {
672 }
673
674 /*!
675     \qmlproperty color QtQuick2::ColorAnimation::from
676     This property holds the color value at which the animation should begin.
677
678     For example, the following animation is not applied until a color value
679     has reached "#c0c0c0":
680
681     \qml
682     Item {
683         states: [
684             // States are defined here...
685         ]
686
687         transition: Transition {
688             NumberAnimation { from: "#c0c0c0"; duration: 2000 }
689         }
690     }
691     \endqml
692
693     If the ColorAnimation is defined within a \l Transition or \l Behavior,
694     this value defaults to the value defined in the starting state of the
695     \l Transition, or the current value of the property at the moment the
696     \l Behavior is triggered.
697
698     \sa {QML Animation and Transitions}
699 */
700 QColor QDeclarativeColorAnimation::from() const
701 {
702     Q_D(const QDeclarativePropertyAnimation);
703     return d->from.value<QColor>();
704 }
705
706 void QDeclarativeColorAnimation::setFrom(const QColor &f)
707 {
708     QDeclarativePropertyAnimation::setFrom(f);
709 }
710
711 /*!
712     \qmlproperty color QtQuick2::ColorAnimation::to
713
714     This property holds the color value at which the animation should end.
715
716     If the ColorAnimation is defined within a \l Transition or \l Behavior,
717     this value defaults to the value defined in the end state of the
718     \l Transition, or the value of the property change that triggered the
719     \l Behavior.
720
721     \sa {QML Animation and Transitions}
722 */
723 QColor QDeclarativeColorAnimation::to() const
724 {
725     Q_D(const QDeclarativePropertyAnimation);
726     return d->to.value<QColor>();
727 }
728
729 void QDeclarativeColorAnimation::setTo(const QColor &t)
730 {
731     QDeclarativePropertyAnimation::setTo(t);
732 }
733
734
735
736 /*!
737     \qmlclass ScriptAction QDeclarativeScriptAction
738     \inqmlmodule QtQuick 2
739     \ingroup qml-animation-transition
740     \inherits Animation
741     \brief The ScriptAction element allows scripts to be run during an animation.
742
743     ScriptAction can be used to run a script at a specific point in an animation.
744
745     \qml
746     SequentialAnimation {
747         NumberAnimation {
748             // ...
749         }
750         ScriptAction { script: doSomething(); }
751         NumberAnimation {
752             // ...
753         }
754     }
755     \endqml
756
757     When used as part of a Transition, you can also target a specific
758     StateChangeScript to run using the \c scriptName property.
759
760     \snippet doc/src/snippets/declarative/states/statechangescript.qml state and transition
761
762     \sa StateChangeScript
763 */
764 QDeclarativeScriptAction::QDeclarativeScriptAction(QObject *parent)
765     :QDeclarativeAbstractAnimation(*(new QDeclarativeScriptActionPrivate), parent)
766 {
767     Q_D(QDeclarativeScriptAction);
768     d->init();
769 }
770
771 QDeclarativeScriptAction::~QDeclarativeScriptAction()
772 {
773 }
774
775 void QDeclarativeScriptActionPrivate::init()
776 {
777     Q_Q(QDeclarativeScriptAction);
778     rsa = new QActionAnimation(&proxy);
779     QDeclarative_setParent_noEvent(rsa, q);
780 }
781
782 /*!
783     \qmlproperty script QtQuick2::ScriptAction::script
784     This property holds the script to run.
785 */
786 QDeclarativeScriptString QDeclarativeScriptAction::script() const
787 {
788     Q_D(const QDeclarativeScriptAction);
789     return d->script;
790 }
791
792 void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script)
793 {
794     Q_D(QDeclarativeScriptAction);
795     d->script = script;
796 }
797
798 /*!
799     \qmlproperty string QtQuick2::ScriptAction::scriptName
800     This property holds the the name of the StateChangeScript to run.
801
802     This property is only valid when ScriptAction is used as part of a transition.
803     If both script and scriptName are set, scriptName will be used.
804
805     \note When using scriptName in a reversible transition, the script will only
806     be run when the transition is being run forwards.
807 */
808 QString QDeclarativeScriptAction::stateChangeScriptName() const
809 {
810     Q_D(const QDeclarativeScriptAction);
811     return d->name;
812 }
813
814 void QDeclarativeScriptAction::setStateChangeScriptName(const QString &name)
815 {
816     Q_D(QDeclarativeScriptAction);
817     d->name = name;
818 }
819
820 void QDeclarativeScriptActionPrivate::execute()
821 {
822     Q_Q(QDeclarativeScriptAction);
823     if (hasRunScriptScript && reversing)
824         return;
825
826     QDeclarativeScriptString scriptStr = hasRunScriptScript ? runScriptScript : script;
827
828     if (!scriptStr.script().isEmpty()) {
829         QDeclarativeExpression expr(scriptStr);
830         expr.evaluate();
831         if (expr.hasError())
832             qmlInfo(q) << expr.error();
833     }
834 }
835
836 void QDeclarativeScriptAction::transition(QDeclarativeStateActions &actions,
837                                     QDeclarativeProperties &modified,
838                                     TransitionDirection direction)
839 {
840     Q_D(QDeclarativeScriptAction);
841     Q_UNUSED(modified);
842
843     d->hasRunScriptScript = false;
844     d->reversing = (direction == Backward);
845     for (int ii = 0; ii < actions.count(); ++ii) {
846         QDeclarativeAction &action = actions[ii];
847
848         if (action.event && action.event->typeName() == QLatin1String("StateChangeScript")
849             && static_cast<QDeclarativeStateChangeScript*>(action.event)->name() == d->name) {
850             d->runScriptScript = static_cast<QDeclarativeStateChangeScript*>(action.event)->script();
851             d->hasRunScriptScript = true;
852             action.actionDone = true;
853             break;  //only match one (names should be unique)
854         }
855     }
856 }
857
858 QAbstractAnimation *QDeclarativeScriptAction::qtAnimation()
859 {
860     Q_D(QDeclarativeScriptAction);
861     return d->rsa;
862 }
863
864
865
866 /*!
867     \qmlclass PropertyAction QDeclarativePropertyAction
868     \inqmlmodule QtQuick 2
869     \ingroup qml-animation-transition
870     \inherits Animation
871     \brief The PropertyAction element allows immediate property changes during animation.
872
873     PropertyAction is used to specify an immediate property change during an
874     animation. The property change is not animated.
875
876     It is useful for setting non-animated property values during an animation.
877
878     For example, here is a SequentialAnimation that sets the image's
879     \l {Image::}{smooth} property to \c true, animates the width of the image,
880     then sets \l {Image::}{smooth} back to \c false:
881
882     \snippet doc/src/snippets/declarative/propertyaction.qml standalone
883
884     PropertyAction is also useful for setting the exact point at which a property
885     change should occur during a \l Transition. For example, if PropertyChanges
886     was used in a \l State to rotate an item around a particular
887     \l {Item::}{transformOrigin}, it might be implemented like this:
888
889     \snippet doc/src/snippets/declarative/propertyaction.qml transition
890
891     However, with this code, the \c transformOrigin is not set until \e after
892     the animation, as a \l State is taken to define the values at the \e end of
893     a transition. The animation would rotate at the default \c transformOrigin,
894     then jump to \c Item.BottomRight. To fix this, insert a PropertyAction
895     before the RotationAnimation begins:
896
897     \snippet doc/src/snippets/declarative/propertyaction-sequential.qml sequential
898
899     This immediately sets the \c transformOrigin property to the value defined
900     in the end state of the \l Transition (i.e. the value defined in the
901     PropertyAction object) so that the rotation animation begins with the
902     correct transform origin.
903
904     \sa {QML Animation and Transitions}, QtDeclarative
905 */
906 QDeclarativePropertyAction::QDeclarativePropertyAction(QObject *parent)
907 : QDeclarativeAbstractAnimation(*(new QDeclarativePropertyActionPrivate), parent)
908 {
909     Q_D(QDeclarativePropertyAction);
910     d->init();
911 }
912
913 QDeclarativePropertyAction::~QDeclarativePropertyAction()
914 {
915 }
916
917 void QDeclarativePropertyActionPrivate::init()
918 {
919     Q_Q(QDeclarativePropertyAction);
920     spa = new QActionAnimation;
921     QDeclarative_setParent_noEvent(spa, q);
922 }
923
924 QObject *QDeclarativePropertyAction::target() const
925 {
926     Q_D(const QDeclarativePropertyAction);
927     return d->target;
928 }
929
930 void QDeclarativePropertyAction::setTarget(QObject *o)
931 {
932     Q_D(QDeclarativePropertyAction);
933     if (d->target == o)
934         return;
935     d->target = o;
936     emit targetChanged();
937 }
938
939 QString QDeclarativePropertyAction::property() const
940 {
941     Q_D(const QDeclarativePropertyAction);
942     return d->propertyName;
943 }
944
945 void QDeclarativePropertyAction::setProperty(const QString &n)
946 {
947     Q_D(QDeclarativePropertyAction);
948     if (d->propertyName == n)
949         return;
950     d->propertyName = n;
951     emit propertyChanged();
952 }
953
954 /*!
955     \qmlproperty Object QtQuick2::PropertyAction::target
956     \qmlproperty list<Object> QtQuick2::PropertyAction::targets
957     \qmlproperty string QtQuick2::PropertyAction::property
958     \qmlproperty string QtQuick2::PropertyAction::properties
959
960     These properties determine the items and their properties that are
961     affected by this action.
962
963     The details of how these properties are interpreted in different situations
964     is covered in the \l{PropertyAnimation::properties}{corresponding} PropertyAnimation
965     documentation.
966
967     \sa exclude
968 */
969 QString QDeclarativePropertyAction::properties() const
970 {
971     Q_D(const QDeclarativePropertyAction);
972     return d->properties;
973 }
974
975 void QDeclarativePropertyAction::setProperties(const QString &p)
976 {
977     Q_D(QDeclarativePropertyAction);
978     if (d->properties == p)
979         return;
980     d->properties = p;
981     emit propertiesChanged(p);
982 }
983
984 QDeclarativeListProperty<QObject> QDeclarativePropertyAction::targets()
985 {
986     Q_D(QDeclarativePropertyAction);
987     return QDeclarativeListProperty<QObject>(this, d->targets);
988 }
989
990 /*!
991     \qmlproperty list<Object> QtQuick2::PropertyAction::exclude
992     This property holds the objects that should not be affected by this action.
993
994     \sa targets
995 */
996 QDeclarativeListProperty<QObject> QDeclarativePropertyAction::exclude()
997 {
998     Q_D(QDeclarativePropertyAction);
999     return QDeclarativeListProperty<QObject>(this, d->exclude);
1000 }
1001
1002 /*!
1003     \qmlproperty any QtQuick2::PropertyAction::value
1004     This property holds the value to be set on the property.
1005
1006     If the PropertyAction is defined within a \l Transition or \l Behavior,
1007     this value defaults to the value defined in the end state of the
1008     \l Transition, or the value of the property change that triggered the
1009     \l Behavior.
1010 */
1011 QVariant QDeclarativePropertyAction::value() const
1012 {
1013     Q_D(const QDeclarativePropertyAction);
1014     return d->value;
1015 }
1016
1017 void QDeclarativePropertyAction::setValue(const QVariant &v)
1018 {
1019     Q_D(QDeclarativePropertyAction);
1020     if (d->value.isNull || d->value != v) {
1021         d->value = v;
1022         emit valueChanged(v);
1023     }
1024 }
1025
1026 QAbstractAnimation *QDeclarativePropertyAction::qtAnimation()
1027 {
1028     Q_D(QDeclarativePropertyAction);
1029     return d->spa;
1030 }
1031
1032 void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions,
1033                                       QDeclarativeProperties &modified,
1034                                       TransitionDirection direction)
1035 {
1036     Q_D(QDeclarativePropertyAction);
1037     Q_UNUSED(direction);
1038
1039     struct QDeclarativeSetPropertyAnimationAction : public QAbstractAnimationAction
1040     {
1041         QDeclarativeStateActions actions;
1042         virtual void doAction()
1043         {
1044             for (int ii = 0; ii < actions.count(); ++ii) {
1045                 const QDeclarativeAction &action = actions.at(ii);
1046                 QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
1047             }
1048         }
1049     };
1050
1051     QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
1052     for (int ii = 0; ii < props.count(); ++ii)
1053         props[ii] = props.at(ii).trimmed();
1054     if (!d->propertyName.isEmpty())
1055         props << d->propertyName;
1056
1057     QList<QObject*> targets = d->targets;
1058     if (d->target)
1059         targets.append(d->target);
1060
1061     bool hasSelectors = !props.isEmpty() || !targets.isEmpty() || !d->exclude.isEmpty();
1062
1063     if (d->defaultProperty.isValid() && !hasSelectors) {
1064         props << d->defaultProperty.name();
1065         targets << d->defaultProperty.object();
1066     }
1067
1068     QDeclarativeSetPropertyAnimationAction *data = new QDeclarativeSetPropertyAnimationAction;
1069
1070     bool hasExplicit = false;
1071     //an explicit animation has been specified
1072     if (d->value.isValid()) {
1073         for (int i = 0; i < props.count(); ++i) {
1074             for (int j = 0; j < targets.count(); ++j) {
1075                 QDeclarativeAction myAction;
1076                 myAction.property = d->createProperty(targets.at(j), props.at(i), this);
1077                 if (myAction.property.isValid()) {
1078                     myAction.toValue = d->value;
1079                     QDeclarativePropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType());
1080                     data->actions << myAction;
1081                     hasExplicit = true;
1082                     for (int ii = 0; ii < actions.count(); ++ii) {
1083                         QDeclarativeAction &action = actions[ii];
1084                         if (action.property.object() == myAction.property.object() &&
1085                             myAction.property.name() == action.property.name()) {
1086                             modified << action.property;
1087                             break;  //### any chance there could be multiples?
1088                         }
1089                     }
1090                 }
1091             }
1092         }
1093     }
1094
1095     if (!hasExplicit)
1096     for (int ii = 0; ii < actions.count(); ++ii) {
1097         QDeclarativeAction &action = actions[ii];
1098
1099         QObject *obj = action.property.object();
1100         QString propertyName = action.property.name();
1101         QObject *sObj = action.specifiedObject;
1102         QString sPropertyName = action.specifiedProperty;
1103         bool same = (obj == sObj);
1104
1105         if ((targets.isEmpty() || targets.contains(obj) || (!same && targets.contains(sObj))) &&
1106            (!d->exclude.contains(obj)) && (same || (!d->exclude.contains(sObj))) &&
1107            (props.contains(propertyName) || (!same && props.contains(sPropertyName)))) {
1108             QDeclarativeAction myAction = action;
1109
1110             if (d->value.isValid())
1111                 myAction.toValue = d->value;
1112             QDeclarativePropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType());
1113
1114             modified << action.property;
1115             data->actions << myAction;
1116             action.fromValue = myAction.toValue;
1117         }
1118     }
1119
1120     if (data->actions.count()) {
1121         d->spa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped);
1122     } else {
1123         delete data;
1124     }
1125 }
1126
1127 /*!
1128     \qmlclass NumberAnimation QDeclarativeNumberAnimation
1129     \inqmlmodule QtQuick 2
1130   \ingroup qml-animation-transition
1131     \inherits PropertyAnimation
1132     \brief The NumberAnimation element animates changes in qreal-type values.
1133
1134     NumberAnimation is a specialized PropertyAnimation that defines an
1135     animation to be applied when a numerical value changes.
1136
1137     Here is a NumberAnimation applied to the \c x property of a \l Rectangle
1138     as a property value source. It animates the \c x value from its current
1139     value to a value of 50, over 1000 milliseconds:
1140
1141     \snippet doc/src/snippets/declarative/numberanimation.qml 0
1142
1143     Like any other animation element, a NumberAnimation can be applied in a
1144     number of ways, including transitions, behaviors and property value
1145     sources. The \l {QML Animation and Transitions} documentation shows a
1146     variety of methods for creating animations.
1147
1148     Note that NumberAnimation may not animate smoothly if there are irregular
1149     changes in the number value that it is tracking. If this is the case, use
1150     SmoothedAnimation instead.
1151
1152     \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1153 */
1154 QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QObject *parent)
1155 : QDeclarativePropertyAnimation(parent)
1156 {
1157     init();
1158 }
1159
1160 QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent)
1161 : QDeclarativePropertyAnimation(dd, parent)
1162 {
1163     init();
1164 }
1165
1166 QDeclarativeNumberAnimation::~QDeclarativeNumberAnimation()
1167 {
1168 }
1169
1170 void QDeclarativeNumberAnimation::init()
1171 {
1172     Q_D(QDeclarativePropertyAnimation);
1173     d->interpolatorType = QMetaType::QReal;
1174     d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1175 }
1176
1177 /*!
1178     \qmlproperty real QtQuick2::NumberAnimation::from
1179     This property holds the starting value for the animation.
1180
1181     For example, the following animation is not applied until the \c x value
1182     has reached 100:
1183
1184     \qml
1185     Item {
1186         states: [
1187             // ...
1188         ]
1189
1190         transition: Transition {
1191             NumberAnimation { properties: "x"; from: 100; duration: 200 }
1192         }
1193     }
1194     \endqml
1195
1196     If the NumberAnimation is defined within a \l Transition or \l Behavior,
1197     this value defaults to the value defined in the starting state of the
1198     \l Transition, or the current value of the property at the moment the
1199     \l Behavior is triggered.
1200
1201     \sa {QML Animation and Transitions}
1202 */
1203
1204 qreal QDeclarativeNumberAnimation::from() const
1205 {
1206     Q_D(const QDeclarativePropertyAnimation);
1207     return d->from.toReal();
1208 }
1209
1210 void QDeclarativeNumberAnimation::setFrom(qreal f)
1211 {
1212     QDeclarativePropertyAnimation::setFrom(f);
1213 }
1214
1215 /*!
1216     \qmlproperty real QtQuick2::NumberAnimation::to
1217     This property holds the end value for the animation.
1218
1219     If the NumberAnimation is defined within a \l Transition or \l Behavior,
1220     this value defaults to the value defined in the end state of the
1221     \l Transition, or the value of the property change that triggered the
1222     \l Behavior.
1223
1224     \sa {QML Animation and Transitions}
1225 */
1226 qreal QDeclarativeNumberAnimation::to() const
1227 {
1228     Q_D(const QDeclarativePropertyAnimation);
1229     return d->to.toReal();
1230 }
1231
1232 void QDeclarativeNumberAnimation::setTo(qreal t)
1233 {
1234     QDeclarativePropertyAnimation::setTo(t);
1235 }
1236
1237
1238
1239 /*!
1240     \qmlclass Vector3dAnimation QDeclarativeVector3dAnimation
1241     \inqmlmodule QtQuick 2
1242     \ingroup qml-animation-transition
1243     \inherits PropertyAnimation
1244     \brief The Vector3dAnimation element animates changes in QVector3d values.
1245
1246     Vector3dAnimation is a specialized PropertyAnimation that defines an
1247     animation to be applied when a Vector3d value changes.
1248
1249     Like any other animation element, a Vector3dAnimation can be applied in a
1250     number of ways, including transitions, behaviors and property value
1251     sources. The \l {QML Animation and Transitions} documentation shows a
1252     variety of methods for creating animations.
1253
1254     \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1255 */
1256 QDeclarativeVector3dAnimation::QDeclarativeVector3dAnimation(QObject *parent)
1257 : QDeclarativePropertyAnimation(parent)
1258 {
1259     Q_D(QDeclarativePropertyAnimation);
1260     d->interpolatorType = QMetaType::QVector3D;
1261     d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1262     d->defaultToInterpolatorType = true;
1263 }
1264
1265 QDeclarativeVector3dAnimation::~QDeclarativeVector3dAnimation()
1266 {
1267 }
1268
1269 /*!
1270     \qmlproperty real QtQuick2::Vector3dAnimation::from
1271     This property holds the starting value for the animation.
1272
1273     If the Vector3dAnimation is defined within a \l Transition or \l Behavior,
1274     this value defaults to the value defined in the starting state of the
1275     \l Transition, or the current value of the property at the moment the
1276     \l Behavior is triggered.
1277
1278     \sa {QML Animation and Transitions}
1279 */
1280 QVector3D QDeclarativeVector3dAnimation::from() const
1281 {
1282     Q_D(const QDeclarativePropertyAnimation);
1283     return d->from.value<QVector3D>();
1284 }
1285
1286 void QDeclarativeVector3dAnimation::setFrom(QVector3D f)
1287 {
1288     QDeclarativePropertyAnimation::setFrom(f);
1289 }
1290
1291 /*!
1292     \qmlproperty real QtQuick2::Vector3dAnimation::to
1293     This property holds the end value for the animation.
1294
1295     If the Vector3dAnimation is defined within a \l Transition or \l Behavior,
1296     this value defaults to the value defined in the end state of the
1297     \l Transition, or the value of the property change that triggered the
1298     \l Behavior.
1299
1300     \sa {QML Animation and Transitions}
1301 */
1302 QVector3D QDeclarativeVector3dAnimation::to() const
1303 {
1304     Q_D(const QDeclarativePropertyAnimation);
1305     return d->to.value<QVector3D>();
1306 }
1307
1308 void QDeclarativeVector3dAnimation::setTo(QVector3D t)
1309 {
1310     QDeclarativePropertyAnimation::setTo(t);
1311 }
1312
1313
1314
1315 /*!
1316     \qmlclass RotationAnimation QDeclarativeRotationAnimation
1317     \inqmlmodule QtQuick 2
1318     \ingroup qml-animation-transition
1319     \inherits PropertyAnimation
1320     \brief The RotationAnimation element animates changes in rotation values.
1321
1322     RotationAnimation is a specialized PropertyAnimation that gives control
1323     over the direction of rotation during an animation.
1324
1325     By default, it rotates in the direction
1326     of the numerical change; a rotation from 0 to 240 will rotate 240 degrees
1327     clockwise, while a rotation from 240 to 0 will rotate 240 degrees
1328     counterclockwise. The \l direction property can be set to specify the
1329     direction in which the rotation should occur.
1330
1331     In the following example we use RotationAnimation to animate the rotation
1332     between states via the shortest path:
1333
1334     \snippet doc/src/snippets/declarative/rotationanimation.qml 0
1335
1336     Notice the RotationAnimation did not need to set a \l target
1337     value. As a convenience, when used in a transition, RotationAnimation will rotate all
1338     properties named "rotation" or "angle". You can override this by providing
1339     your own properties via \l {PropertyAnimation::properties}{properties} or
1340     \l {PropertyAnimation::property}{property}.
1341
1342     Also, note the \l Rectangle will be rotated around its default
1343     \l {Item::}{transformOrigin} (which is \c Item.Center). To use a different
1344     transform origin, set the origin in the PropertyChanges object and apply
1345     the change at the start of the animation using PropertyAction. See the
1346     PropertyAction documentation for more details.
1347
1348     Like any other animation element, a RotationAnimation can be applied in a
1349     number of ways, including transitions, behaviors and property value
1350     sources. The \l {QML Animation and Transitions} documentation shows a
1351     variety of methods for creating animations.
1352
1353     \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1354 */
1355 QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress)
1356 {
1357     qreal newt = t;
1358     qreal diff = t-f;
1359     while(diff > 180.0){
1360         newt -= 360.0;
1361         diff -= 360.0;
1362     }
1363     while(diff < -180.0){
1364         newt += 360.0;
1365         diff += 360.0;
1366     }
1367     return QVariant(f + (newt - f) * progress);
1368 }
1369
1370 QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress)
1371 {
1372     qreal newt = t;
1373     qreal diff = t-f;
1374     while(diff < 0.0){
1375         newt += 360.0;
1376         diff += 360.0;
1377     }
1378     return QVariant(f + (newt - f) * progress);
1379 }
1380
1381 QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress)
1382 {
1383     qreal newt = t;
1384     qreal diff = t-f;
1385     while(diff > 0.0){
1386         newt -= 360.0;
1387         diff -= 360.0;
1388     }
1389     return QVariant(f + (newt - f) * progress);
1390 }
1391
1392 QDeclarativeRotationAnimation::QDeclarativeRotationAnimation(QObject *parent)
1393 : QDeclarativePropertyAnimation(*(new QDeclarativeRotationAnimationPrivate), parent)
1394 {
1395     Q_D(QDeclarativeRotationAnimation);
1396     d->interpolatorType = QMetaType::QReal;
1397     d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1398     d->defaultProperties = QLatin1String("rotation,angle");
1399 }
1400
1401 QDeclarativeRotationAnimation::~QDeclarativeRotationAnimation()
1402 {
1403 }
1404
1405 /*!
1406     \qmlproperty real QtQuick2::RotationAnimation::from
1407     This property holds the starting value for the animation.
1408
1409     For example, the following animation is not applied until the \c angle value
1410     has reached 100:
1411
1412     \qml
1413     Item {
1414         states: [
1415             // ...
1416         ]
1417
1418         transition: Transition {
1419             RotationAnimation { properties: "angle"; from: 100; duration: 2000 }
1420         }
1421     }
1422     \endqml
1423
1424     If the RotationAnimation is defined within a \l Transition or \l Behavior,
1425     this value defaults to the value defined in the starting state of the
1426     \l Transition, or the current value of the property at the moment the
1427     \l Behavior is triggered.
1428
1429     \sa {QML Animation and Transitions}
1430 */
1431 qreal QDeclarativeRotationAnimation::from() const
1432 {
1433     Q_D(const QDeclarativeRotationAnimation);
1434     return d->from.toReal();
1435 }
1436
1437 void QDeclarativeRotationAnimation::setFrom(qreal f)
1438 {
1439     QDeclarativePropertyAnimation::setFrom(f);
1440 }
1441
1442 /*!
1443     \qmlproperty real QtQuick2::RotationAnimation::to
1444     This property holds the end value for the animation..
1445
1446     If the RotationAnimation is defined within a \l Transition or \l Behavior,
1447     this value defaults to the value defined in the end state of the
1448     \l Transition, or the value of the property change that triggered the
1449     \l Behavior.
1450
1451     \sa {QML Animation and Transitions}
1452 */
1453 qreal QDeclarativeRotationAnimation::to() const
1454 {
1455     Q_D(const QDeclarativeRotationAnimation);
1456     return d->to.toReal();
1457 }
1458
1459 void QDeclarativeRotationAnimation::setTo(qreal t)
1460 {
1461     QDeclarativePropertyAnimation::setTo(t);
1462 }
1463
1464 /*!
1465     \qmlproperty enumeration QtQuick2::RotationAnimation::direction
1466     This property holds the direction of the rotation.
1467
1468     Possible values are:
1469
1470     \list
1471     \o RotationAnimation.Numerical (default) - Rotate by linearly interpolating between the two numbers.
1472            A rotation from 10 to 350 will rotate 340 degrees clockwise.
1473     \o RotationAnimation.Clockwise - Rotate clockwise between the two values
1474     \o RotationAnimation.Counterclockwise - Rotate counterclockwise between the two values
1475     \o RotationAnimation.Shortest - Rotate in the direction that produces the shortest animation path.
1476            A rotation from 10 to 350 will rotate 20 degrees counterclockwise.
1477     \endlist
1478 */
1479 QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const
1480 {
1481     Q_D(const QDeclarativeRotationAnimation);
1482     return d->direction;
1483 }
1484
1485 void QDeclarativeRotationAnimation::setDirection(QDeclarativeRotationAnimation::RotationDirection direction)
1486 {
1487     Q_D(QDeclarativeRotationAnimation);
1488     if (d->direction == direction)
1489         return;
1490
1491     d->direction = direction;
1492     switch(d->direction) {
1493     case Clockwise:
1494         d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateClockwiseRotation);
1495         break;
1496     case Counterclockwise:
1497         d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateCounterclockwiseRotation);
1498         break;
1499     case Shortest:
1500         d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateShortestRotation);
1501         break;
1502     default:
1503         d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
1504         break;
1505     }
1506
1507     emit directionChanged();
1508 }
1509
1510
1511
1512 QDeclarativeAnimationGroup::QDeclarativeAnimationGroup(QObject *parent)
1513 : QDeclarativeAbstractAnimation(*(new QDeclarativeAnimationGroupPrivate), parent)
1514 {
1515 }
1516
1517 QDeclarativeAnimationGroup::QDeclarativeAnimationGroup(QDeclarativeAnimationGroupPrivate &dd, QObject *parent)
1518     : QDeclarativeAbstractAnimation(dd, parent)
1519 {
1520 }
1521
1522 void QDeclarativeAnimationGroupPrivate::append_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list, QDeclarativeAbstractAnimation *a)
1523 {
1524     QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object);
1525     if (q) {
1526         a->setGroup(q);
1527         // This is an optimization for the parenting that already occurs via addAnimation
1528         QDeclarative_setParent_noEvent(a->qtAnimation(), q->d_func()->ag);
1529         q->d_func()->ag->addAnimation(a->qtAnimation());
1530     }
1531 }
1532
1533 void QDeclarativeAnimationGroupPrivate::clear_animation(QDeclarativeListProperty<QDeclarativeAbstractAnimation> *list)
1534 {
1535     QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object);
1536     if (q) {
1537         while (q->d_func()->animations.count()) {
1538             QDeclarativeAbstractAnimation *firstAnim = q->d_func()->animations.at(0);
1539             QDeclarative_setParent_noEvent(firstAnim->qtAnimation(), 0);
1540             q->d_func()->ag->removeAnimation(firstAnim->qtAnimation());
1541             firstAnim->setGroup(0);
1542         }
1543     }
1544 }
1545
1546 QDeclarativeAnimationGroup::~QDeclarativeAnimationGroup()
1547 {
1548 }
1549
1550 QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeAnimationGroup::animations()
1551 {
1552     Q_D(QDeclarativeAnimationGroup);
1553     QDeclarativeListProperty<QDeclarativeAbstractAnimation> list(this, d->animations);
1554     list.append = &QDeclarativeAnimationGroupPrivate::append_animation;
1555     list.clear = &QDeclarativeAnimationGroupPrivate::clear_animation;
1556     return list;
1557 }
1558
1559 /*!
1560     \qmlclass SequentialAnimation QDeclarativeSequentialAnimation
1561     \inqmlmodule QtQuick 2
1562   \ingroup qml-animation-transition
1563     \inherits Animation
1564     \brief The SequentialAnimation element allows animations to be run sequentially.
1565
1566     The SequentialAnimation and ParallelAnimation elements allow multiple
1567     animations to be run together. Animations defined in a SequentialAnimation
1568     are run one after the other, while animations defined in a ParallelAnimation
1569     are run at the same time.
1570
1571     The following example runs two number animations in a sequence.  The \l Rectangle
1572     animates to a \c x position of 50, then to a \c y position of 50.
1573
1574     \snippet doc/src/snippets/declarative/sequentialanimation.qml 0
1575
1576     Animations defined within a \l Transition are automatically run in parallel,
1577     so SequentialAnimation can be used to enclose the animations in a \l Transition
1578     if this is the preferred behavior.
1579
1580     Like any other animation element, a SequentialAnimation can be applied in a
1581     number of ways, including transitions, behaviors and property value
1582     sources. The \l {QML Animation and Transitions} documentation shows a
1583     variety of methods for creating animations.
1584
1585     \note Once an animation has been grouped into a SequentialAnimation or
1586     ParallelAnimation, it cannot be individually started and stopped; the
1587     SequentialAnimation or ParallelAnimation must be started and stopped as a group.
1588
1589     \sa ParallelAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1590 */
1591
1592 QDeclarativeSequentialAnimation::QDeclarativeSequentialAnimation(QObject *parent) :
1593     QDeclarativeAnimationGroup(parent)
1594 {
1595     Q_D(QDeclarativeAnimationGroup);
1596     d->ag = new QSequentialAnimationGroup;
1597     QDeclarative_setParent_noEvent(d->ag, this);
1598 }
1599
1600 QDeclarativeSequentialAnimation::~QDeclarativeSequentialAnimation()
1601 {
1602 }
1603
1604 QAbstractAnimation *QDeclarativeSequentialAnimation::qtAnimation()
1605 {
1606     Q_D(QDeclarativeAnimationGroup);
1607     return d->ag;
1608 }
1609
1610 void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actions,
1611                                     QDeclarativeProperties &modified,
1612                                     TransitionDirection direction)
1613 {
1614     Q_D(QDeclarativeAnimationGroup);
1615
1616     int inc = 1;
1617     int from = 0;
1618     if (direction == Backward) {
1619         inc = -1;
1620         from = d->animations.count() - 1;
1621     }
1622
1623     bool valid = d->defaultProperty.isValid();
1624     for (int ii = from; ii < d->animations.count() && ii >= 0; ii += inc) {
1625         if (valid)
1626             d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
1627         d->animations.at(ii)->transition(actions, modified, direction);
1628     }
1629 }
1630
1631
1632
1633 /*!
1634     \qmlclass ParallelAnimation QDeclarativeParallelAnimation
1635     \inqmlmodule QtQuick 2
1636   \ingroup qml-animation-transition
1637     \inherits Animation
1638     \brief The ParallelAnimation element allows animations to be run in parallel.
1639
1640     The SequentialAnimation and ParallelAnimation elements allow multiple
1641     animations to be run together. Animations defined in a SequentialAnimation
1642     are run one after the other, while animations defined in a ParallelAnimation
1643     are run at the same time.
1644
1645     The following animation runs two number animations in parallel. The \l Rectangle
1646     moves to (50,50) by animating its \c x and \c y properties at the same time.
1647
1648     \snippet doc/src/snippets/declarative/parallelanimation.qml 0
1649
1650     Like any other animation element, a ParallelAnimation can be applied in a
1651     number of ways, including transitions, behaviors and property value
1652     sources. The \l {QML Animation and Transitions} documentation shows a
1653     variety of methods for creating animations.
1654
1655     \note Once an animation has been grouped into a SequentialAnimation or
1656     ParallelAnimation, it cannot be individually started and stopped; the
1657     SequentialAnimation or ParallelAnimation must be started and stopped as a group.
1658
1659     \sa SequentialAnimation, {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1660 */
1661 QDeclarativeParallelAnimation::QDeclarativeParallelAnimation(QObject *parent) :
1662     QDeclarativeAnimationGroup(parent)
1663 {
1664     Q_D(QDeclarativeAnimationGroup);
1665     d->ag = new QParallelAnimationGroup;
1666     QDeclarative_setParent_noEvent(d->ag, this);
1667 }
1668
1669 QDeclarativeParallelAnimation::~QDeclarativeParallelAnimation()
1670 {
1671 }
1672
1673 QAbstractAnimation *QDeclarativeParallelAnimation::qtAnimation()
1674 {
1675     Q_D(QDeclarativeAnimationGroup);
1676     return d->ag;
1677 }
1678
1679 void QDeclarativeParallelAnimation::transition(QDeclarativeStateActions &actions,
1680                                       QDeclarativeProperties &modified,
1681                                       TransitionDirection direction)
1682 {
1683     Q_D(QDeclarativeAnimationGroup);
1684     bool valid = d->defaultProperty.isValid();
1685     for (int ii = 0; ii < d->animations.count(); ++ii) {
1686         if (valid)
1687             d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
1688         d->animations.at(ii)->transition(actions, modified, direction);
1689     }
1690 }
1691
1692
1693
1694 //convert a variant from string type to another animatable type
1695 void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
1696 {
1697     if (variant.userType() != QVariant::String) {
1698         variant.convert((QVariant::Type)type);
1699         return;
1700     }
1701
1702     switch (type) {
1703     case QVariant::Rect: {
1704         variant.setValue(QDeclarativeStringConverters::rectFFromString(variant.toString()).toRect());
1705         break;
1706     }
1707     case QVariant::RectF: {
1708         variant.setValue(QDeclarativeStringConverters::rectFFromString(variant.toString()));
1709         break;
1710     }
1711     case QVariant::Point: {
1712         variant.setValue(QDeclarativeStringConverters::pointFFromString(variant.toString()).toPoint());
1713         break;
1714     }
1715     case QVariant::PointF: {
1716         variant.setValue(QDeclarativeStringConverters::pointFFromString(variant.toString()));
1717         break;
1718     }
1719     case QVariant::Size: {
1720         variant.setValue(QDeclarativeStringConverters::sizeFFromString(variant.toString()).toSize());
1721         break;
1722     }
1723     case QVariant::SizeF: {
1724         variant.setValue(QDeclarativeStringConverters::sizeFFromString(variant.toString()));
1725         break;
1726     }
1727     case QVariant::Color: {
1728         variant.setValue(QDeclarativeStringConverters::colorFromString(variant.toString()));
1729         break;
1730     }
1731     case QVariant::Vector3D: {
1732         variant.setValue(QDeclarativeStringConverters::vector3DFromString(variant.toString()));
1733         break;
1734     }
1735     default:
1736         if (QDeclarativeValueTypeFactory::isValueType((uint)type)) {
1737             variant.convert((QVariant::Type)type);
1738         } else {
1739             QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
1740             if (converter)
1741                 variant = converter(variant.toString());
1742         }
1743         break;
1744     }
1745 }
1746
1747 /*!
1748     \qmlclass PropertyAnimation QDeclarativePropertyAnimation
1749     \inqmlmodule QtQuick 2
1750   \ingroup qml-animation-transition
1751     \inherits Animation
1752     \brief The PropertyAnimation element animates changes in property values.
1753
1754     PropertyAnimation provides a way to animate changes to a property's value.
1755
1756     It can be used to define animations in a number of ways:
1757
1758     \list
1759     \o In a \l Transition
1760
1761     For example, to animate any objects that have changed their \c x or \c y properties
1762     as a result of a state change, using an \c InOutQuad easing curve:
1763
1764     \snippet doc/src/snippets/declarative/propertyanimation.qml transition
1765
1766
1767     \o In a \l Behavior
1768
1769     For example, to animate all changes to a rectangle's \c x property:
1770
1771     \snippet doc/src/snippets/declarative/propertyanimation.qml behavior
1772
1773
1774     \o As a property value source
1775
1776     For example, to repeatedly animate the rectangle's \c x property:
1777
1778     \snippet doc/src/snippets/declarative/propertyanimation.qml propertyvaluesource
1779
1780
1781     \o In a signal handler
1782
1783     For example, to fade out \c theObject when clicked:
1784     \qml
1785     MouseArea {
1786         anchors.fill: theObject
1787         onClicked: PropertyAnimation { target: theObject; property: "opacity"; to: 0 }
1788     }
1789     \endqml
1790
1791     \o Standalone
1792
1793     For example, to animate \c rect's \c width property over 500ms, from its current width to 30:
1794
1795     \snippet doc/src/snippets/declarative/propertyanimation.qml standalone
1796
1797     \endlist
1798
1799     Depending on how the animation is used, the set of properties normally used will be
1800     different. For more information see the individual property documentation, as well
1801     as the \l{QML Animation and Transitions} introduction.
1802
1803     Note that PropertyAnimation inherits the abstract \l Animation element.
1804     This includes additional properties and methods for controlling the animation.
1805
1806     \sa {QML Animation and Transitions}, {declarative/animation/basics}{Animation basics example}
1807 */
1808
1809 QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QObject *parent)
1810 : QDeclarativeAbstractAnimation(*(new QDeclarativePropertyAnimationPrivate), parent)
1811 {
1812     Q_D(QDeclarativePropertyAnimation);
1813     d->init();
1814 }
1815
1816 QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent)
1817 : QDeclarativeAbstractAnimation(dd, parent)
1818 {
1819     Q_D(QDeclarativePropertyAnimation);
1820     d->init();
1821 }
1822
1823 QDeclarativePropertyAnimation::~QDeclarativePropertyAnimation()
1824 {
1825 }
1826
1827 void QDeclarativePropertyAnimationPrivate::init()
1828 {
1829     Q_Q(QDeclarativePropertyAnimation);
1830     va = new QDeclarativeBulkValueAnimator;
1831     QDeclarative_setParent_noEvent(va, q);
1832 }
1833
1834 /*!
1835     \qmlproperty int QtQuick2::PropertyAnimation::duration
1836     This property holds the duration of the animation, in milliseconds.
1837
1838     The default value is 250.
1839 */
1840 int QDeclarativePropertyAnimation::duration() const
1841 {
1842     Q_D(const QDeclarativePropertyAnimation);
1843     return d->va->duration();
1844 }
1845
1846 void QDeclarativePropertyAnimation::setDuration(int duration)
1847 {
1848     if (duration < 0) {
1849         qmlInfo(this) << tr("Cannot set a duration of < 0");
1850         return;
1851     }
1852
1853     Q_D(QDeclarativePropertyAnimation);
1854     if (d->va->duration() == duration)
1855         return;
1856     d->va->setDuration(duration);
1857     emit durationChanged(duration);
1858 }
1859
1860 /*!
1861     \qmlproperty real QtQuick2::PropertyAnimation::from
1862     This property holds the starting value for the animation.
1863
1864     If the PropertyAnimation is defined within a \l Transition or \l Behavior,
1865     this value defaults to the value defined in the starting state of the
1866     \l Transition, or the current value of the property at the moment the
1867     \l Behavior is triggered.
1868
1869     \sa {QML Animation and Transitions}
1870 */
1871 QVariant QDeclarativePropertyAnimation::from() const
1872 {
1873     Q_D(const QDeclarativePropertyAnimation);
1874     return d->from;
1875 }
1876
1877 void QDeclarativePropertyAnimation::setFrom(const QVariant &f)
1878 {
1879     Q_D(QDeclarativePropertyAnimation);
1880     if (d->fromIsDefined && f == d->from)
1881         return;
1882     d->from = f;
1883     d->fromIsDefined = f.isValid();
1884     emit fromChanged(f);
1885 }
1886
1887 /*!
1888     \qmlproperty real QtQuick2::PropertyAnimation::to
1889     This property holds the end value for the animation.
1890
1891     If the PropertyAnimation is defined within a \l Transition or \l Behavior,
1892     this value defaults to the value defined in the end state of the
1893     \l Transition, or the value of the property change that triggered the
1894     \l Behavior.
1895
1896     \sa {QML Animation and Transitions}
1897 */
1898 QVariant QDeclarativePropertyAnimation::to() const
1899 {
1900     Q_D(const QDeclarativePropertyAnimation);
1901     return d->to;
1902 }
1903
1904 void QDeclarativePropertyAnimation::setTo(const QVariant &t)
1905 {
1906     Q_D(QDeclarativePropertyAnimation);
1907     if (d->toIsDefined && t == d->to)
1908         return;
1909     d->to = t;
1910     d->toIsDefined = t.isValid();
1911     emit toChanged(t);
1912 }
1913
1914 /*!
1915     \qmlproperty enumeration QtQuick2::PropertyAnimation::easing.type
1916     \qmlproperty real QtQuick2::PropertyAnimation::easing.amplitude
1917     \qmlproperty real QtQuick2::PropertyAnimation::easing.overshoot
1918     \qmlproperty real QtQuick2::PropertyAnimation::easing.period
1919     \qmlproperty list<real> QtQuick2::PropertyAnimation::easing.bezierCurve
1920     \brief the easing curve used for the animation.
1921
1922     To specify an easing curve you need to specify at least the type. For some curves you can also specify
1923     amplitude, period and/or overshoot (more details provided after the table). The default easing curve is
1924     \c Easing.Linear.
1925
1926     \qml
1927     PropertyAnimation { properties: "y"; easing.type: Easing.InOutElastic; easing.amplitude: 2.0; easing.period: 1.5 }
1928     \endqml
1929
1930     Available types are:
1931
1932     \table
1933     \row
1934         \o \c Easing.Linear
1935         \o Easing curve for a linear (t) function: velocity is constant.
1936         \o \inlineimage qeasingcurve-linear.png
1937     \row
1938         \o \c Easing.InQuad
1939         \o Easing curve for a quadratic (t^2) function: accelerating from zero velocity.
1940         \o \inlineimage qeasingcurve-inquad.png
1941     \row
1942         \o \c Easing.OutQuad
1943         \o Easing curve for a quadratic (t^2) function: decelerating to zero velocity.
1944         \o \inlineimage qeasingcurve-outquad.png
1945     \row
1946         \o \c Easing.InOutQuad
1947         \o Easing curve for a quadratic (t^2) function: acceleration until halfway, then deceleration.
1948         \o \inlineimage qeasingcurve-inoutquad.png
1949     \row
1950         \o \c Easing.OutInQuad
1951         \o Easing curve for a quadratic (t^2) function: deceleration until halfway, then acceleration.
1952         \o \inlineimage qeasingcurve-outinquad.png
1953     \row
1954         \o \c Easing.InCubic
1955         \o Easing curve for a cubic (t^3) function: accelerating from zero velocity.
1956         \o \inlineimage qeasingcurve-incubic.png
1957     \row
1958         \o \c Easing.OutCubic
1959         \o Easing curve for a cubic (t^3) function: decelerating from zero velocity.
1960         \o \inlineimage qeasingcurve-outcubic.png
1961     \row
1962         \o \c Easing.InOutCubic
1963         \o Easing curve for a cubic (t^3) function: acceleration until halfway, then deceleration.
1964         \o \inlineimage qeasingcurve-inoutcubic.png
1965     \row
1966         \o \c Easing.OutInCubic
1967         \o Easing curve for a cubic (t^3) function: deceleration until halfway, then acceleration.
1968         \o \inlineimage qeasingcurve-outincubic.png
1969     \row
1970         \o \c Easing.InQuart
1971         \o Easing curve for a quartic (t^4) function: accelerating from zero velocity.
1972         \o \inlineimage qeasingcurve-inquart.png
1973     \row
1974         \o \c Easing.OutQuart
1975         \o Easing curve for a quartic (t^4) function: decelerating from zero velocity.
1976         \o \inlineimage qeasingcurve-outquart.png
1977     \row
1978         \o \c Easing.InOutQuart
1979         \o Easing curve for a quartic (t^4) function: acceleration until halfway, then deceleration.
1980         \o \inlineimage qeasingcurve-inoutquart.png
1981     \row
1982         \o \c Easing.OutInQuart
1983         \o Easing curve for a quartic (t^4) function: deceleration until halfway, then acceleration.
1984         \o \inlineimage qeasingcurve-outinquart.png
1985     \row
1986         \o \c Easing.InQuint
1987         \o Easing curve for a quintic (t^5) function: accelerating from zero velocity.
1988         \o \inlineimage qeasingcurve-inquint.png
1989     \row
1990         \o \c Easing.OutQuint
1991         \o Easing curve for a quintic (t^5) function: decelerating from zero velocity.
1992         \o \inlineimage qeasingcurve-outquint.png
1993     \row
1994         \o \c Easing.InOutQuint
1995         \o Easing curve for a quintic (t^5) function: acceleration until halfway, then deceleration.
1996         \o \inlineimage qeasingcurve-inoutquint.png
1997     \row
1998         \o \c Easing.OutInQuint
1999         \o Easing curve for a quintic (t^5) function: deceleration until halfway, then acceleration.
2000         \o \inlineimage qeasingcurve-outinquint.png
2001     \row
2002         \o \c Easing.InSine
2003         \o Easing curve for a sinusoidal (sin(t)) function: accelerating from zero velocity.
2004         \o \inlineimage qeasingcurve-insine.png
2005     \row
2006         \o \c Easing.OutSine
2007         \o Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity.
2008         \o \inlineimage qeasingcurve-outsine.png
2009     \row
2010         \o \c Easing.InOutSine
2011         \o Easing curve for a sinusoidal (sin(t)) function: acceleration until halfway, then deceleration.
2012         \o \inlineimage qeasingcurve-inoutsine.png
2013     \row
2014         \o \c Easing.OutInSine
2015         \o Easing curve for a sinusoidal (sin(t)) function: deceleration until halfway, then acceleration.
2016         \o \inlineimage qeasingcurve-outinsine.png
2017     \row
2018         \o \c Easing.InExpo
2019         \o Easing curve for an exponential (2^t) function: accelerating from zero velocity.
2020         \o \inlineimage qeasingcurve-inexpo.png
2021     \row
2022         \o \c Easing.OutExpo
2023         \o Easing curve for an exponential (2^t) function: decelerating from zero velocity.
2024         \o \inlineimage qeasingcurve-outexpo.png
2025     \row
2026         \o \c Easing.InOutExpo
2027         \o Easing curve for an exponential (2^t) function: acceleration until halfway, then deceleration.
2028         \o \inlineimage qeasingcurve-inoutexpo.png
2029     \row
2030         \o \c Easing.OutInExpo
2031         \o Easing curve for an exponential (2^t) function: deceleration until halfway, then acceleration.
2032         \o \inlineimage qeasingcurve-outinexpo.png
2033     \row
2034         \o \c Easing.InCirc
2035         \o Easing curve for a circular (sqrt(1-t^2)) function: accelerating from zero velocity.
2036         \o \inlineimage qeasingcurve-incirc.png
2037     \row
2038         \o \c Easing.OutCirc
2039         \o Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity.
2040         \o \inlineimage qeasingcurve-outcirc.png
2041     \row
2042         \o \c Easing.InOutCirc
2043         \o Easing curve for a circular (sqrt(1-t^2)) function: acceleration until halfway, then deceleration.
2044         \o \inlineimage qeasingcurve-inoutcirc.png
2045     \row
2046         \o \c Easing.OutInCirc
2047         \o Easing curve for a circular (sqrt(1-t^2)) function: deceleration until halfway, then acceleration.
2048         \o \inlineimage qeasingcurve-outincirc.png
2049     \row
2050         \o \c Easing.InElastic
2051         \o Easing curve for an elastic (exponentially decaying sine wave) function: accelerating from zero velocity.
2052         \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter.
2053         \o \inlineimage qeasingcurve-inelastic.png
2054     \row
2055         \o \c Easing.OutElastic
2056         \o Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity.
2057         \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter.
2058         \o \inlineimage qeasingcurve-outelastic.png
2059     \row
2060         \o \c Easing.InOutElastic
2061         \o Easing curve for an elastic (exponentially decaying sine wave) function: acceleration until halfway, then deceleration.
2062         \o \inlineimage qeasingcurve-inoutelastic.png
2063     \row
2064         \o \c Easing.OutInElastic
2065         \o Easing curve for an elastic (exponentially decaying sine wave) function: deceleration until halfway, then acceleration.
2066         \o \inlineimage qeasingcurve-outinelastic.png
2067     \row
2068         \o \c Easing.InBack
2069         \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity.
2070         \o \inlineimage qeasingcurve-inback.png
2071     \row
2072         \o \c Easing.OutBack
2073         \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity.
2074         \o \inlineimage qeasingcurve-outback.png
2075     \row
2076         \o \c Easing.InOutBack
2077         \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration.
2078         \o \inlineimage qeasingcurve-inoutback.png
2079     \row
2080         \o \c Easing.OutInBack
2081         \o Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration.
2082         \o \inlineimage qeasingcurve-outinback.png
2083     \row
2084         \o \c Easing.InBounce
2085         \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: accelerating from zero velocity.
2086         \o \inlineimage qeasingcurve-inbounce.png
2087     \row
2088         \o \c Easing.OutBounce
2089         \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity.
2090         \o \inlineimage qeasingcurve-outbounce.png
2091     \row
2092         \o \c Easing.InOutBounce
2093         \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration.
2094         \o \inlineimage qeasingcurve-inoutbounce.png
2095     \row
2096         \o \c Easing.OutInBounce
2097         \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration.
2098         \o \inlineimage qeasingcurve-outinbounce.png
2099     \row
2100         \o \c Easing.Bezier
2101         \o Custom easing curve defined by the easing.bezierCurve property.
2102         \o
2103     \endtable
2104
2105     \c easing.amplitude is only applicable for bounce and elastic curves (curves of type
2106     \c Easing.InBounce, \c Easing.OutBounce, \c Easing.InOutBounce, \c Easing.OutInBounce, \c Easing.InElastic,
2107     \c Easing.OutElastic, \c Easing.InOutElastic or \c Easing.OutInElastic).
2108
2109     \c easing.overshoot is only applicable if \c easing.type is: \c Easing.InBack, \c Easing.OutBack,
2110     \c Easing.InOutBack or \c Easing.OutInBack.
2111
2112     \c easing.period is only applicable if easing.type is: \c Easing.InElastic, \c Easing.OutElastic,
2113     \c Easing.InOutElastic or \c Easing.OutInElastic.
2114
2115     \c easing.bezierCurve is only applicable if easing.type is: \c Easing.Bezier.  This property is a list<real> containing
2116     groups of three points defining a curve from 0,0 to 1,1 - control1, control2,
2117     end point: [cx1, cy1, cx2, cy2, endx, endy, ...].  The last point must be 1,1.
2118
2119     See the \l {declarative/animation/easing}{easing} example for a demonstration of
2120     the different easing settings.
2121 */
2122 QEasingCurve QDeclarativePropertyAnimation::easing() const
2123 {
2124     Q_D(const QDeclarativePropertyAnimation);
2125     return d->va->easingCurve();
2126 }
2127
2128 void QDeclarativePropertyAnimation::setEasing(const QEasingCurve &e)
2129 {
2130     Q_D(QDeclarativePropertyAnimation);
2131     if (d->va->easingCurve() == e)
2132         return;
2133
2134     d->va->setEasingCurve(e);
2135     emit easingChanged(e);
2136 }
2137
2138 QObject *QDeclarativePropertyAnimation::target() const
2139 {
2140     Q_D(const QDeclarativePropertyAnimation);
2141     return d->target;
2142 }
2143
2144 void QDeclarativePropertyAnimation::setTarget(QObject *o)
2145 {
2146     Q_D(QDeclarativePropertyAnimation);
2147     if (d->target == o)
2148         return;
2149     d->target = o;
2150     emit targetChanged();
2151 }
2152
2153 QString QDeclarativePropertyAnimation::property() const
2154 {
2155     Q_D(const QDeclarativePropertyAnimation);
2156     return d->propertyName;
2157 }
2158
2159 void QDeclarativePropertyAnimation::setProperty(const QString &n)
2160 {
2161     Q_D(QDeclarativePropertyAnimation);
2162     if (d->propertyName == n)
2163         return;
2164     d->propertyName = n;
2165     emit propertyChanged();
2166 }
2167
2168 QString QDeclarativePropertyAnimation::properties() const
2169 {
2170     Q_D(const QDeclarativePropertyAnimation);
2171     return d->properties;
2172 }
2173
2174 void QDeclarativePropertyAnimation::setProperties(const QString &prop)
2175 {
2176     Q_D(QDeclarativePropertyAnimation);
2177     if (d->properties == prop)
2178         return;
2179
2180     d->properties = prop;
2181     emit propertiesChanged(prop);
2182 }
2183
2184 /*!
2185     \qmlproperty string QtQuick2::PropertyAnimation::properties
2186     \qmlproperty list<Object> QtQuick2::PropertyAnimation::targets
2187     \qmlproperty string QtQuick2::PropertyAnimation::property
2188     \qmlproperty Object QtQuick2::PropertyAnimation::target
2189
2190     These properties are used as a set to determine which properties should be animated.
2191     The singular and plural forms are functionally identical, e.g.
2192     \qml
2193     NumberAnimation { target: theItem; property: "x"; to: 500 }
2194     \endqml
2195     has the same meaning as
2196     \qml
2197     NumberAnimation { targets: theItem; properties: "x"; to: 500 }
2198     \endqml
2199     The singular forms are slightly optimized, so if you do have only a single target/property
2200     to animate you should try to use them.
2201
2202     The \c targets property allows multiple targets to be set. For example, this animates the
2203     \c x property of both \c itemA and \c itemB:
2204
2205     \qml
2206     NumberAnimation { targets: [itemA, itemB]; properties: "x"; to: 500 }
2207     \endqml
2208
2209     In many cases these properties do not need to be explicitly specified, as they can be
2210     inferred from the animation framework:
2211
2212     \table 80%
2213     \row
2214     \o Value Source / Behavior
2215     \o When an animation is used as a value source or in a Behavior, the default target and property
2216        name to be animated can both be inferred.
2217        \qml
2218        Rectangle {
2219            id: theRect
2220            width: 100; height: 100
2221            color: Qt.rgba(0,0,1)
2222            NumberAnimation on x { to: 500; loops: Animation.Infinite } //animate theRect's x property
2223            Behavior on y { NumberAnimation {} } //animate theRect's y property
2224        }
2225        \endqml
2226     \row
2227     \o Transition
2228     \o When used in a transition, a property animation is assumed to match \e all targets
2229        but \e no properties. In practice, that means you need to specify at least the properties
2230        in order for the animation to do anything.
2231        \qml
2232        Rectangle {
2233            id: theRect
2234            width: 100; height: 100
2235            color: Qt.rgba(0,0,1)
2236            Item { id: uselessItem }
2237            states: State {
2238                name: "state1"
2239                PropertyChanges { target: theRect; x: 200; y: 200; z: 4 }
2240                PropertyChanges { target: uselessItem; x: 10; y: 10; z: 2 }
2241            }
2242            transitions: Transition {
2243                //animate both theRect's and uselessItem's x and y to their final values
2244                NumberAnimation { properties: "x,y" }
2245
2246                //animate theRect's z to its final value
2247                NumberAnimation { target: theRect; property: "z" }
2248            }
2249        }
2250        \endqml
2251     \row
2252     \o Standalone
2253     \o When an animation is used standalone, both the target and property need to be
2254        explicitly specified.
2255        \qml
2256        Rectangle {
2257            id: theRect
2258            width: 100; height: 100
2259            color: Qt.rgba(0,0,1)
2260            //need to explicitly specify target and property
2261            NumberAnimation { id: theAnim; target: theRect; property: "x"; to: 500 }
2262            MouseArea {
2263                anchors.fill: parent
2264                onClicked: theAnim.start()
2265            }
2266        }
2267        \endqml
2268     \endtable
2269
2270     As seen in the above example, properties is specified as a comma-separated string of property names to animate.
2271
2272     \sa exclude, {QML Animation and Transitions}
2273 */
2274 QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::targets()
2275 {
2276     Q_D(QDeclarativePropertyAnimation);
2277     return QDeclarativeListProperty<QObject>(this, d->targets);
2278 }
2279
2280 /*!
2281     \qmlproperty list<Object> QtQuick2::PropertyAnimation::exclude
2282     This property holds the items not to be affected by this animation.
2283     \sa PropertyAnimation::targets
2284 */
2285 QDeclarativeListProperty<QObject> QDeclarativePropertyAnimation::exclude()
2286 {
2287     Q_D(QDeclarativePropertyAnimation);
2288     return QDeclarativeListProperty<QObject>(this, d->exclude);
2289 }
2290
2291 QAbstractAnimation *QDeclarativePropertyAnimation::qtAnimation()
2292 {
2293     Q_D(QDeclarativePropertyAnimation);
2294     return d->va;
2295 }
2296
2297 void QDeclarativeAnimationPropertyUpdater::setValue(qreal v)
2298 {
2299     bool deleted = false;
2300     wasDeleted = &deleted;
2301     if (reverse)    //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1
2302         v = 1 - v;
2303     for (int ii = 0; ii < actions.count(); ++ii) {
2304         QDeclarativeAction &action = actions[ii];
2305
2306         if (v == 1.)
2307             QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
2308         else {
2309             if (!fromSourced && !fromDefined) {
2310                 action.fromValue = action.property.read();
2311                 if (interpolatorType)
2312                     QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType);
2313             }
2314             if (!interpolatorType) {
2315                 int propType = action.property.propertyType();
2316                 if (!prevInterpolatorType || prevInterpolatorType != propType) {
2317                     prevInterpolatorType = propType;
2318                     interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType);
2319                 }
2320             }
2321             if (interpolator)
2322                 QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
2323         }
2324         if (deleted)
2325             return;
2326     }
2327     wasDeleted = 0;
2328     fromSourced = true;
2329 }
2330
2331 void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions,
2332                                      QDeclarativeProperties &modified,
2333                                      TransitionDirection direction)
2334 {
2335     Q_D(QDeclarativePropertyAnimation);
2336
2337     QStringList props = d->properties.isEmpty() ? QStringList() : d->properties.split(QLatin1Char(','));
2338     for (int ii = 0; ii < props.count(); ++ii)
2339         props[ii] = props.at(ii).trimmed();
2340     if (!d->propertyName.isEmpty())
2341         props << d->propertyName;
2342
2343     QList<QObject*> targets = d->targets;
2344     if (d->target)
2345         targets.append(d->target);
2346
2347     bool hasSelectors = !props.isEmpty() || !targets.isEmpty() || !d->exclude.isEmpty();
2348     bool useType = (props.isEmpty() && d->defaultToInterpolatorType) ? true : false;
2349
2350     if (d->defaultProperty.isValid() && !hasSelectors) {
2351         props << d->defaultProperty.name();
2352         targets << d->defaultProperty.object();
2353     }
2354
2355     if (props.isEmpty() && !d->defaultProperties.isEmpty()) {
2356         props << d->defaultProperties.split(QLatin1Char(','));
2357     }
2358
2359     QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater;
2360     data->interpolatorType = d->interpolatorType;
2361     data->interpolator = d->interpolator;
2362     data->reverse = direction == Backward ? true : false;
2363     data->fromSourced = false;
2364     data->fromDefined = d->fromIsDefined;
2365
2366     bool hasExplicit = false;
2367     //an explicit animation has been specified
2368     if (d->toIsDefined) {
2369         for (int i = 0; i < props.count(); ++i) {
2370             for (int j = 0; j < targets.count(); ++j) {
2371                 QDeclarativeAction myAction;
2372                 myAction.property = d->createProperty(targets.at(j), props.at(i), this);
2373                 if (myAction.property.isValid()) {
2374                     if (d->fromIsDefined) {
2375                         myAction.fromValue = d->from;
2376                         d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2377                     }
2378                     myAction.toValue = d->to;
2379                     d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2380                     data->actions << myAction;
2381                     hasExplicit = true;
2382                     for (int ii = 0; ii < actions.count(); ++ii) {
2383                         QDeclarativeAction &action = actions[ii];
2384                         if (action.property.object() == myAction.property.object() &&
2385                             myAction.property.name() == action.property.name()) {
2386                             modified << action.property;
2387                             break;  //### any chance there could be multiples?
2388                         }
2389                     }
2390                 }
2391             }
2392         }
2393     }
2394
2395     if (!hasExplicit)
2396     for (int ii = 0; ii < actions.count(); ++ii) {
2397         QDeclarativeAction &action = actions[ii];
2398
2399         QObject *obj = action.property.object();
2400         QString propertyName = action.property.name();
2401         QObject *sObj = action.specifiedObject;
2402         QString sPropertyName = action.specifiedProperty;
2403         bool same = (obj == sObj);
2404
2405         if ((targets.isEmpty() || targets.contains(obj) || (!same && targets.contains(sObj))) &&
2406            (!d->exclude.contains(obj)) && (same || (!d->exclude.contains(sObj))) &&
2407            (props.contains(propertyName) || (!same && props.contains(sPropertyName))
2408                || (useType && action.property.propertyType() == d->interpolatorType))) {
2409             QDeclarativeAction myAction = action;
2410
2411             if (d->fromIsDefined)
2412                 myAction.fromValue = d->from;
2413             else
2414                 myAction.fromValue = QVariant();
2415             if (d->toIsDefined)
2416                 myAction.toValue = d->to;
2417
2418             d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2419             d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
2420
2421             modified << action.property;
2422
2423             data->actions << myAction;
2424             action.fromValue = myAction.toValue;
2425         }
2426     }
2427
2428     if (data->actions.count()) {
2429         if (!d->rangeIsSet) {
2430             d->va->setStartValue(qreal(0));
2431             d->va->setEndValue(qreal(1));
2432             d->rangeIsSet = true;
2433         }
2434         d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
2435         d->va->setFromSourcedValue(&data->fromSourced);
2436         d->actions = &data->actions;
2437     } else {
2438         delete data;
2439         d->va->setFromSourcedValue(0);  //clear previous data
2440         d->va->setAnimValue(0, QAbstractAnimation::DeleteWhenStopped);  //clear previous data
2441         d->actions = 0;
2442     }
2443 }
2444
2445
2446 QDeclarativeScriptActionPrivate::QDeclarativeScriptActionPrivate()
2447     : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {}
2448
2449
2450 QT_END_NAMESPACE