diff options
author | Piotr Mikolajczyk <piotr.mikolajczyk@qt.io> | 2020-10-06 10:27:20 +0200 |
---|---|---|
committer | Piotr Mikolajczyk <piotr.mikolajczyk@qt.io> | 2020-10-13 11:57:03 +0200 |
commit | d66d0540dc323e6a536b952acedcfda70cd90c0c (patch) | |
tree | c23de7945f4b104e345afa31a398e5846eb5b872 /tests | |
parent | aba1bf6fca24ec6ee21ffc4417ef05d5d2cfdfeb (diff) |
Fix alwaysRunToEnd==true prevented complex Anim from stopping
AnimatorProxyJob would not forward loopCount to the controlled job causing
the sequential or parallel animation to go infinitely after attempt to stop
Task-number: QTBUG-82890
Pick-to: 5.15
Change-Id: I6a1ca787f06789064e05407bbe9ae5e5861f24d5
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests')
3 files changed, 163 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickanimations/data/alwaysRunToEndInSequentialAnimationBug.qml b/tests/auto/quick/qquickanimations/data/alwaysRunToEndInSequentialAnimationBug.qml new file mode 100644 index 0000000000..a775e5d263 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/alwaysRunToEndInSequentialAnimationBug.qml @@ -0,0 +1,59 @@ +import QtQuick 2.15 +import QtQuick.Window 2.15 + +Rectangle { + width: 100 + height: 100 + visible: true + color: "blue" + property bool onFinishedCalled : false; + property bool onStoppedCalled : false; + property int loopsMade: 0; + + Rectangle { + id: whiteRect + objectName: "whiteRect" + anchors.fill: parent + color: "white" + opacity: 1 + + } + + property var seqAnim : SequentialAnimation { + loops: Animation.Infinite + alwaysRunToEnd: true + NumberAnimation { + target: whiteRect + properties: "opacity" + from: 1; + to: 0.1; + duration: 500 + } + NumberAnimation { + target: whiteRect + properties: "opacity" + from: 0.1; + to: 1; + duration: 500 + } + ScriptAction { + script: loopsMade++ + } + + onFinished: { + whiteRect.opacity = 1 + onFinishedCalled = true + } + + onStopped : { + whiteRect.opacity = 1 + onStoppedCalled = true + } + + onStarted:{ + onFinishedCalled = false + onStoppedCalled = false + loopsMade = 0 + } + } +} diff --git a/tests/auto/quick/qquickanimations/qquickanimations.pro b/tests/auto/quick/qquickanimations/qquickanimations.pro index 6998c023db..85a77ae620 100644 --- a/tests/auto/quick/qquickanimations/qquickanimations.pro +++ b/tests/auto/quick/qquickanimations/qquickanimations.pro @@ -12,6 +12,7 @@ QT += core-private gui-private qml-private quick-private testlib qmlmodels-priv DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ + data/alwaysRunToEndInSequentialAnimationBug.qml \ data/animationJobSelfDestructionBug.qml\ data/attached.qml \ data/badproperty1.qml \ diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 8580a2dc1b..fe366d0f34 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -115,6 +115,7 @@ private slots: void animationJobSelfDestruction(); void fastFlickingBug(); void opacityAnimationFromZero(); + void alwaysRunToEndInSequentialAnimationBug(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -1895,6 +1896,108 @@ void tst_qquickanimations::opacityAnimationFromZero() QTRY_VERIFY(!img.isNull() && img.pixel(100, 100) > qRgb(10, 10, 10)); } +void tst_qquickanimations::alwaysRunToEndInSequentialAnimationBug() +{ + QQuickView view(QUrl::fromLocalFile("data/alwaysRunToEndInSequentialAnimationBug.qml")); + view.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(view.rootObject()); + QObject *root = view.rootObject(); + QQuickAbstractAnimation* seqAnim = root->property("seqAnim").value<QQuickAbstractAnimation *>(); + QObject *whiteRect = root->findChild<QObject*>("whiteRect"); + + // + // Tesing the SequentialAnimation with alwaysRunToEnd = true + // + + // + // Stopping in the first loop + + QVERIFY(whiteRect->property("opacity").value<qreal>() == 1.0); + seqAnim->start(); + QTRY_VERIFY(seqAnim->isRunning() == true); + + seqAnim->stop(); + QTRY_VERIFY(seqAnim->isRunning() == false); + QTRY_VERIFY(!root->property("onStoppedCalled").value<bool>()); + QTRY_VERIFY(!root->property("onFinishedCalled").value<bool>()); + + //The animation should still be running + QTest::qWait(500); + QTRY_VERIFY(whiteRect->property("opacity").value<qreal>() != 1.0); + + QTest::qWait(500); + + //The animation should now be stopped - after reaching its cycle end + QTRY_COMPARE(whiteRect->property("opacity").value<qreal>(), 1.0); + QTRY_VERIFY(root->property("onStoppedCalled").value<bool>()); + QTRY_VERIFY(root->property("onFinishedCalled").value<bool>()); + + // + // Stopping in the second loop + + QVERIFY(whiteRect->property("opacity").value<qreal>() == 1.0); + seqAnim->start(); + QTRY_VERIFY(seqAnim->isRunning() == true); + + QTRY_COMPARE(root->property("loopsMade").value<int>(), 1); // Wait for cycle no 2 to start + + seqAnim->stop(); + QTRY_VERIFY(seqAnim->isRunning() == false); + QTRY_VERIFY(!root->property("onStoppedCalled").value<bool>()); + QTRY_VERIFY(!root->property("onFinishedCalled").value<bool>()); + + //The animation should still be running + QTest::qWait(500); + QTRY_VERIFY(whiteRect->property("opacity").value<qreal>() != 1.0); + + QTest::qWait(500); + + //The animation should now be stopped - after reaching its cycle end + QTRY_COMPARE(whiteRect->property("opacity").value<qreal>(), 1.0); + QTRY_VERIFY(root->property("onStoppedCalled").value<bool>()); + QTRY_VERIFY(root->property("onFinishedCalled").value<bool>()); + + + // + // Tesing the SequentialAnimation with alwaysRunToEnd = false + // + + // + // Stopping in the first loop + + seqAnim->setProperty("alwaysRunToEnd", false); + QVERIFY(whiteRect->property("opacity").value<qreal>() == 1.0); + + seqAnim->start(); + QTRY_VERIFY(seqAnim->isRunning() == true); + + QTest::qWait(50); + seqAnim->stop(); + //The animation should be stopped immediately + QVERIFY(seqAnim->isRunning() == false); + QVERIFY(root->property("onStoppedCalled").value<bool>()); + QVERIFY(root->property("onFinishedCalled").value<bool>()); + QCOMPARE(whiteRect->property("opacity").value<qreal>(), 1.0); + + // + // Stopping in the second loop + QVERIFY(whiteRect->property("opacity").value<qreal>() == 1.0); + seqAnim->start(); + QTRY_VERIFY(seqAnim->isRunning() == true); + + QTRY_COMPARE(root->property("loopsMade").value<int>(), 1); // Wait for cycle no 2 to start + + QTest::qWait(50); + seqAnim->stop(); + //The animation should be stopped immediately + QVERIFY(seqAnim->isRunning() == false); + QVERIFY(root->property("onStoppedCalled").value<bool>()); + QVERIFY(root->property("onFinishedCalled").value<bool>()); + QCOMPARE(whiteRect->property("opacity").value<qreal>(),1.0); +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" |