aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/animations/qabstractanimationjob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/animations/qabstractanimationjob.cpp')
-rw-r--r--src/declarative/animations/qabstractanimationjob.cpp544
1 files changed, 0 insertions, 544 deletions
diff --git a/src/declarative/animations/qabstractanimationjob.cpp b/src/declarative/animations/qabstractanimationjob.cpp
deleted file mode 100644
index 4d149ce99a..0000000000
--- a/src/declarative/animations/qabstractanimationjob.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qthreadstorage.h>
-
-#include "private/qabstractanimationjob_p.h"
-#include "private/qanimationgroupjob_p.h"
-#include "private/qanimationjobutil_p.h"
-
-#define DEFAULT_TIMER_INTERVAL 16
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_THREAD
-Q_GLOBAL_STATIC(QThreadStorage<QDeclarativeAnimationTimer *>, animationTimer)
-#endif
-
-QDeclarativeAnimationTimer::QDeclarativeAnimationTimer() :
- QAbstractAnimationTimer(), lastTick(0), lastDelta(0),
- currentAnimationIdx(0), insideTick(false),
- startAnimationPending(false), stopTimerPending(false),
- runningLeafAnimations(0)
-{
-}
-
-QDeclarativeAnimationTimer *QDeclarativeAnimationTimer::instance(bool create)
-{
- QDeclarativeAnimationTimer *inst;
-#ifndef QT_NO_THREAD
- if (create && !animationTimer()->hasLocalData()) {
- inst = new QDeclarativeAnimationTimer;
- animationTimer()->setLocalData(inst);
- } else {
- inst = animationTimer() ? animationTimer()->localData() : 0;
- }
-#else
- static QAnimationTimer unifiedTimer;
- inst = &unifiedTimer;
-#endif
- return inst;
-}
-
-QDeclarativeAnimationTimer *QDeclarativeAnimationTimer::instance()
-{
- return instance(true);
-}
-
-void QDeclarativeAnimationTimer::ensureTimerUpdate()
-{
- QDeclarativeAnimationTimer *inst = QDeclarativeAnimationTimer::instance(false);
- QUnifiedTimer *instU = QUnifiedTimer::instance(false);
- if (instU && inst && inst->isPaused)
- instU->updateAnimationTimers(-1);
-}
-
-void QDeclarativeAnimationTimer::updateAnimationsTime(qint64 delta)
-{
- //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
- if (insideTick)
- return;
-
- lastTick += delta;
- lastDelta = delta;
-
- //we make sure we only call update time if the time has actually changed
- //it might happen in some cases that the time doesn't change because events are delayed
- //when the CPU load is high
- if (delta) {
- insideTick = true;
- for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
- QAbstractAnimationJob *animation = animations.at(currentAnimationIdx);
- int elapsed = animation->m_totalCurrentTime
- + (animation->direction() == QAbstractAnimationJob::Forward ? delta : -delta);
- animation->setCurrentTime(elapsed);
- }
- insideTick = false;
- currentAnimationIdx = 0;
- }
-}
-
-void QDeclarativeAnimationTimer::updateAnimationTimer()
-{
- QDeclarativeAnimationTimer *inst = QDeclarativeAnimationTimer::instance(false);
- if (inst)
- inst->restartAnimationTimer();
-}
-
-void QDeclarativeAnimationTimer::restartAnimationTimer()
-{
- if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty())
- QUnifiedTimer::pauseAnimationTimer(this, closestPauseAnimationTimeToFinish());
- else if (isPaused)
- QUnifiedTimer::resumeAnimationTimer(this);
- else if (!isRegistered)
- QUnifiedTimer::startAnimationTimer(this);
-}
-
-void QDeclarativeAnimationTimer::startAnimations()
-{
- startAnimationPending = false;
- //force timer to update, which prevents large deltas for our newly added animations
- if (!animations.isEmpty())
- QUnifiedTimer::instance()->maybeUpdateAnimationsToCurrentTime();
-
- //we transfer the waiting animations into the "really running" state
- animations += animationsToStart;
- animationsToStart.clear();
- if (!animations.isEmpty())
- restartAnimationTimer();
-}
-
-void QDeclarativeAnimationTimer::stopTimer()
-{
- stopTimerPending = false;
- if (animations.isEmpty()) {
- QUnifiedTimer::resumeAnimationTimer(this);
- QUnifiedTimer::stopAnimationTimer(this);
- // invalidate the start reference time
- lastTick = 0;
- lastDelta = 0;
- }
-}
-
-void QDeclarativeAnimationTimer::registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel)
-{
- QDeclarativeAnimationTimer *inst = instance(true); //we create the instance if needed
- inst->registerRunningAnimation(animation);
- if (isTopLevel) {
- Q_ASSERT(!animation->m_hasRegisteredTimer);
- animation->m_hasRegisteredTimer = true;
- inst->animationsToStart << animation;
- if (!inst->startAnimationPending) {
- inst->startAnimationPending = true;
- QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection);
- }
- }
-}
-
-void QDeclarativeAnimationTimer::unregisterAnimation(QAbstractAnimationJob *animation)
-{
- QDeclarativeAnimationTimer *inst = QDeclarativeAnimationTimer::instance(false);
- if (inst) {
- //at this point the unified timer should have been created
- //but it might also have been already destroyed in case the application is shutting down
-
- inst->unregisterRunningAnimation(animation);
-
- if (!animation->m_hasRegisteredTimer)
- return;
-
- int idx = inst->animations.indexOf(animation);
- if (idx != -1) {
- inst->animations.removeAt(idx);
- // this is needed if we unregister an animation while its running
- if (idx <= inst->currentAnimationIdx)
- --inst->currentAnimationIdx;
-
- if (inst->animations.isEmpty() && !inst->stopTimerPending) {
- inst->stopTimerPending = true;
- QMetaObject::invokeMethod(inst, "stopTimer", Qt::QueuedConnection);
- }
- } else {
- inst->animationsToStart.removeOne(animation);
- }
- }
- animation->m_hasRegisteredTimer = false;
-}
-
-void QDeclarativeAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animation)
-{
- if (animation->m_isGroup)
- return;
-
- if (animation->m_isPause) {
- runningPauseAnimations << animation;
- } else
- runningLeafAnimations++;
-}
-
-void QDeclarativeAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *animation)
-{
- if (animation->m_isGroup)
- return;
-
- if (animation->m_isPause)
- runningPauseAnimations.removeOne(animation);
- else
- runningLeafAnimations--;
- Q_ASSERT(runningLeafAnimations >= 0);
-}
-
-int QDeclarativeAnimationTimer::closestPauseAnimationTimeToFinish()
-{
- int closestTimeToFinish = INT_MAX;
- for (int i = 0; i < runningPauseAnimations.size(); ++i) {
- QAbstractAnimationJob *animation = runningPauseAnimations.at(i);
- int timeToFinish;
-
- if (animation->direction() == QAbstractAnimationJob::Forward)
- timeToFinish = animation->duration() - animation->currentLoopTime();
- else
- timeToFinish = animation->currentLoopTime();
-
- if (timeToFinish < closestTimeToFinish)
- closestTimeToFinish = timeToFinish;
- }
- return closestTimeToFinish;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-QAbstractAnimationJob::QAbstractAnimationJob()
- : m_isPause(false)
- , m_isGroup(false)
- , m_loopCount(1)
- , m_group(0)
- , m_direction(QAbstractAnimationJob::Forward)
- , m_state(QAbstractAnimationJob::Stopped)
- , m_totalCurrentTime(0)
- , m_currentTime(0)
- , m_currentLoop(0)
- , m_hasRegisteredTimer(false)
- , m_uncontrolledFinishTime(-1)
- , m_wasDeleted(0)
- , m_nextSibling(0)
- , m_previousSibling(0)
-{
-}
-
-QAbstractAnimationJob::~QAbstractAnimationJob()
-{
- if (m_wasDeleted)
- *m_wasDeleted = true;
-
- //we can't call stop here. Otherwise we get pure virtual calls
- if (m_state != Stopped) {
- State oldState = m_state;
- m_state = Stopped;
- stateChanged(oldState, m_state);
- if (oldState == Running)
- QDeclarativeAnimationTimer::unregisterAnimation(this);
- }
-
- if (m_group)
- m_group->removeAnimation(this);
-}
-
-void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
-{
- if (m_state == newState)
- return;
-
- if (m_loopCount == 0)
- return;
-
- State oldState = m_state;
- int oldCurrentTime = m_currentTime;
- int oldCurrentLoop = m_currentLoop;
- Direction oldDirection = m_direction;
-
- // check if we should Rewind
- if ((newState == Paused || newState == Running) && oldState == Stopped) {
- //here we reset the time if needed
- //we don't call setCurrentTime because this might change the way the animation
- //behaves: changing the state or changing the current value
- m_totalCurrentTime = m_currentTime = (m_direction == Forward) ?
- 0 : (m_loopCount == -1 ? duration() : totalDuration());
- }
-
- m_state = newState;
- //(un)registration of the animation must always happen before calls to
- //virtual function (updateState) to ensure a correct state of the timer
- bool isTopLevel = !m_group || m_group->isStopped();
- if (oldState == Running) {
- if (newState == Paused && m_hasRegisteredTimer)
- QDeclarativeAnimationTimer::ensureTimerUpdate();
- //the animation, is not running any more
- QDeclarativeAnimationTimer::unregisterAnimation(this);
- } else if (newState == Running) {
- QDeclarativeAnimationTimer::registerAnimation(this, isTopLevel);
- }
-
- //starting an animation qualifies as a top level loop change
- if (newState == Running && oldState == Stopped && !m_group)
- topLevelAnimationLoopChanged();
-
- RETURN_IF_DELETED(updateState(newState, oldState));
-
- if (newState != m_state) //this is to be safe if updateState changes the state
- return;
-
- // Notify state change
- stateChanged(newState, oldState);
- if (newState != m_state) //this is to be safe if updateState changes the state
- return;
-
- switch (m_state) {
- case Paused:
- break;
- case Running:
- {
- // this ensures that the value is updated now that the animation is running
- if (oldState == Stopped) {
- if (isTopLevel) {
- // currentTime needs to be updated if pauseTimer is active
- QDeclarativeAnimationTimer::ensureTimerUpdate();
- setCurrentTime(m_totalCurrentTime);
- }
- }
- }
- break;
- case Stopped:
- // Leave running state.
- int dura = duration();
-
- if (dura == -1 || m_loopCount < 0
- || (oldDirection == Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * m_loopCount))
- || (oldDirection == Backward && oldCurrentTime == 0)) {
- finished();
- }
- break;
- }
-}
-
-void QAbstractAnimationJob::setDirection(Direction direction)
-{
- if (m_direction == direction)
- return;
-
- if (m_state == Stopped) {
- if (m_direction == Backward) {
- m_currentTime = duration();
- m_currentLoop = m_loopCount - 1;
- } else {
- m_currentTime = 0;
- m_currentLoop = 0;
- }
- }
-
- // the commands order below is important: first we need to setCurrentTime with the old direction,
- // then update the direction on this and all children and finally restart the pauseTimer if needed
- if (m_hasRegisteredTimer)
- QDeclarativeAnimationTimer::ensureTimerUpdate();
-
- m_direction = direction;
- updateDirection(direction);
-
- if (m_hasRegisteredTimer)
- // needed to update the timer interval in case of a pause animation
- QDeclarativeAnimationTimer::updateAnimationTimer();
-}
-
-void QAbstractAnimationJob::setLoopCount(int loopCount)
-{
- m_loopCount = loopCount;
-}
-
-int QAbstractAnimationJob::totalDuration() const
-{
- int dura = duration();
- if (dura <= 0)
- return dura;
- int loopcount = loopCount();
- if (loopcount < 0)
- return -1;
- return dura * loopcount;
-}
-
-void QAbstractAnimationJob::setCurrentTime(int msecs)
-{
- msecs = qMax(msecs, 0);
- // Calculate new time and loop.
- int dura = duration();
- int totalDura = dura <= 0 ? dura : ((m_loopCount < 0) ? -1 : dura * m_loopCount);
- if (totalDura != -1)
- msecs = qMin(totalDura, msecs);
- m_totalCurrentTime = msecs;
-
- // Update new values.
- int oldLoop = m_currentLoop;
- m_currentLoop = ((dura <= 0) ? 0 : (msecs / dura));
- if (m_currentLoop == m_loopCount) {
- //we're at the end
- m_currentTime = qMax(0, dura);
- m_currentLoop = qMax(0, m_loopCount - 1);
- } else {
- if (m_direction == Forward) {
- m_currentTime = (dura <= 0) ? msecs : (msecs % dura);
- } else {
- m_currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1;
- if (m_currentTime == dura)
- --m_currentLoop;
- }
- }
-
- if (m_currentLoop != oldLoop && !m_group) //### verify Running as well?
- topLevelAnimationLoopChanged();
-
- RETURN_IF_DELETED(updateCurrentTime(m_currentTime));
-
- if (m_currentLoop != oldLoop)
- currentLoopChanged(m_currentLoop);
-
- // All animations are responsible for stopping the animation when their
- // own end state is reached; in this case the animation is time driven,
- // and has reached the end.
- if ((m_direction == Forward && m_totalCurrentTime == totalDura)
- || (m_direction == Backward && m_totalCurrentTime == 0)) {
- stop();
- }
-}
-
-void QAbstractAnimationJob::start()
-{
- if (m_state == Running)
- return;
- setState(Running);
-}
-
-void QAbstractAnimationJob::stop()
-{
- if (m_state == Stopped)
- return;
- setState(Stopped);
-}
-
-void QAbstractAnimationJob::pause()
-{
- if (m_state == Stopped) {
- qWarning("QAbstractAnimationJob::pause: Cannot pause a stopped animation");
- return;
- }
-
- setState(Paused);
-}
-
-void QAbstractAnimationJob::resume()
-{
- if (m_state != Paused) {
- qWarning("QAbstractAnimationJob::resume: "
- "Cannot resume an animation that is not paused");
- return;
- }
- setState(Running);
-}
-
-void QAbstractAnimationJob::updateState(QAbstractAnimationJob::State newState,
- QAbstractAnimationJob::State oldState)
-{
- Q_UNUSED(oldState);
- Q_UNUSED(newState);
-}
-
-void QAbstractAnimationJob::updateDirection(QAbstractAnimationJob::Direction direction)
-{
- Q_UNUSED(direction);
-}
-
-void QAbstractAnimationJob::finished()
-{
- //TODO: update this code so it is valid to delete the animation in animationFinished
- for (int i = 0; i < changeListeners.count(); ++i) {
- const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
- if (change.types & QAbstractAnimationJob::Completion)
- change.listener->animationFinished(this);
- }
-
- if (m_group && (duration() == -1 || loopCount() < 0)) {
- //this is an uncontrolled animation, need to notify the group animation we are finished
- m_group->uncontrolledAnimationFinished(this);
- }
-}
-
-void QAbstractAnimationJob::stateChanged(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState)
-{
- for (int i = 0; i < changeListeners.count(); ++i) {
- const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
- if (change.types & QAbstractAnimationJob::StateChange)
- change.listener->animationStateChanged(this, newState, oldState);
- }
-}
-
-void QAbstractAnimationJob::currentLoopChanged(int currentLoop)
-{
- Q_UNUSED(currentLoop);
- for (int i = 0; i < changeListeners.count(); ++i) {
- const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
- if (change.types & QAbstractAnimationJob::CurrentLoop)
- change.listener->animationCurrentLoopChanged(this);
- }
-}
-
-void QAbstractAnimationJob::addAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes changes)
-{
- changeListeners.append(ChangeListener(listener, changes));
-}
-
-void QAbstractAnimationJob::removeAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes changes)
-{
- changeListeners.removeOne(ChangeListener(listener, changes));
-}
-
-
-QT_END_NAMESPACE
-
-//#include "moc_qabstractanimation2_p.cpp"