From 5bbb2e195b2cee8dbea0715ebf6eef41f36a3100 Mon Sep 17 00:00:00 2001 From: Charles Yin Date: Sat, 17 Mar 2012 00:26:58 +1000 Subject: [PATCH] Add a new running property to QQuickTransition This read only property can be used to track the transition running state. As all animation items inside a Transition item are just animation defination templetes, so their running properties won't be updated during the transition animations running, which makes it hard to know the current running state of a transition animation. Change-Id: If7fc0616ba384abc6bf2da67c7c639430c3d8fb9 Reviewed-by: Michael Brasser --- src/qml/animations/qabstractanimationjob.cpp | 1 - src/qml/animations/qabstractanimationjob_p.h | 1 - src/quick/util/qquicktransition.cpp | 106 ++++++++++++++------- src/quick/util/qquicktransition_p.h | 9 +- .../qquickanimations/tst_qquickanimations.cpp | 3 +- 5 files changed, 82 insertions(+), 38 deletions(-) diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index fecd8fb..d1b8880 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -567,7 +567,6 @@ void QAbstractAnimationJob::removeAnimationChangeListener(QAnimationJobChangeLis changeListeners.removeOne(ChangeListener(listener, changes)); } - QT_END_NAMESPACE //#include "moc_qabstractanimation2_p.cpp" diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h index e7d96dd..d26aa86 100644 --- a/src/qml/animations/qabstractanimationjob_p.h +++ b/src/qml/animations/qabstractanimationjob_p.h @@ -113,7 +113,6 @@ public: void addAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes); void removeAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes); - QAbstractAnimationJob *nextSibling() const { return m_nextSibling; } QAbstractAnimationJob *previousSibling() const { return m_previousSibling; } diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index 5d9a288..0f6ccb2 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -96,34 +96,6 @@ QT_BEGIN_NAMESPACE \sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtQml} */ -QQuickTransitionInstance::QQuickTransitionInstance() - : m_anim(0) -{ -} - -QQuickTransitionInstance::~QQuickTransitionInstance() -{ - delete m_anim; -} - -void QQuickTransitionInstance::start() -{ - if (m_anim) - m_anim->start(); -} - -void QQuickTransitionInstance::stop() -{ - if (m_anim) - m_anim->stop(); -} - -bool QQuickTransitionInstance::isRunning() const -{ - return m_anim && m_anim->state() == QAbstractAnimationJob::Running; -} - - //ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting //and disconnecting signals and slots frequently class ParallelAnimationWrapper : public QParallelAnimationGroupJob @@ -136,21 +108,32 @@ protected: virtual void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState); }; -class QQuickTransitionPrivate : public QObjectPrivate +class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener { Q_DECLARE_PUBLIC(QQuickTransition) public: QQuickTransitionPrivate() - : fromState(QLatin1String("*")), toState(QLatin1String("*")), - reversed(false), reversible(false), enabled(true) + : fromState(QLatin1String("*")), toState(QLatin1String("*")) + , runningInstanceCount(0), state(QAbstractAnimationJob::Stopped) + , reversed(false), reversible(false), enabled(true) { } + void removeStateChangeListener(QAbstractAnimationJob *anim) + { + if (anim) + anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + } + QString fromState; QString toState; + quint32 runningInstanceCount; + QAbstractAnimationJob::State state; bool reversed; bool reversible; bool enabled; +protected: + virtual void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State); static void append_animation(QQmlListProperty *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty *list); @@ -187,6 +170,21 @@ void QQuickTransitionPrivate::clear_animations(QQmlListPropertyrunningChanged(); + runningInstanceCount++; + } else if (newState == QAbstractAnimationJob::Stopped) { + runningInstanceCount--; + if (!runningInstanceCount) + emit q->runningChanged(); + } +} + void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) { QParallelAnimationGroupJob::updateState(newState, oldState); @@ -198,6 +196,34 @@ void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState } } +QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim) + : m_transition(transition) + , m_anim(anim) +{ +} + +QQuickTransitionInstance::~QQuickTransitionInstance() +{ + m_transition->removeStateChangeListener(m_anim); + delete m_anim; +} + +void QQuickTransitionInstance::start() +{ + if (m_anim) + m_anim->start(); +} + +void QQuickTransitionInstance::stop() +{ + if (m_anim) + m_anim->stop(); +} + +bool QQuickTransitionInstance::isRunning() const +{ + return m_anim && m_anim->state() == QAbstractAnimationJob::Running; +} QQuickTransition::QQuickTransition(QObject *parent) : QObject(*(new QQuickTransitionPrivate), parent) @@ -240,8 +266,8 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward); - QQuickTransitionInstance *wrapper = new QQuickTransitionInstance; - wrapper->m_anim = group; + group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange); + QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group); return wrapper; } @@ -386,6 +412,20 @@ void QQuickTransition::setEnabled(bool enabled) } /*! + \qmlproperty bool QtQuick2::Transition::running + + This property holds whether the transition is currently running. + + This property is read only. +*/ +bool QQuickTransition::running() const +{ + Q_D(const QQuickTransition); + return d->runningInstanceCount; +} + + +/*! \qmlproperty list QtQuick2::Transition::animations \default diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h index ebd82fd..976439c 100644 --- a/src/quick/util/qquicktransition_p.h +++ b/src/quick/util/qquicktransition_p.h @@ -43,6 +43,7 @@ #define QQUICKTRANSITION_H #include "qquickstate_p.h" +#include #include #include @@ -55,12 +56,11 @@ class QQuickAbstractAnimation; class QQuickTransitionPrivate; class QQuickTransitionManager; class QQuickTransition; -class QAbstractAnimationJob; class Q_QUICK_EXPORT QQuickTransitionInstance { public: - QQuickTransitionInstance(); + QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim); ~QQuickTransitionInstance(); void start(); @@ -69,6 +69,7 @@ public: bool isRunning() const; private: + QQuickTransitionPrivate *m_transition; QAbstractAnimationJob *m_anim; friend class QQuickTransition; }; @@ -81,6 +82,7 @@ class Q_QUICK_EXPORT QQuickTransition : public QObject Q_PROPERTY(QString from READ fromState WRITE setFromState NOTIFY fromChanged) Q_PROPERTY(QString to READ toState WRITE setToState NOTIFY toChanged) Q_PROPERTY(bool reversible READ reversible WRITE setReversible NOTIFY reversibleChanged) + Q_PROPERTY(bool running READ running NOTIFY runningChanged) Q_PROPERTY(QQmlListProperty animations READ animations) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_CLASSINFO("DefaultProperty", "animations") @@ -102,6 +104,8 @@ public: bool enabled() const; void setEnabled(bool enabled); + bool running() const; + QQmlListProperty animations(); QQuickTransitionInstance *prepare(QQuickStateOperation::ActionList &actions, @@ -116,6 +120,7 @@ Q_SIGNALS: void toChanged(); void reversibleChanged(); void enabledChanged(); + void runningChanged(); }; QT_END_NAMESPACE diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 166f4b8..878cd55 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -961,11 +961,12 @@ void tst_qquickanimations::disabledTransition() QCOMPARE(myRect->x(),qreal(200)); trans->setEnabled(true); - + QSignalSpy runningSpy(trans, SIGNAL(runningChanged())); QQuickItemPrivate::get(rect)->setState(""); QCOMPARE(myRect->x(),qreal(200)); QTest::qWait(300); QTIMED_COMPARE(myRect->x(),qreal(100)); + QCOMPARE(runningSpy.count(), 2); //stopped, running, stopped } void tst_qquickanimations::invalidDuration() -- 2.7.4