From: Charles Yin Date: Wed, 7 Mar 2012 14:12:58 +0000 (+1000) Subject: More refactoring on animation controller X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=c67ed6887a8ee2fac935d81630b4b77926486c9b;p=konrad%2Fqtdeclarative.git More refactoring on animation controller Add a flag and helper functions for disabling user control in QAbstractAnimationJob class and make it synchronized with QDeclarativeAnimation class's disableUserControl flag. Change-Id: Ifa84ab0c78291941469c33f2cafe5f61ee718b2c Reviewed-by: Michael Brasser --- diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index a540382..fecd8fb 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -161,6 +161,9 @@ void QQmlAnimationTimer::stopTimer() void QQmlAnimationTimer::registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel) { + if (animation->userControlDisabled()) + return; + QQmlAnimationTimer *inst = instance(true); //we create the instance if needed inst->registerRunningAnimation(animation); if (isTopLevel) { @@ -206,6 +209,8 @@ void QQmlAnimationTimer::unregisterAnimation(QAbstractAnimationJob *animation) void QQmlAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animation) { + Q_ASSERT(!animation->userControlDisabled()); + if (animation->m_isGroup) return; @@ -217,6 +222,9 @@ void QQmlAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animati void QQmlAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *animation) { + if (animation->userControlDisabled()) + return; + if (animation->m_isGroup) return; @@ -248,20 +256,21 @@ int QQmlAnimationTimer::closestPauseAnimationTimeToFinish() ///////////////////////////////////////////////////////////////////////////////////////////////////////// QAbstractAnimationJob::QAbstractAnimationJob() - : m_isPause(false) - , m_isGroup(false) - , m_loopCount(1) + : 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) + , m_wasDeleted(0) + , m_hasRegisteredTimer(false) + , m_isPause(false) + , m_isGroup(false) + , m_disableUserControl(false) { } @@ -482,6 +491,23 @@ void QAbstractAnimationJob::resume() setState(Running); } +void QAbstractAnimationJob::setEnableUserControl() +{ + m_disableUserControl = false; +} + +bool QAbstractAnimationJob::userControlDisabled() const +{ + return m_disableUserControl; +} + +void QAbstractAnimationJob::setDisableUserControl() +{ + m_disableUserControl = true; + start(); + pause(); +} + void QAbstractAnimationJob::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) { diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h index f00090c..e7d96dd 100644 --- a/src/qml/animations/qabstractanimationjob_p.h +++ b/src/qml/animations/qabstractanimationjob_p.h @@ -93,6 +93,9 @@ public: inline bool isRunning() { return m_state == Running; } inline bool isStopped() { return m_state == Stopped; } inline bool isPaused() { return m_state == Paused; } + void setDisableUserControl(); + void setEnableUserControl(); + bool userControlDisabled() const; void setCurrentTime(int msecs); @@ -128,8 +131,6 @@ protected: void directionChanged(QAbstractAnimationJob::Direction); //definition - bool m_isPause; - bool m_isGroup; int m_loopCount; QAnimationGroupJob *m_group; QAbstractAnimationJob::Direction m_direction; @@ -139,10 +140,8 @@ protected: int m_totalCurrentTime; int m_currentTime; int m_currentLoop; - bool m_hasRegisteredTimer; //records the finish time for an uncontrolled animation (used by animation groups) int m_uncontrolledFinishTime; - bool *m_wasDeleted; struct ChangeListener { ChangeListener(QAnimationJobChangeListener *l, QAbstractAnimationJob::ChangeTypes t) : listener(l), types(t) {} @@ -155,6 +154,12 @@ protected: QAbstractAnimationJob *m_nextSibling; QAbstractAnimationJob *m_previousSibling; + bool *m_wasDeleted; + bool m_hasRegisteredTimer:1; + bool m_isPause:1; + bool m_isGroup:1; + bool m_disableUserControl:1; + friend class QQmlAnimationTimer; friend class QAnimationGroupJob; }; diff --git a/src/quick/util/qquickanimationcontroller.cpp b/src/quick/util/qquickanimationcontroller.cpp index a3e343f..2b5d174 100644 --- a/src/quick/util/qquickanimationcontroller.cpp +++ b/src/quick/util/qquickanimationcontroller.cpp @@ -174,6 +174,7 @@ void QQuickAnimationController::reload() if (oldInstance && oldInstance != d->animationInstance) delete oldInstance; d->animationInstance->setLoopCount(1); + d->animationInstance->setDisableUserControl(); d->animationInstance->start(); d->animationInstance->pause(); updateProgress(); @@ -186,6 +187,7 @@ void QQuickAnimationController::updateProgress() if (!d->animationInstance) return; + d->animationInstance->setDisableUserControl(); d->animationInstance->start(); QQmlAnimationTimer::unregisterAnimation(d->animationInstance); d->animationInstance->setCurrentTime(d->progress * d->animationInstance->duration()); diff --git a/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml b/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml new file mode 100755 index 0000000..92e27b9 --- /dev/null +++ b/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml @@ -0,0 +1,38 @@ +import QtQuick 2.0 +import QtTest 1.0 + +Rectangle { + id:container + width:50 + height:50 + + Rectangle {id:rect; x:0; y:0; color:"red"; width:10; height:10} + AnimationController { + id:colorAnimationcontroller + progress:1 + animation: ColorAnimation {id:anim; target: rect; property:"color"; to:"#FFFFFF"; from:"#000000"; duration: 1000} + } + + TestCase { + name:"AnimationController" + when:windowShown + function test_colorAnimation() { + colorAnimationcontroller.progress = 0; + compare(rect.color.toString(), "#000000"); + colorAnimationcontroller.progress = 0.5; + compare(rect.color.toString(), "#7f7f7f"); + + // <=0 -> 0 + colorAnimationcontroller.progress = -1; + compare(rect.color, "#000000"); + + //>=1 -> 1 + colorAnimationcontroller.progress = 1.1; + compare(rect.color.toString(), "#ffffff"); + + //make sure the progress can be set backward + colorAnimationcontroller.progress = 0.5; + compare(rect.color, "#7f7f7f"); + } + } +} \ No newline at end of file diff --git a/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml b/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml new file mode 100644 index 0000000..1a17a1a --- /dev/null +++ b/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml @@ -0,0 +1,63 @@ +import QtQuick 2.0 +import QtTest 1.0 + +Rectangle { + id:container + width:100 + height:100 + + Rectangle {id:rect; x:0; y:0; color:"red"; width:10; height:10} + AnimationController { + id:controller + progress:0 + animation: ParallelAnimation { + id:anim + NumberAnimation { target: rect; property: "x"; from:0; to: 50; duration: 1000 } + NumberAnimation { target: rect; property: "y"; from:0; to: 100; duration: 1000 } + NumberAnimation { target: rect; property: "height"; from:10; to: 50; duration: 1000 } + NumberAnimation { target: rect; property: "width"; from:10; to: 50; duration: 1000 } + ColorAnimation {target:rect; property:"color"; from:"red"; to:"blue"; duration:1000 } + } + } + + TestCase { + name:"AnimationController" + when:windowShown + function test_parallelAnimation_data() { + //FIXME:the commented lines fail on MAC OS X + return [ + {tag:"0.1",progress:0.1, x:5, y:10, color:"#e50019", width:14, height:14}, + //{tag:"0.2",progress:0.2, x:10, y:20, color:"#cb0033", width:18, height:18}, + {tag:"0.30000000000000004",progress:0.30000000000000004, x:15, y:30, color:"#b2004c", width:22, height:22}, + //{tag:"0.4",progress:0.4, x:20, y:40, color:"#980066", width:26, height:26}, + {tag:"0.5",progress:0.5, x:25, y:50, color:"#7f007f", width:30, height:30}, + {tag:"0.6",progress:0.59999999, x:29.95, y:59.9, color:"#660098", width:33.96, height:33.96}, + {tag:"0.7",progress:0.69999999, x:34.949999999999996, y:69.89999999999999, color:"#4c00b2", width:37.96, height:37.96}, + {tag:"0.7999999999999999",progress:0.7999999999999999, x:39.95, y:79.9, color:"#3300cb", width:41.96, height:41.96}, + {tag:"0.8999999999999999",progress:0.8999999999999999, x:44.95, y:89.9, color:"#1900e5", width:45.96, height:45.96}, + {tag:"0.9999999999999999",progress:0.9999999999999999, x:49.95, y:99.9, color:"#0000fe", width:49.96, height:49.96}, + {tag:"1",progress:1, x:50, y:100, color:"#0000ff", width:50, height:50}, + {tag:"0.9",progress:0.9, x:45, y:90, color:"#1900e5", width:46, height:46}, + //{tag:"0.8",progress:0.8, x:40, y:80, color:"#3200cc", width:42, height:42}, + {tag:"0.7000000000000001",progress:0.7000000000000001, x:35, y:70, color:"#4c00b2", width:38, height:38}, + //{tag:"0.6000000000000001",progress:0.6000000000000001, x:30, y:60, color:"#660098", width:34, height:34}, + {tag:"0.5000000000000001",progress:0.5000000000000001, x:25, y:50, color:"#7f007f", width:30, height:30}, + //{tag:"0.40000000000000013",progress:0.40000000000000013, x:20, y:40, color:"#980066", width:26, height:26}, + {tag:"0.30000000000000016",progress:0.30000000000000016, x:15, y:30, color:"#b2004c", width:22, height:22}, + //{tag:"0.20000000000000015",progress:0.19999999999999999, x:10, y:20, color:"#cb0033", width:18, height:18}, + {tag:"0.10000000000000014",progress:0.10000000000000014, x:5, y:10, color:"#e50019", width:14, height:14}, + {tag:"1.3877787807814457e-16",progress:1.3877787807814457e-16, x:0, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0",progress:0, x:0, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0.1",progress:0.1, x:5, y:10, color:"#e50019", width:14, height:14} + ]; + } + function test_parallelAnimation(row) { + controller.progress = row.progress; + compare(rect.x, row.x); + compare(rect.y, row.y); + compare(rect.width, row.width); + compare(rect.height, row.height); + compare(rect.color.toString(), row.color); + } + } +} diff --git a/tests/auto/quick/qquickanimationcontroller/data/tst_sequentialanimation.qml b/tests/auto/quick/qquickanimationcontroller/data/tst_sequentialanimation.qml new file mode 100644 index 0000000..59671f5 --- /dev/null +++ b/tests/auto/quick/qquickanimationcontroller/data/tst_sequentialanimation.qml @@ -0,0 +1,65 @@ +import QtQuick 2.0 +import QtTest 1.0 + +Rectangle { + id:container + width:100 + height:100 + + Rectangle {id:rect; x:0; y:0; color:"red"; width:10; height:10} + AnimationController { + id:controller + progress:0 + animation: SequentialAnimation { + id:anim + NumberAnimation { target: rect; property: "x"; from:0; to: 50; duration: 1000 } + NumberAnimation { target: rect; property: "y"; from:0; to: 100; duration: 1000 } + NumberAnimation { target: rect; property: "height"; from:10; to: 50; duration: 1000 } + NumberAnimation { target: rect; property: "width"; from:10; to: 50; duration: 1000 } + ColorAnimation {target:rect; property:"color"; from:"red"; to:"blue"; duration:1000 } + } + } + + + TestCase { + name:"AnimationController" + when:windowShown + function test_sequentialAnimation_data() { + return [ + {tag:"0.1",progress:0.1, x:25, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0.2",progress:0.2, x:50, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0.30000000000000004",progress:0.30000000000000004, x:50, y:50, color:"#ff0000", width:10, height:10}, + {tag:"0.4",progress:0.4, x:50, y:100, color:"#ff0000", width:10, height:10}, + {tag:"0.5",progress:0.5, x:50, y:100, color:"#ff0000", width:10, height:30}, + {tag:"0.6",progress:0.5999999999999, x:50, y:100, color:"#ff0000", width:10, height:49.96}, + {tag:"0.7",progress:0.6999999999999, x:50, y:100, color:"#ff0000", width:29.96, height:50}, + {tag:"0.7999999999999999",progress:0.7999999999999999, x:50, y:100, color:"#ff0000", width:49.96, height:50}, + {tag:"0.8999999999999999",progress:0.8999999999999999, x:50, y:100, color:"#7f007f", width:50, height:50}, + {tag:"0.9999999999999999",progress:0.9999999999999999, x:50, y:100, color:"#0000fe", width:50, height:50}, + {tag:"1",progress:1, x:50, y:100, color:"#0000ff", width:50, height:50}, + {tag:"0.9",progress:0.9, x:50, y:100, color:"#7f007f", width:50, height:50}, + {tag:"0.8",progress:0.8, x:50, y:100, color:"#ff0000", width:50, height:50}, + {tag:"0.7000000000000001",progress:0.7000000000000001, x:50, y:100, color:"#ff0000", width:30, height:50}, + {tag:"0.6000000000000001",progress:0.6000000000000001, x:50, y:100, color:"#ff0000", width:10, height:50}, + {tag:"0.5000000000000001",progress:0.5000000000000001, x:50, y:100, color:"#ff0000", width:10, height:30}, + {tag:"0.40000000000000013",progress:0.40000000000000013, x:50, y:100, color:"#ff0000", width:10, height:10}, + {tag:"0.30000000000000016",progress:0.30000000000000016, x:50, y:50, color:"#ff0000", width:10, height:10}, + {tag:"0.20000000000000015",progress:0.20000000000000015, x:50, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0.10000000000000014",progress:0.10000000000000014, x:25, y:0, color:"#ff0000", width:10, height:10}, + {tag:"1.3877787807814457e-16",progress:1.3877787807814457e-16, x:0, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0",progress:0, x:0, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0.1",progress:0.1, x:25, y:0, color:"#ff0000", width:10, height:10}, + {tag:"0.2",progress:0.2, x:50, y:0, color:"#ff0000", width:10, height:10} + + ]; + } + function test_sequentialAnimation(row) { + controller.progress = row.progress; + compare(rect.x, row.x); + compare(rect.y, row.y); + compare(rect.width, row.width); + compare(rect.height, row.height); + compare(rect.color.toString(), row.color); + } + } +} diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 4065dbf..c8014be 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -18,6 +18,7 @@ PRIVATETESTS += \ qquickpath \ qquicksmoothedanimation \ qquickspringanimation \ + qquickanimationcontroller \ qquickstyledtext \ qquickstates \ qquicksystempalette \