969a54775b562bbe5ed63c1f3ceaaa0a27a47e0b
[profile/ivi/qtbase.git] / src / corelib / animation / qabstractanimation.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /*!
43     \class QAbstractAnimation
44     \ingroup animation
45     \brief The QAbstractAnimation class is the base of all animations.
46     \since 4.6
47
48     The class defines the functions for the functionality shared by
49     all animations. By inheriting this class, you can create custom
50     animations that plug into the rest of the animation framework.
51
52     The progress of an animation is given by its current time
53     (currentLoopTime()), which is measured in milliseconds from the start
54     of the animation (0) to its end (duration()). The value is updated
55     automatically while the animation is running. It can also be set
56     directly with setCurrentTime().
57
58     At any point an animation is in one of three states:
59     \l{QAbstractAnimation::}{Running},
60     \l{QAbstractAnimation::}{Stopped}, or
61     \l{QAbstractAnimation::}{Paused}--as defined by the
62     \l{QAbstractAnimation::}{State} enum. The current state can be
63     changed by calling start(), stop(), pause(), or resume(). An
64     animation will always reset its \l{currentTime()}{current time}
65     when it is started. If paused, it will continue with the same
66     current time when resumed. When an animation is stopped, it cannot
67     be resumed, but will keep its current time (until started again).
68     QAbstractAnimation will emit stateChanged() whenever its state
69     changes.
70
71     An animation can loop any number of times by setting the loopCount
72     property. When an animation's current time reaches its duration(),
73     it will reset the current time and keep running. A loop count of 1
74     (the default value) means that the animation will run one time.
75     Note that a duration of -1 means that the animation will run until
76     stopped; the current time will increase indefinitely. When the
77     current time equals duration() and the animation is in its
78     final loop, the \l{QAbstractAnimation::}{Stopped} state is
79     entered, and the finished() signal is emitted.
80
81     QAbstractAnimation provides pure virtual functions used by
82     subclasses to track the progress of the animation: duration() and
83     updateCurrentTime(). The duration() function lets you report a
84     duration for the animation (as discussed above). The animation
85     framework calls updateCurrentTime() when current time has changed.
86     By reimplementing this function, you can track the animation
87     progress. Note that neither the interval between calls nor the
88     number of calls to this function are defined; though, it will
89     normally be 60 updates per second.
90
91     By reimplementing updateState(), you can track the animation's
92     state changes, which is particularly useful for animations that
93     are not driven by time.
94
95     \sa QVariantAnimation, QPropertyAnimation, QAnimationGroup, {The Animation Framework}
96 */
97
98 /*!
99     \enum QAbstractAnimation::DeletionPolicy
100
101     \value KeepWhenStopped The animation will not be deleted when stopped.
102     \value DeleteWhenStopped The animation will be automatically deleted when
103     stopped.
104 */
105
106 /*!
107     \fn QAbstractAnimation::finished()
108
109     QAbstractAnimation emits this signal after the animation has stopped and
110     has reached the end.
111
112     This signal is emitted after stateChanged().
113
114     \sa stateChanged()
115 */
116
117 /*!
118     \fn QAbstractAnimation::stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
119
120     QAbstractAnimation emits this signal whenever the state of the animation has
121     changed from \a oldState to \a newState. This signal is emitted after the virtual
122     updateState() function is called.
123
124     \sa updateState()
125 */
126
127 /*!
128     \fn QAbstractAnimation::currentLoopChanged(int currentLoop)
129
130     QAbstractAnimation emits this signal whenever the current loop
131     changes. \a currentLoop is the current loop.
132
133     \sa currentLoop(), loopCount()
134 */
135
136 /*!
137     \fn QAbstractAnimation::directionChanged(QAbstractAnimation::Direction newDirection);
138
139     QAbstractAnimation emits this signal whenever the direction has been
140     changed. \a newDirection is the new direction.
141
142     \sa direction
143 */
144
145 #include "qabstractanimation.h"
146 #include "qanimationgroup.h"
147
148 #include <QtCore/qdebug.h>
149
150 #include "qabstractanimation_p.h"
151
152 #include <QtCore/qmath.h>
153 #include <QtCore/qthreadstorage.h>
154 #include <QtCore/qcoreevent.h>
155 #include <QtCore/qpointer.h>
156
157 #ifndef QT_NO_ANIMATION
158
159 #define DEFAULT_TIMER_INTERVAL 16
160 #define PAUSE_TIMER_COARSE_THRESHOLD 2000
161
162 QT_BEGIN_NAMESPACE
163
164 /*!
165   \class QAbstractAnimationTimer
166   \brief QAbstractAnimationTimer is the base class for animation timers.
167   \internal
168
169   Subclass QAbstractAnimationTimer to provide an animation timer that is run by
170   QUnifiedTimer and can in turn be used to run any number of animations.
171
172   Currently two subclasses have been implemented: QAnimationTimer to drive the Qt C++
173   animation framework (QAbstractAnimation and subclasses) and QDeclarativeAnimationTimer
174   to drive the Qt QML animation framework.
175 */
176
177 /*!
178     \fn virtual void QAbstractAnimationTimer::updateAnimationsTime(qint64 delta) = 0;
179     \internal
180
181     This pure virtual function is called when the animation timer needs to update
182     the current time for all animations it is running.
183 */
184
185 /*!
186     \fn virtual void QAbstractAnimationTimer::restartAnimationTimer() = 0;
187     \internal
188
189     This pure virtual function restarts the animation timer as needed.
190
191     Classes implementing this function may choose to pause or resume the timer
192     as appropriate, or conditionally restart it.
193 */
194
195 /*!
196     \fn virtual int QAbstractAnimationTimer::runningAnimationCount() = 0;
197     \internal
198
199     This pure virtual function returns the number of animations the timer is running.
200     This information is useful for profiling.
201 */
202
203 /*!
204     \class QUnifiedTimer
205     \brief QUnifiedTimer provides a unified timing mechanism for animations in Qt C++ and QML.
206     \internal
207
208     QUnifiedTimer allows animations run by Qt to share a single timer. This keeps animations
209     visually in sync, as well as being more efficient than running numerous timers.
210
211     QUnifiedTimer drives animations indirectly, via QAbstractAnimationTimer.
212 */
213
214 #ifndef QT_NO_THREAD
215 Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
216 #endif
217
218 QUnifiedTimer::QUnifiedTimer() :
219     QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
220     currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), slowMode(false),
221     startTimersPending(false), stopTimerPending(false),
222     slowdownFactor(5.0f), profilerCallback(0)
223 {
224     time.invalidate();
225     driver = &defaultDriver;
226 }
227
228
229 QUnifiedTimer *QUnifiedTimer::instance(bool create)
230 {
231     QUnifiedTimer *inst;
232 #ifndef QT_NO_THREAD
233     if (create && !unifiedTimer()->hasLocalData()) {
234         inst = new QUnifiedTimer;
235         unifiedTimer()->setLocalData(inst);
236     } else {
237         inst = unifiedTimer() ? unifiedTimer()->localData() : 0;
238     }
239 #else
240     static QUnifiedTimer unifiedTimer;
241     inst = &unifiedTimer;
242 #endif
243     return inst;
244 }
245
246 QUnifiedTimer *QUnifiedTimer::instance()
247 {
248     return instance(true);
249 }
250
251 void QUnifiedTimer::maybeUpdateAnimationsToCurrentTime()
252 {
253     if (time.elapsed() - lastTick > 50)
254         updateAnimationTimers(driver->elapsed());
255 }
256
257 void QUnifiedTimer::updateAnimationTimers(qint64 currentTick)
258 {
259     //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
260     if(insideTick)
261         return;
262
263     qint64 totalElapsed = currentTick >= 0 ? currentTick : time.elapsed();
264
265     // ignore consistentTiming in case the pause timer is active
266     qint64 delta = (consistentTiming && !pauseTimer.isActive()) ?
267                         timingInterval : totalElapsed - lastTick;
268     if (slowMode) {
269         if (slowdownFactor > 0)
270             delta = qRound(delta / slowdownFactor);
271         else
272             delta = 0;
273     }
274
275     lastTick = totalElapsed;
276
277     //we make sure we only call update time if the time has actually changed
278     //it might happen in some cases that the time doesn't change because events are delayed
279     //when the CPU load is high
280     if (delta) {
281         insideTick = true;
282         if (profilerCallback)
283             profilerCallback(delta);
284         for (currentAnimationIdx = 0; currentAnimationIdx < animationTimers.count(); ++currentAnimationIdx) {
285             QAbstractAnimationTimer *animation = animationTimers.at(currentAnimationIdx);
286             animation->updateAnimationsTime(delta);
287         }
288         insideTick = false;
289         currentAnimationIdx = 0;
290     }
291 }
292
293 int QUnifiedTimer::runningAnimationCount()
294 {
295     int count = 0;
296     for (int i = 0; i < animationTimers.count(); ++i)
297         count += animationTimers.at(i)->runningAnimationCount();
298     return count;
299 }
300
301 void QUnifiedTimer::registerProfilerCallback(void (*cb)(qint64))
302 {
303     profilerCallback = cb;
304 }
305
306 void QUnifiedTimer::localRestart()
307 {
308     if (insideRestart)
309         return;
310
311     if (!pausedAnimationTimers.isEmpty() && (animationTimers.count() + animationTimersToStart.count() == pausedAnimationTimers.count())) {
312         driver->stop();
313         int closestTimeToFinish = closestPausedAnimationTimerTimeToFinish();
314         // use a precise timer if the pause will be short
315         Qt::TimerType timerType = closestTimeToFinish < PAUSE_TIMER_COARSE_THRESHOLD ? Qt::PreciseTimer : Qt::CoarseTimer;
316         pauseTimer.start(closestTimeToFinish, timerType, this);
317     } else if (!driver->isRunning()) {
318         if (pauseTimer.isActive())
319             pauseTimer.stop();
320         driver->setStartTime(time.isValid() ? time.elapsed() : 0);
321         driver->start();
322     }
323
324 }
325
326 void QUnifiedTimer::restart()
327 {
328     insideRestart = true;
329     for (int i = 0; i < animationTimers.count(); ++i)
330         animationTimers.at(i)->restartAnimationTimer();
331     insideRestart = false;
332
333     localRestart();
334 }
335
336 void QUnifiedTimer::setTimingInterval(int interval)
337 {
338     timingInterval = interval;
339
340     if (driver->isRunning() && !pauseTimer.isActive()) {
341         //we changed the timing interval
342         driver->stop();
343         driver->setStartTime(time.isValid() ? time.elapsed() : 0);
344         driver->start();
345     }
346 }
347
348 void QUnifiedTimer::startTimers()
349 {
350     startTimersPending = false;
351     if (!animationTimers.isEmpty())
352         updateAnimationTimers(-1);
353
354     //we transfer the waiting animations into the "really running" state
355     animationTimers += animationTimersToStart;
356     animationTimersToStart.clear();
357     if (!animationTimers.isEmpty()) {
358         localRestart();
359         if (!time.isValid()) {
360             lastTick = 0;
361             time.start();
362         }
363     }
364 }
365
366 void QUnifiedTimer::stopTimer()
367 {
368     stopTimerPending = false;
369     if (animationTimers.isEmpty()) {
370         driver->stop();
371         pauseTimer.stop();
372         // invalidate the start reference time
373         time.invalidate();
374     }
375 }
376
377 void QUnifiedTimer::timerEvent(QTimerEvent *event)
378 {
379     //in the case of consistent timing we make sure the order in which events come is always the same
380     //for that purpose we do as if the startstoptimer would always fire before the animation timer
381     if (consistentTiming) {
382         if (stopTimerPending)
383             stopTimer();
384         if (startTimersPending)
385             startTimers();
386     }
387
388     if (event->timerId() == pauseTimer.timerId()) {
389         // update current time on all timers
390         updateAnimationTimers(-1);
391         restart();
392     }
393 }
394
395 void QUnifiedTimer::startAnimationTimer(QAbstractAnimationTimer *timer)
396 {
397     if (timer->isRegistered)
398         return;
399     timer->isRegistered = true;
400
401     QUnifiedTimer *inst = instance(true); //we create the instance if needed
402     inst->animationTimersToStart << timer;
403     if (!inst->startTimersPending) {
404         inst->startTimersPending = true;
405         QMetaObject::invokeMethod(inst, "startTimers", Qt::QueuedConnection);
406     }
407 }
408
409 void QUnifiedTimer::stopAnimationTimer(QAbstractAnimationTimer *timer)
410 {
411     QUnifiedTimer *inst = QUnifiedTimer::instance(false);
412     if (inst) {
413         //at this point the unified timer should have been created
414         //but it might also have been already destroyed in case the application is shutting down
415
416         if (!timer->isRegistered)
417             return;
418         timer->isRegistered = false;
419
420         int idx = inst->animationTimers.indexOf(timer);
421         if (idx != -1) {
422             inst->animationTimers.removeAt(idx);
423             // this is needed if we unregister an animation while its running
424             if (idx <= inst->currentAnimationIdx)
425                 --inst->currentAnimationIdx;
426
427             if (inst->animationTimers.isEmpty() && !inst->stopTimerPending) {
428                 inst->stopTimerPending = true;
429                 QMetaObject::invokeMethod(inst, "stopTimer", Qt::QueuedConnection);
430             }
431         } else {
432             inst->animationTimersToStart.removeOne(timer);
433         }
434     }
435 }
436
437 void QUnifiedTimer::pauseAnimationTimer(QAbstractAnimationTimer *timer, int duration)
438 {
439     QUnifiedTimer *inst = QUnifiedTimer::instance();
440     if (!timer->isRegistered)
441         inst->startAnimationTimer(timer);
442
443     bool timerWasPaused = timer->isPaused;
444     timer->isPaused = true;
445     timer->pauseDuration = duration;
446     if (!timerWasPaused)
447         inst->pausedAnimationTimers << timer;
448     inst->localRestart();
449 }
450
451 void QUnifiedTimer::resumeAnimationTimer(QAbstractAnimationTimer *timer)
452 {
453     if (!timer->isPaused)
454         return;
455
456     timer->isPaused = false;
457     QUnifiedTimer *inst = QUnifiedTimer::instance();
458     inst->pausedAnimationTimers.removeOne(timer);
459     inst->localRestart();
460 }
461
462 int QUnifiedTimer::closestPausedAnimationTimerTimeToFinish()
463 {
464     int closestTimeToFinish = INT_MAX;
465     for (int i = 0; i < pausedAnimationTimers.size(); ++i) {
466         int timeToFinish = pausedAnimationTimers.at(i)->pauseDuration;
467         if (timeToFinish < closestTimeToFinish)
468             closestTimeToFinish = timeToFinish;
469     }
470     return closestTimeToFinish;
471 }
472
473 void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d)
474 {
475     if (driver != &defaultDriver) {
476         qWarning("QUnifiedTimer: animation driver already installed...");
477         return;
478     }
479
480     if (driver->isRunning()) {
481         driver->stop();
482         d->setStartTime(time.isValid() ? time.elapsed() : 0);
483         d->start();
484     }
485
486     driver = d;
487
488 }
489
490 void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d)
491 {
492     if (driver != d) {
493         qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed...");
494         return;
495     }
496
497     driver = &defaultDriver;
498
499     if (d->isRunning()) {
500         d->stop();
501         driver->setStartTime(time.isValid() ? time.elapsed() : 0);
502         driver->start();
503     }
504 }
505
506 /*!
507     Returns true if \a d is the currently installed animation driver
508     and is not the default animation driver (which can never be uninstalled).
509 */
510 bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d)
511 {
512     return d == driver && driver != &defaultDriver;
513 }
514
515 #ifndef QT_NO_THREAD
516 Q_GLOBAL_STATIC(QThreadStorage<QAnimationTimer *>, animationTimer)
517 #endif
518
519 QAnimationTimer::QAnimationTimer() :
520     QAbstractAnimationTimer(), lastTick(0),
521     currentAnimationIdx(0), insideTick(false),
522     startAnimationPending(false), stopTimerPending(false),
523     runningLeafAnimations(0)
524 {
525 }
526
527 QAnimationTimer *QAnimationTimer::instance(bool create)
528 {
529     QAnimationTimer *inst;
530 #ifndef QT_NO_THREAD
531     if (create && !animationTimer()->hasLocalData()) {
532         inst = new QAnimationTimer;
533         animationTimer()->setLocalData(inst);
534     } else {
535         inst = animationTimer() ? animationTimer()->localData() : 0;
536     }
537 #else
538     static QAnimationTimer animationTimer;
539     inst = &animationTimer;
540 #endif
541     return inst;
542 }
543
544 QAnimationTimer *QAnimationTimer::instance()
545 {
546     return instance(true);
547 }
548
549 void QAnimationTimer::ensureTimerUpdate()
550 {
551     QAnimationTimer *inst = QAnimationTimer::instance(false);
552     QUnifiedTimer *instU = QUnifiedTimer::instance(false);
553     if (instU && inst && inst->isPaused)
554         instU->updateAnimationTimers(-1);
555 }
556
557 void QAnimationTimer::updateAnimationsTime(qint64 delta)
558 {
559     //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
560     if (insideTick)
561         return;
562
563     lastTick += delta;
564
565     //we make sure we only call update time if the time has actually changed
566     //it might happen in some cases that the time doesn't change because events are delayed
567     //when the CPU load is high
568     if (delta) {
569         insideTick = true;
570         for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
571             QAbstractAnimation *animation = animations.at(currentAnimationIdx);
572             int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime
573                           + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta);
574             animation->setCurrentTime(elapsed);
575         }
576         insideTick = false;
577         currentAnimationIdx = 0;
578     }
579 }
580
581 void QAnimationTimer::updateAnimationTimer()
582 {
583     QAnimationTimer *inst = QAnimationTimer::instance(false);
584     if (inst)
585         inst->restartAnimationTimer();
586 }
587
588 void QAnimationTimer::restartAnimationTimer()
589 {
590     if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty())
591         QUnifiedTimer::pauseAnimationTimer(this, closestPauseAnimationTimeToFinish());
592     else if (isPaused)
593         QUnifiedTimer::resumeAnimationTimer(this);
594     else if (!isRegistered)
595         QUnifiedTimer::startAnimationTimer(this);
596 }
597
598 void QAnimationTimer::startAnimations()
599 {
600     startAnimationPending = false;
601     //force timer to update, which prevents large deltas for our newly added animations
602     if (!animations.isEmpty())
603         QUnifiedTimer::instance()->maybeUpdateAnimationsToCurrentTime();
604
605     //we transfer the waiting animations into the "really running" state
606     animations += animationsToStart;
607     animationsToStart.clear();
608     if (!animations.isEmpty())
609         restartAnimationTimer();
610 }
611
612 void QAnimationTimer::stopTimer()
613 {
614     stopTimerPending = false;
615     if (animations.isEmpty()) {
616         QUnifiedTimer::resumeAnimationTimer(this);
617         QUnifiedTimer::stopAnimationTimer(this);
618         // invalidate the start reference time
619         lastTick = 0;
620     }
621 }
622
623 void QAnimationTimer::registerAnimation(QAbstractAnimation *animation, bool isTopLevel)
624 {
625     QAnimationTimer *inst = instance(true); //we create the instance if needed
626     inst->registerRunningAnimation(animation);
627     if (isTopLevel) {
628         Q_ASSERT(!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer);
629         QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = true;
630         inst->animationsToStart << animation;
631         if (!inst->startAnimationPending) {
632             inst->startAnimationPending = true;
633             QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection);
634         }
635     }
636 }
637
638 void QAnimationTimer::unregisterAnimation(QAbstractAnimation *animation)
639 {
640     QAnimationTimer *inst = QAnimationTimer::instance(false);
641     if (inst) {
642         //at this point the unified timer should have been created
643         //but it might also have been already destroyed in case the application is shutting down
644
645         inst->unregisterRunningAnimation(animation);
646
647         if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
648             return;
649
650         int idx = inst->animations.indexOf(animation);
651         if (idx != -1) {
652             inst->animations.removeAt(idx);
653             // this is needed if we unregister an animation while its running
654             if (idx <= inst->currentAnimationIdx)
655                 --inst->currentAnimationIdx;
656
657             if (inst->animations.isEmpty() && !inst->stopTimerPending) {
658                 inst->stopTimerPending = true;
659                 QMetaObject::invokeMethod(inst, "stopTimer", Qt::QueuedConnection);
660             }
661         } else {
662             inst->animationsToStart.removeOne(animation);
663         }
664     }
665     QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = false;
666 }
667
668 void QAnimationTimer::registerRunningAnimation(QAbstractAnimation *animation)
669 {
670     if (QAbstractAnimationPrivate::get(animation)->isGroup)
671         return;
672
673     if (QAbstractAnimationPrivate::get(animation)->isPause) {
674         runningPauseAnimations << animation;
675     } else
676         runningLeafAnimations++;
677 }
678
679 void QAnimationTimer::unregisterRunningAnimation(QAbstractAnimation *animation)
680 {
681     if (QAbstractAnimationPrivate::get(animation)->isGroup)
682         return;
683
684     if (QAbstractAnimationPrivate::get(animation)->isPause)
685         runningPauseAnimations.removeOne(animation);
686     else
687         runningLeafAnimations--;
688     Q_ASSERT(runningLeafAnimations >= 0);
689 }
690
691 int QAnimationTimer::closestPauseAnimationTimeToFinish()
692 {
693     int closestTimeToFinish = INT_MAX;
694     for (int i = 0; i < runningPauseAnimations.size(); ++i) {
695         QAbstractAnimation *animation = runningPauseAnimations.at(i);
696         int timeToFinish;
697
698         if (animation->direction() == QAbstractAnimation::Forward)
699             timeToFinish = animation->duration() - animation->currentLoopTime();
700         else
701             timeToFinish = animation->currentLoopTime();
702
703         if (timeToFinish < closestTimeToFinish)
704             closestTimeToFinish = timeToFinish;
705     }
706     return closestTimeToFinish;
707 }
708
709 /*!
710    \class QAnimationDriver
711
712    \brief The QAnimationDriver class is used to exchange the mechanism that drives animations.
713
714    The default animation system is driven by a timer that fires at regular intervals.
715    In some scenarios, it is better to drive the animation based on other synchronization
716    mechanisms, such as the vertical refresh rate of the screen.
717
718    \internal
719  */
720
721 QAnimationDriver::QAnimationDriver(QObject *parent)
722     : QObject(*(new QAnimationDriverPrivate), parent)
723 {
724 }
725
726 QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent)
727     : QObject(dd, parent)
728 {
729 }
730
731 QAnimationDriver::~QAnimationDriver()
732 {
733     QUnifiedTimer *timer = QUnifiedTimer::instance(false);
734     if (timer && timer->canUninstallAnimationDriver(this))
735         uninstall();
736 }
737
738
739 /*!
740     Sets the time at which an animation driver should start at.
741
742     This is to take into account that pauses can occur in running
743     animations which will stop the driver, but the time still
744     increases.
745  */
746 void QAnimationDriver::setStartTime(qint64 startTime)
747 {
748     Q_D(QAnimationDriver);
749     d->startTime = startTime;
750 }
751
752 /*!
753     Returns the start time of the animation.
754  */
755 qint64 QAnimationDriver::startTime() const
756 {
757     Q_D(const QAnimationDriver);
758     return d->startTime;
759 }
760
761
762 /*!
763     Advances the animation based to the specified \a timeStep. This function should
764     be continuously called by the driver subclasses while the animation is running.
765
766     If \a timeStep is positive, it will be used as the current time in the
767     calculations; otherwise, the current clock time will be used.
768  */
769
770 void QAnimationDriver::advanceAnimation(qint64 timeStep)
771 {
772     QUnifiedTimer *instance = QUnifiedTimer::instance();
773
774     // update current time on all top level animations
775     instance->updateAnimationTimers(timeStep);
776     instance->restart();
777 }
778
779
780
781 /*!
782     Advances the animation. This function should be continously called
783     by the driver while the animation is running.
784  */
785
786 void QAnimationDriver::advance()
787 {
788     advanceAnimation(-1);
789 }
790
791
792
793 /*!
794     Installs this animation driver. The animation driver is thread local and
795     will only apply for the thread its installed in.
796  */
797
798 void QAnimationDriver::install()
799 {
800     QUnifiedTimer *timer = QUnifiedTimer::instance(true);
801     timer->installAnimationDriver(this);
802 }
803
804
805
806 /*!
807     Uninstalls this animation driver.
808  */
809
810 void QAnimationDriver::uninstall()
811 {
812     QUnifiedTimer *timer = QUnifiedTimer::instance(true);
813     timer->uninstallAnimationDriver(this);
814 }
815
816 bool QAnimationDriver::isRunning() const
817 {
818     return d_func()->running;
819 }
820
821
822 void QAnimationDriver::start()
823 {
824     Q_D(QAnimationDriver);
825     if (!d->running) {
826         emit started();
827         d->running = true;
828     }
829 }
830
831
832 void QAnimationDriver::stop()
833 {
834     Q_D(QAnimationDriver);
835     if (d->running) {
836         emit stopped();
837         d->running = false;
838     }
839 }
840
841
842 /*!
843     \fn qint64 QAnimationDriver::elapsed() const
844
845     Returns the number of milliseconds since the animations was started.
846  */
847
848 qint64 QAnimationDriver::elapsed() const
849 {
850     // The default implementation picks up the elapsed time from the
851     // unified timer and can ignore the time offset.
852     return QUnifiedTimer::instance()->time.elapsed();
853 }
854
855 /*!
856     \fn QAnimationDriver::started()
857
858     This signal is emitted by the animation framework to notify the driver
859     that continous animation has started.
860
861     \internal
862  */
863
864 /*!
865     \fn QAnimationDriver::stopped()
866
867     This signal is emitted by the animation framework to notify the driver
868     that continous animation has stopped.
869
870     \internal
871  */
872
873 /*!
874    The default animation driver just spins the timer...
875  */
876 QDefaultAnimationDriver::QDefaultAnimationDriver(QUnifiedTimer *timer)
877     : QAnimationDriver(0), m_unified_timer(timer)
878 {
879     connect(this, SIGNAL(started()), this, SLOT(startTimer()));
880     connect(this, SIGNAL(stopped()), this, SLOT(stopTimer()));
881 }
882
883 void QDefaultAnimationDriver::timerEvent(QTimerEvent *e)
884 {
885     Q_ASSERT(e->timerId() == m_timer.timerId());
886     Q_UNUSED(e); // if the assertions are disabled
887     advance();
888 }
889
890 void QDefaultAnimationDriver::startTimer()
891 {
892     // always use a precise timer to drive animations
893     m_timer.start(m_unified_timer->timingInterval, Qt::PreciseTimer, this);
894 }
895
896 void QDefaultAnimationDriver::stopTimer()
897 {
898     m_timer.stop();
899 }
900
901
902
903 void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState)
904 {
905     Q_Q(QAbstractAnimation);
906     if (state == newState)
907         return;
908
909     if (loopCount == 0)
910         return;
911
912     QAbstractAnimation::State oldState = state;
913     int oldCurrentTime = currentTime;
914     int oldCurrentLoop = currentLoop;
915     QAbstractAnimation::Direction oldDirection = direction;
916
917     // check if we should Rewind
918     if ((newState == QAbstractAnimation::Paused || newState == QAbstractAnimation::Running)
919         && oldState == QAbstractAnimation::Stopped) {
920             //here we reset the time if needed
921             //we don't call setCurrentTime because this might change the way the animation
922             //behaves: changing the state or changing the current value
923             totalCurrentTime = currentTime = (direction == QAbstractAnimation::Forward) ?
924                 0 : (loopCount == -1 ? q->duration() : q->totalDuration());
925     }
926
927     state = newState;
928     QWeakPointer<QAbstractAnimation> guard(q);
929
930     //(un)registration of the animation must always happen before calls to
931     //virtual function (updateState) to ensure a correct state of the timer
932     bool isTopLevel = !group || group->state() == QAbstractAnimation::Stopped;
933     if (oldState == QAbstractAnimation::Running) {
934         if (newState == QAbstractAnimation::Paused && hasRegisteredTimer)
935             QAnimationTimer::ensureTimerUpdate();
936         //the animation, is not running any more
937         QAnimationTimer::unregisterAnimation(q);
938     } else if (newState == QAbstractAnimation::Running) {
939         QAnimationTimer::registerAnimation(q, isTopLevel);
940     }
941
942     q->updateState(newState, oldState);
943     if (!guard || newState != state) //this is to be safe if updateState changes the state
944         return;
945
946     // Notify state change
947     emit q->stateChanged(newState, oldState);
948     if (!guard || newState != state) //this is to be safe if updateState changes the state
949         return;
950
951     switch (state) {
952     case QAbstractAnimation::Paused:
953         break;
954     case QAbstractAnimation::Running:
955         {
956
957             // this ensures that the value is updated now that the animation is running
958             if (oldState == QAbstractAnimation::Stopped) {
959                 if (isTopLevel) {
960                     // currentTime needs to be updated if pauseTimer is active
961                     QAnimationTimer::ensureTimerUpdate();
962                     q->setCurrentTime(totalCurrentTime);
963                 }
964             }
965         }
966         break;
967     case QAbstractAnimation::Stopped:
968         // Leave running state.
969         int dura = q->duration();
970
971         if (deleteWhenStopped)
972             q->deleteLater();
973
974         if (dura == -1 || loopCount < 0
975             || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount))
976             || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) {
977                 emit q->finished();
978         }
979         break;
980     }
981 }
982
983 /*!
984     Constructs the QAbstractAnimation base class, and passes \a parent to
985     QObject's constructor.
986
987     \sa QVariantAnimation, QAnimationGroup
988 */
989 QAbstractAnimation::QAbstractAnimation(QObject *parent)
990     : QObject(*new QAbstractAnimationPrivate, 0)
991 {
992     // Allow auto-add on reparent
993     setParent(parent);
994 }
995
996 /*!
997     \internal
998 */
999 QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent)
1000     : QObject(dd, 0)
1001 {
1002     // Allow auto-add on reparent
1003    setParent(parent);
1004 }
1005
1006 /*!
1007     Stops the animation if it's running, then destroys the
1008     QAbstractAnimation. If the animation is part of a QAnimationGroup, it is
1009     automatically removed before it's destroyed.
1010 */
1011 QAbstractAnimation::~QAbstractAnimation()
1012 {
1013     Q_D(QAbstractAnimation);
1014     //we can't call stop here. Otherwise we get pure virtual calls
1015     if (d->state != Stopped) {
1016         QAbstractAnimation::State oldState = d->state;
1017         d->state = Stopped;
1018         emit stateChanged(oldState, d->state);
1019         if (oldState == QAbstractAnimation::Running)
1020             QAnimationTimer::unregisterAnimation(this);
1021     }
1022 }
1023
1024 /*!
1025     \property QAbstractAnimation::state
1026     \brief state of the animation.
1027
1028     This property describes the current state of the animation. When the
1029     animation state changes, QAbstractAnimation emits the stateChanged()
1030     signal.
1031 */
1032 QAbstractAnimation::State QAbstractAnimation::state() const
1033 {
1034     Q_D(const QAbstractAnimation);
1035     return d->state;
1036 }
1037
1038 /*!
1039     If this animation is part of a QAnimationGroup, this function returns a
1040     pointer to the group; otherwise, it returns 0.
1041
1042     \sa QAnimationGroup::addAnimation()
1043 */
1044 QAnimationGroup *QAbstractAnimation::group() const
1045 {
1046     Q_D(const QAbstractAnimation);
1047     return d->group;
1048 }
1049
1050 /*!
1051     \enum QAbstractAnimation::State
1052
1053     This enum describes the state of the animation.
1054
1055     \value Stopped The animation is not running. This is the initial state
1056     of QAbstractAnimation, and the state QAbstractAnimation reenters when finished. The current
1057     time remain unchanged until either setCurrentTime() is
1058     called, or the animation is started by calling start().
1059
1060     \value Paused The animation is paused (i.e., temporarily
1061     suspended). Calling resume() will resume animation activity.
1062
1063     \value Running The animation is running. While control is in the event
1064     loop, QAbstractAnimation will update its current time at regular intervals,
1065     calling updateCurrentTime() when appropriate.
1066
1067     \sa state(), stateChanged()
1068 */
1069
1070 /*!
1071     \enum QAbstractAnimation::Direction
1072
1073     This enum describes the direction of the animation when in \l Running state.
1074
1075     \value Forward The current time of the animation increases with time (i.e.,
1076     moves from 0 and towards the end / duration).
1077
1078     \value Backward The current time of the animation decreases with time (i.e.,
1079     moves from the end / duration and towards 0).
1080
1081     \sa direction
1082 */
1083
1084 /*!
1085     \property QAbstractAnimation::direction
1086     \brief the direction of the animation when it is in \l Running
1087     state.
1088
1089     This direction indicates whether the time moves from 0 towards the
1090     animation duration, or from the value of the duration and towards 0 after
1091     start() has been called.
1092
1093     By default, this property is set to \l Forward.
1094 */
1095 QAbstractAnimation::Direction QAbstractAnimation::direction() const
1096 {
1097     Q_D(const QAbstractAnimation);
1098     return d->direction;
1099 }
1100 void QAbstractAnimation::setDirection(Direction direction)
1101 {
1102     Q_D(QAbstractAnimation);
1103     if (d->direction == direction)
1104         return;
1105
1106     if (state() == Stopped) {
1107         if (direction == Backward) {
1108             d->currentTime = duration();
1109             d->currentLoop = d->loopCount - 1;
1110         } else {
1111             d->currentTime = 0;
1112             d->currentLoop = 0;
1113         }
1114     }
1115
1116     // the commands order below is important: first we need to setCurrentTime with the old direction,
1117     // then update the direction on this and all children and finally restart the pauseTimer if needed
1118     if (d->hasRegisteredTimer)
1119         QAnimationTimer::ensureTimerUpdate();
1120
1121     d->direction = direction;
1122     updateDirection(direction);
1123
1124     if (d->hasRegisteredTimer)
1125         // needed to update the timer interval in case of a pause animation
1126         QAnimationTimer::updateAnimationTimer();
1127
1128     emit directionChanged(direction);
1129 }
1130
1131 /*!
1132     \property QAbstractAnimation::duration
1133     \brief the duration of the animation.
1134
1135     If the duration is -1, it means that the duration is undefined.
1136     In this case, loopCount is ignored.
1137 */
1138
1139 /*!
1140     \property QAbstractAnimation::loopCount
1141     \brief the loop count of the animation
1142
1143     This property describes the loop count of the animation as an integer.
1144     By default this value is 1, indicating that the animation
1145     should run once only, and then stop. By changing it you can let the
1146     animation loop several times. With a value of 0, the animation will not
1147     run at all, and with a value of -1, the animation will loop forever
1148     until stopped.
1149     It is not supported to have loop on an animation that has an undefined
1150     duration. It will only run once.
1151 */
1152 int QAbstractAnimation::loopCount() const
1153 {
1154     Q_D(const QAbstractAnimation);
1155     return d->loopCount;
1156 }
1157 void QAbstractAnimation::setLoopCount(int loopCount)
1158 {
1159     Q_D(QAbstractAnimation);
1160     d->loopCount = loopCount;
1161 }
1162
1163 /*!
1164     \property QAbstractAnimation::currentLoop
1165     \brief the current loop of the animation
1166
1167     This property describes the current loop of the animation. By default,
1168     the animation's loop count is 1, and so the current loop will
1169     always be 0. If the loop count is 2 and the animation runs past its
1170     duration, it will automatically rewind and restart at current time 0, and
1171     current loop 1, and so on.
1172
1173     When the current loop changes, QAbstractAnimation emits the
1174     currentLoopChanged() signal.
1175 */
1176 int QAbstractAnimation::currentLoop() const
1177 {
1178     Q_D(const QAbstractAnimation);
1179     return d->currentLoop;
1180 }
1181
1182 /*!
1183     \fn virtual int QAbstractAnimation::duration() const = 0
1184
1185     This pure virtual function returns the duration of the animation, and
1186     defines for how long QAbstractAnimation should update the current
1187     time. This duration is local, and does not include the loop count.
1188
1189     A return value of -1 indicates that the animation has no defined duration;
1190     the animation should run forever until stopped. This is useful for
1191     animations that are not time driven, or where you cannot easily predict
1192     its duration (e.g., event driven audio playback in a game).
1193
1194     If the animation is a parallel QAnimationGroup, the duration will be the longest
1195     duration of all its animations. If the animation is a sequential QAnimationGroup,
1196     the duration will be the sum of the duration of all its animations.
1197     \sa loopCount
1198 */
1199
1200 /*!
1201     Returns the total and effective duration of the animation, including the
1202     loop count.
1203
1204     \sa duration(), currentTime
1205 */
1206 int QAbstractAnimation::totalDuration() const
1207 {
1208     int dura = duration();
1209     if (dura <= 0)
1210         return dura;
1211     int loopcount = loopCount();
1212     if (loopcount < 0)
1213         return -1;
1214     return dura * loopcount;
1215 }
1216
1217 /*!
1218     Returns the current time inside the current loop. It can go from 0 to duration().
1219
1220     \sa duration(), currentTime
1221 */
1222
1223 int QAbstractAnimation::currentLoopTime() const
1224 {
1225     Q_D(const QAbstractAnimation);
1226     return d->currentTime;
1227 }
1228
1229 /*!
1230     \property QAbstractAnimation::currentTime
1231     \brief the current time and progress of the animation
1232
1233     This property describes the animation's current time. You can change the
1234     current time by calling setCurrentTime, or you can call start() and let
1235     the animation run, setting the current time automatically as the animation
1236     progresses.
1237
1238     The animation's current time starts at 0, and ends at totalDuration().
1239
1240     \sa loopCount, currentLoopTime()
1241  */
1242 int QAbstractAnimation::currentTime() const
1243 {
1244     Q_D(const QAbstractAnimation);
1245     return d->totalCurrentTime;
1246 }
1247 void QAbstractAnimation::setCurrentTime(int msecs)
1248 {
1249     Q_D(QAbstractAnimation);
1250     msecs = qMax(msecs, 0);
1251
1252     // Calculate new time and loop.
1253     int dura = duration();
1254     int totalDura = dura <= 0 ? dura : ((d->loopCount < 0) ? -1 : dura * d->loopCount);
1255     if (totalDura != -1)
1256         msecs = qMin(totalDura, msecs);
1257     d->totalCurrentTime = msecs;
1258
1259     // Update new values.
1260     int oldLoop = d->currentLoop;
1261     d->currentLoop = ((dura <= 0) ? 0 : (msecs / dura));
1262     if (d->currentLoop == d->loopCount) {
1263         //we're at the end
1264         d->currentTime = qMax(0, dura);
1265         d->currentLoop = qMax(0, d->loopCount - 1);
1266     } else {
1267         if (d->direction == Forward) {
1268             d->currentTime = (dura <= 0) ? msecs : (msecs % dura);
1269         } else {
1270             d->currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1;
1271             if (d->currentTime == dura)
1272                 --d->currentLoop;
1273         }
1274     }
1275
1276     updateCurrentTime(d->currentTime);
1277     if (d->currentLoop != oldLoop)
1278         emit currentLoopChanged(d->currentLoop);
1279
1280     // All animations are responsible for stopping the animation when their
1281     // own end state is reached; in this case the animation is time driven,
1282     // and has reached the end.
1283     if ((d->direction == Forward && d->totalCurrentTime == totalDura)
1284         || (d->direction == Backward && d->totalCurrentTime == 0)) {
1285         stop();
1286     }
1287 }
1288
1289 /*!
1290     Starts the animation. The \a policy argument says whether or not the
1291     animation should be deleted when it's done. When the animation starts, the
1292     stateChanged() signal is emitted, and state() returns Running. When control
1293     reaches the event loop, the animation will run by itself, periodically
1294     calling updateCurrentTime() as the animation progresses.
1295
1296     If the animation is currently stopped or has already reached the end,
1297     calling start() will rewind the animation and start again from the beginning.
1298     When the animation reaches the end, the animation will either stop, or
1299     if the loop level is more than 1, it will rewind and continue from the beginning.
1300
1301     If the animation is already running, this function does nothing.
1302
1303     \sa stop(), state()
1304 */
1305 void QAbstractAnimation::start(DeletionPolicy policy)
1306 {
1307     Q_D(QAbstractAnimation);
1308     if (d->state == Running)
1309         return;
1310     d->deleteWhenStopped = policy;
1311     d->setState(Running);
1312 }
1313
1314 /*!
1315     Stops the animation. When the animation is stopped, it emits the stateChanged()
1316     signal, and state() returns Stopped. The current time is not changed.
1317
1318     If the animation stops by itself after reaching the end (i.e.,
1319     currentLoopTime() == duration() and currentLoop() > loopCount() - 1), the
1320     finished() signal is emitted.
1321
1322     \sa start(), state()
1323  */
1324 void QAbstractAnimation::stop()
1325 {
1326     Q_D(QAbstractAnimation);
1327
1328     if (d->state == Stopped)
1329         return;
1330
1331     d->setState(Stopped);
1332 }
1333
1334 /*!
1335     Pauses the animation. When the animation is paused, state() returns Paused.
1336     The value of currentTime will remain unchanged until resume() or start()
1337     is called. If you want to continue from the current time, call resume().
1338
1339     \sa start(), state(), resume()
1340  */
1341 void QAbstractAnimation::pause()
1342 {
1343     Q_D(QAbstractAnimation);
1344     if (d->state == Stopped) {
1345         qWarning("QAbstractAnimation::pause: Cannot pause a stopped animation");
1346         return;
1347     }
1348
1349     d->setState(Paused);
1350 }
1351
1352 /*!
1353     Resumes the animation after it was paused. When the animation is resumed,
1354     it emits the resumed() and stateChanged() signals. The currenttime is not
1355     changed.
1356
1357     \sa start(), pause(), state()
1358  */
1359 void QAbstractAnimation::resume()
1360 {
1361     Q_D(QAbstractAnimation);
1362     if (d->state != Paused) {
1363         qWarning("QAbstractAnimation::resume: "
1364                  "Cannot resume an animation that is not paused");
1365         return;
1366     }
1367
1368     d->setState(Running);
1369 }
1370
1371 /*!
1372     If \a paused is true, the animation is paused.
1373     If \a paused is false, the animation is resumed.
1374
1375     \sa state(), pause(), resume()
1376 */
1377 void QAbstractAnimation::setPaused(bool paused)
1378 {
1379     if (paused)
1380         pause();
1381     else
1382         resume();
1383 }
1384
1385
1386 /*!
1387     \reimp
1388 */
1389 bool QAbstractAnimation::event(QEvent *event)
1390 {
1391     return QObject::event(event);
1392 }
1393
1394 /*!
1395     \fn virtual void QAbstractAnimation::updateCurrentTime(int currentTime) = 0;
1396
1397     This pure virtual function is called every time the animation's
1398     \a currentTime changes.
1399
1400     \sa updateState()
1401 */
1402
1403 /*!
1404     This virtual function is called by QAbstractAnimation when the state
1405     of the animation is changed from \a oldState to \a newState.
1406
1407     \sa start(), stop(), pause(), resume()
1408 */
1409 void QAbstractAnimation::updateState(QAbstractAnimation::State newState,
1410                                      QAbstractAnimation::State oldState)
1411 {
1412     Q_UNUSED(oldState);
1413     Q_UNUSED(newState);
1414 }
1415
1416 /*!
1417     This virtual function is called by QAbstractAnimation when the direction
1418     of the animation is changed. The \a direction argument is the new direction.
1419
1420     \sa setDirection(), direction()
1421 */
1422 void QAbstractAnimation::updateDirection(QAbstractAnimation::Direction direction)
1423 {
1424     Q_UNUSED(direction);
1425 }
1426
1427
1428 QT_END_NAMESPACE
1429
1430 #include "moc_qabstractanimation.cpp"
1431
1432 #endif //QT_NO_ANIMATION