Fix, test and document animation started/stopped signals.

Rename completed to stopped (as it is not only emitted
on completion). Ensure that the started and stopped signals
are emitted at the right times. Document the signals.

Task-number: QTBUG-14968
Change-Id: Icd3babcef2c9e544476592a26e6b9e58a21ebe95
Reviewed-by: Yunqiao Yin <charles.yin@nokia.com>
This commit is contained in:
Michael Brasser 2012-07-06 11:43:41 +10:00 committed by Qt by Nokia
parent 73cdca2441
commit f9d7a3ec09
4 changed files with 119 additions and 7 deletions

View File

@ -175,7 +175,7 @@ void QQuickAbstractAnimationPrivate::commence()
animationInstance->start();
if (animationInstance->isStopped()) {
running = false;
emit q->completed();
emit q->stopped();
}
}
}
@ -193,6 +193,31 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
return prop;
}
/*!
\qmlsignal QtQuick2::Animation::onStarted()
This signal handler is called when the animation begins.
It is only triggered for top-level, standalone animations. It will not be
triggered for animations in a Behavior or Transition, or animations
that are part of an animation group.
*/
/*!
\qmlsignal QtQuick2::Animation::onStopped()
This signal handler is called when the animation ends.
The animation may have been stopped manually, or may have run to completion.
It is only triggered for top-level, standalone animations. It will not be
triggered for animations in a Behavior or Transition, or animations
that are part of an animation group.
If \l alwaysRunToEnd is true, onStopped will not be called until the animation
has completed its current iteration.
*/
void QQuickAbstractAnimation::setRunning(bool r)
{
Q_D(QQuickAbstractAnimation);
@ -231,9 +256,10 @@ void QQuickAbstractAnimation::setRunning(bool r)
d->animationInstance->setLoopCount(d->animationInstance->currentLoop() + d->loopCount);
supressStart = true; //we want the animation to continue, rather than restart
}
if (!supressStart)
if (!supressStart) {
d->commence();
emit started();
emit started();
}
} else {
if (d->paused) {
d->paused = false; //reset paused state to false when stopped
@ -246,9 +272,9 @@ void QQuickAbstractAnimation::setRunning(bool r)
d->animationInstance->setLoopCount(d->animationInstance->currentLoop()+1); //finish the current loop
} else {
d->animationInstance->stop();
emit stopped();
}
}
emit completed();
}
emit runningChanged(d->running);
@ -608,9 +634,11 @@ void QQuickAbstractAnimationPrivate::animationFinished(QAbstractAnimationJob*)
{
Q_Q(QQuickAbstractAnimation);
q->setRunning(false);
if (alwaysRunToEnd && loopCount != 1) {
if (alwaysRunToEnd) {
emit q->stopped();
//restore the proper loopCount for the next run
animationInstance->setLoopCount(loopCount);
if (loopCount != 1)
animationInstance->setLoopCount(loopCount);
}
}

View File

@ -106,7 +106,7 @@ public:
Q_SIGNALS:
void started();
void completed();
void stopped();
void runningChanged(bool);
void pausedChanged(bool);
void alwaysRunToEndChanged(bool);

View File

@ -0,0 +1,30 @@
import QtQuick 2.0
Item {
id: wrapper
width: 400; height: 400
function start() { animation.start() }
function stop() { animation.stop() }
property alias alwaysRunToEnd: animation.alwaysRunToEnd
property int startedCount: 0
property int stoppedCount: 0
Rectangle {
id: greenRect
width: 50; height: 50
color: "green"
NumberAnimation on x {
id: animation
from: 0
to: 100
duration: 200
onStarted: ++startedCount
onStopped: ++stoppedCount
}
}
}

View File

@ -97,6 +97,7 @@ private slots:
void dontStart();
void easingProperties();
void rotation();
void startStopSignals();
void runningTrueBug();
void nonTransitionBug();
void registrationBug();
@ -1196,6 +1197,59 @@ void tst_qquickanimations::rotation()
QTIMED_COMPARE(rr->rotation() + rr2->rotation() + rr3->rotation() + rr4->rotation(), qreal(370*4));
}
void tst_qquickanimations::startStopSignals()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("signals.qml"));
QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
QVERIFY(root);
QCOMPARE(root->property("startedCount").toInt(), 1); //autostart
QCOMPARE(root->property("stoppedCount").toInt(), 0);
QMetaObject::invokeMethod(root, "stop");
QCOMPARE(root->property("startedCount").toInt(), 1);
QCOMPARE(root->property("stoppedCount").toInt(), 1);
QMetaObject::invokeMethod(root, "start");
QCOMPARE(root->property("startedCount").toInt(), 2);
QCOMPARE(root->property("stoppedCount").toInt(), 1);
QTest::qWait(100);
QCOMPARE(root->property("startedCount").toInt(), 2);
QCOMPARE(root->property("stoppedCount").toInt(), 1);
QTest::qWait(100);
QTRY_COMPARE(root->property("stoppedCount").toInt(), 2);
QCOMPARE(root->property("startedCount").toInt(), 2);
root->setProperty("alwaysRunToEnd", true);
QMetaObject::invokeMethod(root, "start");
QCOMPARE(root->property("startedCount").toInt(), 3);
QCOMPARE(root->property("stoppedCount").toInt(), 2);
QTest::qWait(100);
QCOMPARE(root->property("startedCount").toInt(), 3);
QCOMPARE(root->property("stoppedCount").toInt(), 2);
QMetaObject::invokeMethod(root, "stop");
QCOMPARE(root->property("startedCount").toInt(), 3);
QCOMPARE(root->property("stoppedCount").toInt(), 2);
QTest::qWait(100);
QTRY_COMPARE(root->property("stoppedCount").toInt(), 3);
QCOMPARE(root->property("startedCount").toInt(), 3);
}
void tst_qquickanimations::runningTrueBug()
{
//ensure we start correctly when "running: true" is explicitly set