diff options
3 files changed, 106 insertions, 2 deletions
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 9962313f26..0f0ac2b78d 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -2040,8 +2040,9 @@ void QQuickBulkValueAnimator::updateCurrentTime(int currentTime) void QQuickBulkValueAnimator::topLevelAnimationLoopChanged() { - //check for new from every top-level loop (when the top level animation is started and all subsequent loops) - if (fromIsSourced) + // Check for new "from" value only when animation has one loop. + // Otherwise use the initial "from" value for every iteration. + if (m_loopCount == 1 && fromIsSourced) *fromIsSourced = false; QAbstractAnimationJob::topLevelAnimationLoopChanged(); } diff --git a/tests/auto/quick/qquickanimations/data/infiniteAnimationWithoutFrom.qml b/tests/auto/quick/qquickanimations/data/infiniteAnimationWithoutFrom.qml new file mode 100644 index 0000000000..9b4bfe4faa --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/infiniteAnimationWithoutFrom.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: 100 + height: 100 + + // note that 'from' property is missing + NumberAnimation { + objectName: "anim" + to: from+360 + loops: Animation.Infinite + target: rect + properties: "rotation" + duration: 100 + } + + Rectangle { + objectName: "rect" + id: rect + width: 30 + height: 10 + color: "red" + anchors.centerIn: parent + transformOrigin: Item.Center + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 10c8fb3487..72e0da91cb 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -119,6 +119,7 @@ private slots: void cleanupWhenRenderThreadStops(); void changePropertiesDuringAnimation_data(); void changePropertiesDuringAnimation(); + void infiniteLoopsWithoutFrom(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -2120,6 +2121,54 @@ void tst_qquickanimations::changePropertiesDuringAnimation() QCOMPARE(stoppedSpy.count(), 0); } +void tst_qquickanimations::infiniteLoopsWithoutFrom() +{ + // This test checks QTBUG-84375 + QQuickView view(testFileUrl("infiniteAnimationWithoutFrom.qml")); + view.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(view.rootObject()); + + QObject *root = view.rootObject(); + QQuickAbstractAnimation *animation = root->findChild<QQuickAbstractAnimation *>("anim"); + QVERIFY(animation); + QQuickRectangle *rectangle = root->findChild<QQuickRectangle *>("rect"); + QVERIFY(rectangle); + + qreal prevRotation = rectangle->rotation(); + int numsCrossedZero = 0; + connect(rectangle, &QQuickRectangle::rotationChanged, this, [&]() { + const auto rotation = rectangle->rotation(); + // We take a large range of (180; 360] here, because the animation in + // the test runs for a short time, and so there can be huge gaps between + // rotation values. + const bool prevRotationOldLoop = prevRotation > 180.0 && prevRotation <= 360.0; + const bool currRotationNewLoop = rotation >= 0.0 && rotation <= 180.0; + if (prevRotationOldLoop && currRotationNewLoop) + numsCrossedZero++; + prevRotation = rotation; + }); + + // The logic in lamdba function above requires at least two positions in + // a rotation animation - one in [0; 180] range, and another in (180; 360] + // range + animation->start(); + animation->pause(); + QCOMPARE(numsCrossedZero, 0); + animation->setCurrentTime(40); + animation->setCurrentTime(90); + QCOMPARE(numsCrossedZero, 0); + animation->setCurrentTime(140); + animation->setCurrentTime(190); + QCOMPARE(numsCrossedZero, 1); + animation->setCurrentTime(240); + animation->setCurrentTime(290); + QCOMPARE(numsCrossedZero, 2); + + animation->stop(); +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" |