source: trunk/src/corelib/animation/qabstractanimation.cpp@ 769

Last change on this file since 769 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 27.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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 STARTSTOP_TIMER_DELAY 0
161
162QT_BEGIN_NAMESPACE
163
164Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
165
166QUnifiedTimer::QUnifiedTimer() :
167 QObject(), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
168 currentAnimationIdx(0), consistentTiming(false), slowMode(false),
169 isPauseTimerActive(false), runningLeafAnimations(0)
170{
171}
172
173QUnifiedTimer *QUnifiedTimer::instance()
174{
175 QUnifiedTimer *inst;
176 if (!unifiedTimer()->hasLocalData()) {
177 inst = new QUnifiedTimer;
178 unifiedTimer()->setLocalData(inst);
179 } else {
180 inst = unifiedTimer()->localData();
181 }
182 return inst;
183}
184
185void QUnifiedTimer::ensureTimerUpdate()
186{
187 if (isPauseTimerActive)
188 updateAnimationsTime();
189}
190
191void QUnifiedTimer::updateAnimationsTime()
192{
193 // ignore consistentTiming in case the pause timer is active
194 int delta = (consistentTiming && !isPauseTimerActive) ?
195 timingInterval : time.elapsed() - lastTick;
196 if (slowMode)
197 delta /= 5;
198 lastTick = time.elapsed();
199
200 //we make sure we only call update time if the time has actually changed
201 //it might happen in some cases that the time doesn't change because events are delayed
202 //when the CPU load is high
203 if (delta) {
204 for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
205 QAbstractAnimation *animation = animations.at(currentAnimationIdx);
206 int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime
207 + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta);
208 animation->setCurrentTime(elapsed);
209 }
210 currentAnimationIdx = 0;
211 }
212}
213
214void QUnifiedTimer::restartAnimationTimer()
215{
216 if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty()) {
217 int closestTimeToFinish = closestPauseAnimationTimeToFinish();
218 if (closestTimeToFinish < 0) {
219 qDebug() << runningPauseAnimations;
220 qDebug() << closestPauseAnimationTimeToFinish();
221 }
222 animationTimer.start(closestTimeToFinish, this);
223 isPauseTimerActive = true;
224 } else if (!animationTimer.isActive() || isPauseTimerActive) {
225 animationTimer.start(timingInterval, this);
226 isPauseTimerActive = false;
227 }
228}
229
230void QUnifiedTimer::timerEvent(QTimerEvent *event)
231{
232 //in the case of consistent timing we make sure the orders in which events come is always the same
233 //for that purpose we do as if the startstoptimer would always fire before the animation timer
234 if ((consistentTiming && startStopAnimationTimer.isActive()) ||
235 event->timerId() == startStopAnimationTimer.timerId()) {
236 startStopAnimationTimer.stop();
237
238 //we transfer the waiting animations into the "really running" state
239 animations += animationsToStart;
240 animationsToStart.clear();
241 if (animations.isEmpty()) {
242 animationTimer.stop();
243 isPauseTimerActive = false;
244 // invalidate the start reference time
245 time = QTime();
246 } else {
247 restartAnimationTimer();
248 if (!time.isValid()) {
249 lastTick = 0;
250 time.start();
251 }
252 }
253 }
254
255 if (event->timerId() == animationTimer.timerId()) {
256 // update current time on all top level animations
257 updateAnimationsTime();
258 restartAnimationTimer();
259 }
260}
261
262void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation, bool isTopLevel)
263{
264 registerRunningAnimation(animation);
265 if (isTopLevel) {
266 Q_ASSERT(!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer);
267 QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = true;
268 animationsToStart << animation;
269 if (!startStopAnimationTimer.isActive())
270 startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, this);
271 }
272}
273
274void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation)
275{
276 unregisterRunningAnimation(animation);
277
278 if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
279 return;
280
281 int idx = animations.indexOf(animation);
282 if (idx != -1) {
283 animations.removeAt(idx);
284 // this is needed if we unregister an animation while its running
285 if (idx <= currentAnimationIdx)
286 --currentAnimationIdx;
287
288 if (animations.isEmpty() && !startStopAnimationTimer.isActive())
289 startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, this);
290 } else {
291 animationsToStart.removeOne(animation);
292 }
293 QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = false;
294}
295
296void QUnifiedTimer::registerRunningAnimation(QAbstractAnimation *animation)
297{
298 if (QAbstractAnimationPrivate::get(animation)->isGroup)
299 return;
300
301 if (QAbstractAnimationPrivate::get(animation)->isPause) {
302 runningPauseAnimations << animation;
303 } else
304 runningLeafAnimations++;
305}
306
307void QUnifiedTimer::unregisterRunningAnimation(QAbstractAnimation *animation)
308{
309 if (QAbstractAnimationPrivate::get(animation)->isGroup)
310 return;
311
312 if (QAbstractAnimationPrivate::get(animation)->isPause)
313 runningPauseAnimations.removeOne(animation);
314 else
315 runningLeafAnimations--;
316 Q_ASSERT(runningLeafAnimations >= 0);
317}
318
319int QUnifiedTimer::closestPauseAnimationTimeToFinish()
320{
321 int closestTimeToFinish = INT_MAX;
322 for (int i = 0; i < runningPauseAnimations.size(); ++i) {
323 QAbstractAnimation *animation = runningPauseAnimations.at(i);
324 int timeToFinish;
325
326 if (animation->direction() == QAbstractAnimation::Forward)
327 timeToFinish = animation->duration() - animation->currentLoopTime();
328 else
329 timeToFinish = animation->currentLoopTime();
330
331 if (timeToFinish < closestTimeToFinish)
332 closestTimeToFinish = timeToFinish;
333 }
334 return closestTimeToFinish;
335}
336
337void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState)
338{
339 Q_Q(QAbstractAnimation);
340 if (state == newState)
341 return;
342
343 QAbstractAnimation::State oldState = state;
344 int oldCurrentTime = currentTime;
345 int oldCurrentLoop = currentLoop;
346 QAbstractAnimation::Direction oldDirection = direction;
347
348 // check if we should Rewind
349 if ((newState == QAbstractAnimation::Paused || newState == QAbstractAnimation::Running)
350 && oldState == QAbstractAnimation::Stopped) {
351 //here we reset the time if needed
352 //we don't call setCurrentTime because this might change the way the animation
353 //behaves: changing the state or changing the current value
354 totalCurrentTime = currentTime = (direction == QAbstractAnimation::Forward) ?
355 0 : (loopCount == -1 ? q->duration() : q->totalDuration());
356 }
357
358 state = newState;
359 QWeakPointer<QAbstractAnimation> guard(q);
360
361 //(un)registration of the animation must always happen before calls to
362 //virtual function (updateState) to ensure a correct state of the timer
363 bool isTopLevel = !group || group->state() == QAbstractAnimation::Stopped;
364 if (oldState == QAbstractAnimation::Running) {
365 if (newState == QAbstractAnimation::Paused && hasRegisteredTimer)
366 QUnifiedTimer::instance()->ensureTimerUpdate();
367 //the animation, is not running any more
368 QUnifiedTimer::instance()->unregisterAnimation(q);
369 } else if (newState == QAbstractAnimation::Running) {
370 QUnifiedTimer::instance()->registerAnimation(q, isTopLevel);
371 }
372
373 q->updateState(newState, oldState);
374 if (!guard || newState != state) //this is to be safe if updateState changes the state
375 return;
376
377 // Notify state change
378 emit q->stateChanged(newState, oldState);
379 if (!guard || newState != state) //this is to be safe if updateState changes the state
380 return;
381
382 switch (state) {
383 case QAbstractAnimation::Paused:
384 break;
385 case QAbstractAnimation::Running:
386 {
387
388 // this ensures that the value is updated now that the animation is running
389 if (oldState == QAbstractAnimation::Stopped) {
390 if (isTopLevel) {
391 // currentTime needs to be updated if pauseTimer is active
392 QUnifiedTimer::instance()->ensureTimerUpdate();
393 q->setCurrentTime(totalCurrentTime);
394 }
395 }
396 }
397 break;
398 case QAbstractAnimation::Stopped:
399 // Leave running state.
400 int dura = q->duration();
401
402 if (deleteWhenStopped)
403 q->deleteLater();
404
405 if (dura == -1 || loopCount < 0
406 || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount))
407 || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) {
408 emit q->finished();
409 }
410 break;
411 }
412}
413
414/*!
415 Constructs the QAbstractAnimation base class, and passes \a parent to
416 QObject's constructor.
417
418 \sa QVariantAnimation, QAnimationGroup
419*/
420QAbstractAnimation::QAbstractAnimation(QObject *parent)
421 : QObject(*new QAbstractAnimationPrivate, 0)
422{
423 // Allow auto-add on reparent
424 setParent(parent);
425}
426
427/*!
428 \internal
429*/
430QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent)
431 : QObject(dd, 0)
432{
433 // Allow auto-add on reparent
434 setParent(parent);
435}
436
437/*!
438 Stops the animation if it's running, then destroys the
439 QAbstractAnimation. If the animation is part of a QAnimationGroup, it is
440 automatically removed before it's destroyed.
441*/
442QAbstractAnimation::~QAbstractAnimation()
443{
444 Q_D(QAbstractAnimation);
445 //we can't call stop here. Otherwise we get pure virtual calls
446 if (d->state != Stopped) {
447 QAbstractAnimation::State oldState = d->state;
448 d->state = Stopped;
449 emit stateChanged(oldState, d->state);
450 if (oldState == QAbstractAnimation::Running)
451 QUnifiedTimer::instance()->unregisterAnimation(this);
452 }
453}
454
455/*!
456 \property QAbstractAnimation::state
457 \brief state of the animation.
458
459 This property describes the current state of the animation. When the
460 animation state changes, QAbstractAnimation emits the stateChanged()
461 signal.
462*/
463QAbstractAnimation::State QAbstractAnimation::state() const
464{
465 Q_D(const QAbstractAnimation);
466 return d->state;
467}
468
469/*!
470 If this animation is part of a QAnimationGroup, this function returns a
471 pointer to the group; otherwise, it returns 0.
472
473 \sa QAnimationGroup::addAnimation()
474*/
475QAnimationGroup *QAbstractAnimation::group() const
476{
477 Q_D(const QAbstractAnimation);
478 return d->group;
479}
480
481/*!
482 \enum QAbstractAnimation::State
483
484 This enum describes the state of the animation.
485
486 \value Stopped The animation is not running. This is the initial state
487 of QAbstractAnimation, and the state QAbstractAnimation reenters when finished. The current
488 time remain unchanged until either setCurrentTime() is
489 called, or the animation is started by calling start().
490
491 \value Paused The animation is paused (i.e., temporarily
492 suspended). Calling resume() will resume animation activity.
493
494 \value Running The animation is running. While control is in the event
495 loop, QAbstractAnimation will update its current time at regular intervals,
496 calling updateCurrentTime() when appropriate.
497
498 \sa state(), stateChanged()
499*/
500
501/*!
502 \enum QAbstractAnimation::Direction
503
504 This enum describes the direction of the animation when in \l Running state.
505
506 \value Forward The current time of the animation increases with time (i.e.,
507 moves from 0 and towards the end / duration).
508
509 \value Backward The current time of the animation decreases with time (i.e.,
510 moves from the end / duration and towards 0).
511
512 \sa direction
513*/
514
515/*!
516 \property QAbstractAnimation::direction
517 \brief the direction of the animation when it is in \l Running
518 state.
519
520 This direction indicates whether the time moves from 0 towards the
521 animation duration, or from the value of the duration and towards 0 after
522 start() has been called.
523
524 By default, this property is set to \l Forward.
525*/
526QAbstractAnimation::Direction QAbstractAnimation::direction() const
527{
528 Q_D(const QAbstractAnimation);
529 return d->direction;
530}
531void QAbstractAnimation::setDirection(Direction direction)
532{
533 Q_D(QAbstractAnimation);
534 if (d->direction == direction)
535 return;
536
537 if (state() == Stopped) {
538 if (direction == Backward) {
539 d->currentTime = duration();
540 d->currentLoop = d->loopCount - 1;
541 } else {
542 d->currentTime = 0;
543 d->currentLoop = 0;
544 }
545 }
546
547 // the commands order below is important: first we need to setCurrentTime with the old direction,
548 // then update the direction on this and all children and finally restart the pauseTimer if needed
549 if (d->hasRegisteredTimer)
550 QUnifiedTimer::instance()->ensureTimerUpdate();
551
552 d->direction = direction;
553 updateDirection(direction);
554
555 if (d->hasRegisteredTimer)
556 // needed to update the timer interval in case of a pause animation
557 QUnifiedTimer::instance()->restartAnimationTimer();
558
559 emit directionChanged(direction);
560}
561
562/*!
563 \property QAbstractAnimation::duration
564 \brief the duration of the animation.
565
566 If the duration is -1, it means that the duration is undefined.
567 In this case, loopCount is ignored.
568*/
569
570/*!
571 \property QAbstractAnimation::loopCount
572 \brief the loop count of the animation
573
574 This property describes the loop count of the animation as an integer.
575 By default this value is 1, indicating that the animation
576 should run once only, and then stop. By changing it you can let the
577 animation loop several times. With a value of 0, the animation will not
578 run at all, and with a value of -1, the animation will loop forever
579 until stopped.
580 It is not supported to have loop on an animation that has an undefined
581 duration. It will only run once.
582*/
583int QAbstractAnimation::loopCount() const
584{
585 Q_D(const QAbstractAnimation);
586 return d->loopCount;
587}
588void QAbstractAnimation::setLoopCount(int loopCount)
589{
590 Q_D(QAbstractAnimation);
591 d->loopCount = loopCount;
592}
593
594/*!
595 \property QAbstractAnimation::currentLoop
596 \brief the current loop of the animation
597
598 This property describes the current loop of the animation. By default,
599 the animation's loop count is 1, and so the current loop will
600 always be 0. If the loop count is 2 and the animation runs past its
601 duration, it will automatically rewind and restart at current time 0, and
602 current loop 1, and so on.
603
604 When the current loop changes, QAbstractAnimation emits the
605 currentLoopChanged() signal.
606*/
607int QAbstractAnimation::currentLoop() const
608{
609 Q_D(const QAbstractAnimation);
610 return d->currentLoop;
611}
612
613/*!
614 \fn virtual int QAbstractAnimation::duration() const = 0
615
616 This pure virtual function returns the duration of the animation, and
617 defines for how long QAbstractAnimation should update the current
618 time. This duration is local, and does not include the loop count.
619
620 A return value of -1 indicates that the animation has no defined duration;
621 the animation should run forever until stopped. This is useful for
622 animations that are not time driven, or where you cannot easily predict
623 its duration (e.g., event driven audio playback in a game).
624
625 If the animation is a parallel QAnimationGroup, the duration will be the longest
626 duration of all its animations. If the animation is a sequential QAnimationGroup,
627 the duration will be the sum of the duration of all its animations.
628 \sa loopCount
629*/
630
631/*!
632 Returns the total and effective duration of the animation, including the
633 loop count.
634
635 \sa duration(), currentTime
636*/
637int QAbstractAnimation::totalDuration() const
638{
639 int dura = duration();
640 if (dura <= 0)
641 return dura;
642 int loopcount = loopCount();
643 if (loopcount < 0)
644 return -1;
645 return dura * loopcount;
646}
647
648/*!
649 Returns the current time inside the current loop. It can go from 0 to duration().
650
651 \sa duration(), currentTime
652*/
653
654int QAbstractAnimation::currentLoopTime() const
655{
656 Q_D(const QAbstractAnimation);
657 return d->currentTime;
658}
659
660/*!
661 \property QAbstractAnimation::currentTime
662 \brief the current time and progress of the animation
663
664 This property describes the animation's current time. You can change the
665 current time by calling setCurrentTime, or you can call start() and let
666 the animation run, setting the current time automatically as the animation
667 progresses.
668
669 The animation's current time starts at 0, and ends at totalDuration().
670
671 \sa loopCount, currentLoopTime()
672 */
673int QAbstractAnimation::currentTime() const
674{
675 Q_D(const QAbstractAnimation);
676 return d->totalCurrentTime;
677}
678void QAbstractAnimation::setCurrentTime(int msecs)
679{
680 Q_D(QAbstractAnimation);
681 msecs = qMax(msecs, 0);
682
683 // Calculate new time and loop.
684 int dura = duration();
685 int totalDura = dura <= 0 ? dura : ((d->loopCount < 0) ? -1 : dura * d->loopCount);
686 if (totalDura != -1)
687 msecs = qMin(totalDura, msecs);
688 d->totalCurrentTime = msecs;
689
690 // Update new values.
691 int oldLoop = d->currentLoop;
692 d->currentLoop = ((dura <= 0) ? 0 : (msecs / dura));
693 if (d->currentLoop == d->loopCount) {
694 //we're at the end
695 d->currentTime = qMax(0, dura);
696 d->currentLoop = qMax(0, d->loopCount - 1);
697 } else {
698 if (d->direction == Forward) {
699 d->currentTime = (dura <= 0) ? msecs : (msecs % dura);
700 } else {
701 d->currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1;
702 if (d->currentTime == dura)
703 --d->currentLoop;
704 }
705 }
706
707 updateCurrentTime(d->currentTime);
708 if (d->currentLoop != oldLoop)
709 emit currentLoopChanged(d->currentLoop);
710
711 // All animations are responsible for stopping the animation when their
712 // own end state is reached; in this case the animation is time driven,
713 // and has reached the end.
714 if ((d->direction == Forward && d->totalCurrentTime == totalDura)
715 || (d->direction == Backward && d->totalCurrentTime == 0)) {
716 stop();
717 }
718}
719
720/*!
721 Starts the animation. The \a policy argument says whether or not the
722 animation should be deleted when it's done. When the animation starts, the
723 stateChanged() signal is emitted, and state() returns Running. When control
724 reaches the event loop, the animation will run by itself, periodically
725 calling updateCurrentTime() as the animation progresses.
726
727 If the animation is currently stopped or has already reached the end,
728 calling start() will rewind the animation and start again from the beginning.
729 When the animation reaches the end, the animation will either stop, or
730 if the loop level is more than 1, it will rewind and continue from the beginning.
731
732 If the animation is already running, this function does nothing.
733
734 \sa stop(), state()
735*/
736void QAbstractAnimation::start(DeletionPolicy policy)
737{
738 Q_D(QAbstractAnimation);
739 if (d->state == Running)
740 return;
741 d->deleteWhenStopped = policy;
742 d->setState(Running);
743}
744
745/*!
746 Stops the animation. When the animation is stopped, it emits the stateChanged()
747 signal, and state() returns Stopped. The current time is not changed.
748
749 If the animation stops by itself after reaching the end (i.e.,
750 currentLoopTime() == duration() and currentLoop() > loopCount() - 1), the
751 finished() signal is emitted.
752
753 \sa start(), state()
754 */
755void QAbstractAnimation::stop()
756{
757 Q_D(QAbstractAnimation);
758
759 d->setState(Stopped);
760}
761
762/*!
763 Pauses the animation. When the animation is paused, state() returns Paused.
764 The value of currentTime will remain unchanged until resume() or start()
765 is called. If you want to continue from the current time, call resume().
766
767 \sa start(), state(), resume()
768 */
769void QAbstractAnimation::pause()
770{
771 Q_D(QAbstractAnimation);
772 if (d->state == Stopped) {
773 qWarning("QAbstractAnimation::pause: Cannot pause a stopped animation");
774 return;
775 }
776
777 d->setState(Paused);
778}
779
780/*!
781 Resumes the animation after it was paused. When the animation is resumed,
782 it emits the resumed() and stateChanged() signals. The currenttime is not
783 changed.
784
785 \sa start(), pause(), state()
786 */
787void QAbstractAnimation::resume()
788{
789 Q_D(QAbstractAnimation);
790 if (d->state != Paused) {
791 qWarning("QAbstractAnimation::resume: "
792 "Cannot resume an animation that is not paused");
793 return;
794 }
795
796 d->setState(Running);
797}
798
799/*!
800 If \a paused is true, the animation is paused.
801 If \a paused is false, the animation is resumed.
802
803 \sa state(), pause(), resume()
804*/
805void QAbstractAnimation::setPaused(bool paused)
806{
807 if (paused)
808 pause();
809 else
810 resume();
811}
812
813
814/*!
815 \reimp
816*/
817bool QAbstractAnimation::event(QEvent *event)
818{
819 return QObject::event(event);
820}
821
822/*!
823 \fn virtual void QAbstractAnimation::updateCurrentTime(int currentTime) = 0;
824
825 This pure virtual function is called every time the animation's
826 \a currentTime changes.
827
828 \sa updateState()
829*/
830
831/*!
832 This virtual function is called by QAbstractAnimation when the state
833 of the animation is changed from \a oldState to \a newState.
834
835 \sa start(), stop(), pause(), resume()
836*/
837void QAbstractAnimation::updateState(QAbstractAnimation::State newState,
838 QAbstractAnimation::State oldState)
839{
840 Q_UNUSED(oldState);
841 Q_UNUSED(newState);
842}
843
844/*!
845 This virtual function is called by QAbstractAnimation when the direction
846 of the animation is changed. The \a direction argument is the new direction.
847
848 \sa setDirection(), direction()
849*/
850void QAbstractAnimation::updateDirection(QAbstractAnimation::Direction direction)
851{
852 Q_UNUSED(direction);
853}
854
855
856QT_END_NAMESPACE
857
858#include "moc_qabstractanimation.cpp"
859
860#endif //QT_NO_ANIMATION
Note: See TracBrowser for help on using the repository browser.