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