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