コード例 #1
0
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) {
            RETURN_IF_DELETED(change.listener->animationStateChanged(this, newState, oldState));
        }
    }
}
コード例 #2
0
void QAbstractAnimationJob::currentLoopChanged()
{
    for (int i = 0; i < changeListeners.count(); ++i) {
        const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
        if (change.types & QAbstractAnimationJob::CurrentLoop) {
           RETURN_IF_DELETED(change.listener->animationCurrentLoopChanged(this));
        }
    }
}
void QContinuingAnimationGroupJob::updateCurrentTime(int /*currentTime*/)
{
    Q_ASSERT(firstChild());

    for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
        if (animation->state() == state()) {
            RETURN_IF_DELETED(animation->setCurrentTime(m_currentTime));
        }
    }
}
コード例 #4
0
void QAbstractAnimationJob::currentTimeChanged(int currentTime)
{
    Q_ASSERT(m_hasCurrentTimeChangeListeners);

    for (int i = 0; i < changeListeners.count(); ++i) {
        const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
        if (change.types & QAbstractAnimationJob::CurrentTime) {
           RETURN_IF_DELETED(change.listener->animationCurrentTimeChanged(this, currentTime));
        }
    }
}
コード例 #5
0
void QSequentialAnimationGroupJob::updateCurrentTime(int currentTime)
{
    if (!m_currentAnimation)
        return;

    const QSequentialAnimationGroupJob::AnimationIndex newAnimationIndex = indexForCurrentTime();

    // newAnimationIndex.index is the new current animation
    if (m_previousLoop < m_currentLoop
        || (m_previousLoop == m_currentLoop && m_currentAnimation != newAnimationIndex.animation && newAnimationIndex.afterCurrent)) {
            // advancing with forward direction is the same as rewinding with backwards direction
            RETURN_IF_DELETED(advanceForwards(newAnimationIndex));
    } else if (m_previousLoop > m_currentLoop
        || (m_previousLoop == m_currentLoop && m_currentAnimation != newAnimationIndex.animation && !newAnimationIndex.afterCurrent)) {
            // rewinding with forward direction is the same as advancing with backwards direction
            RETURN_IF_DELETED(rewindForwards(newAnimationIndex));
    }

    setCurrentAnimation(newAnimationIndex.animation);

    const int newCurrentTime = currentTime - newAnimationIndex.timeOffset;

    if (m_currentAnimation) {
        RETURN_IF_DELETED(m_currentAnimation->setCurrentTime(newCurrentTime));
        if (atEnd()) {
            //we make sure that we don't exceed the duration here
            m_currentTime += m_currentAnimation->currentTime() - newCurrentTime;
            stop();
        }
    } else {
        //the only case where currentAnimation could be null
        //is when all animations have been removed
        Q_ASSERT(!firstChild());
        m_currentTime = 0;
        stop();
    }

    m_previousLoop = m_currentLoop;
}
コード例 #6
0
void QSequentialAnimationGroupJob::advanceForwards(const AnimationIndex &newAnimationIndex)
{
    if (m_previousLoop < m_currentLoop) {
        // we need to fast forward to the end
        for (QAbstractAnimationJob *anim = m_currentAnimation; anim; anim = anim->nextSibling()) {
            setCurrentAnimation(anim, true);
            RETURN_IF_DELETED(anim->setCurrentTime(animationActualTotalDuration(anim)));
        }
        // this will make sure the current animation is reset to the beginning
        if (firstChild() && !firstChild()->nextSibling())   //count == 1
            // we need to force activation because setCurrentAnimation will have no effect
            activateCurrentAnimation();
        else
            setCurrentAnimation(firstChild(), true);
    }

    // and now we need to fast forward from the current position to
    for (QAbstractAnimationJob *anim = m_currentAnimation; anim && anim != newAnimationIndex.animation; anim = anim->nextSibling()) {     //### WRONG,
        setCurrentAnimation(anim, true);
        RETURN_IF_DELETED(anim->setCurrentTime(animationActualTotalDuration(anim)));
    }
    // setting the new current animation will happen later
}
コード例 #7
0
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) {
            RETURN_IF_DELETED(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);
    }
}
コード例 #8
0
void QSequentialAnimationGroupJob::rewindForwards(const AnimationIndex &newAnimationIndex)
{
    if (m_previousLoop > m_currentLoop) {
        // we need to fast rewind to the beginning
        for (QAbstractAnimationJob *anim = m_currentAnimation; anim; anim = anim->previousSibling()) {
            setCurrentAnimation(anim, true);
            RETURN_IF_DELETED(anim->setCurrentTime(0));
        }
        // this will make sure the current animation is reset to the end
        if (lastChild() && !lastChild()->previousSibling())   //count == 1
            // we need to force activation because setCurrentAnimation will have no effect
            activateCurrentAnimation();
        else {
            setCurrentAnimation(lastChild(), true);
        }
    }

    // and now we need to fast rewind from the current position to
    for (QAbstractAnimationJob *anim = m_currentAnimation; anim && anim != newAnimationIndex.animation; anim = anim->previousSibling()) {
        setCurrentAnimation(anim, true);
        RETURN_IF_DELETED(anim->setCurrentTime(0));
    }
    // setting the new current animation will happen later
}
コード例 #9
0
void QSequentialAnimationGroupJob::activateCurrentAnimation(bool intermediate)
{
    if (!m_currentAnimation || isStopped())
        return;

    m_currentAnimation->stop();

    // we ensure the direction is consistent with the group's direction
    m_currentAnimation->setDirection(m_direction);

    // reset the finish time of the animation if it is uncontrolled
    if (m_currentAnimation->totalDuration() == -1)
        resetUncontrolledAnimationFinishTime(m_currentAnimation);

    RETURN_IF_DELETED(m_currentAnimation->start());
    if (!intermediate && isPaused())
        m_currentAnimation->pause();
}
コード例 #10
0
void QAbstractAnimationJob::setCurrentTime(int msecs)
{
    msecs = qMax(msecs, 0);
    // Calculate new time and loop.
    int dura = duration();
    int totalDura;
    int oldLoop = m_currentLoop;

    if (dura < 0 && m_direction == Forward)  {
        totalDura = -1;
        if (m_uncontrolledFinishTime >= 0 && msecs >= m_uncontrolledFinishTime) {
            msecs = m_uncontrolledFinishTime;
            if (m_currentLoop == m_loopCount - 1) {
                totalDura = m_uncontrolledFinishTime;
            } else {
                ++m_currentLoop;
                m_currentLoopStartTime = msecs;
                m_uncontrolledFinishTime = -1;
            }
        }
        m_totalCurrentTime = msecs;
        m_currentTime = msecs - m_currentLoopStartTime;
    } else {
        totalDura = dura <= 0 ? dura : ((m_loopCount < 0) ? -1 : dura * m_loopCount);
        if (totalDura != -1)
            msecs = qMin(totalDura, msecs);
        m_totalCurrentTime = msecs;

        // Update new values.
        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?
        fireTopLevelAnimationLoopChanged();

    RETURN_IF_DELETED(updateCurrentTime(m_currentTime));

    if (m_currentLoop != oldLoop)
        currentLoopChanged();

    // 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)) {
        RETURN_IF_DELETED(stop());
    }

    if (m_hasCurrentTimeChangeListeners)
        currentTimeChanged(m_currentTime);
}
コード例 #11
0
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());

        // Reset uncontrolled finish time and currentLoopStartTime for this run.
        m_uncontrolledFinishTime = -1;
        if (!m_group)
            m_currentLoopStartTime = m_totalCurrentTime;
    }

    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)
            QQmlAnimationTimer::ensureTimerUpdate();
        //the animation, is not running any more
        QQmlAnimationTimer::unregisterAnimation(this);
    } else if (newState == Running) {
        QQmlAnimationTimer::registerAnimation(this, isTopLevel);
    }

    //starting an animation qualifies as a top level loop change
    if (newState == Running && oldState == Stopped && !m_group)
        fireTopLevelAnimationLoopChanged();

    RETURN_IF_DELETED(updateState(newState, oldState));

    if (newState != m_state) //this is to be safe if updateState changes the state
        return;

    // Notify state change
    RETURN_IF_DELETED(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) {
                m_currentLoop = 0;
                if (isTopLevel) {
                    // currentTime needs to be updated if pauseTimer is active
                    RETURN_IF_DELETED(QQmlAnimationTimer::ensureTimerUpdate());
                    RETURN_IF_DELETED(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;
    }
}