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