aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@jollamobile.com>2013-12-11 12:28:53 -0600
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-12 21:29:35 +0100
commita2dad3ddee9c4bf274a7c6469342e4104605ceeb (patch)
treeb56f831cd3fd2b9609efdd4b9656c416b4e4e9b9
parentf1997ba4d6e47cc13811630caeb4cc0cf7442401 (diff)
Fix SpringAnimation in Behavior when current value is set.
Fixes regression introduced by d489f2f6549a86b3949004d1c8ec68487fc2adb7. We now only avoid running the animation if the Behavior wasn't already mid-animation. This ensure correct behavior for SpringAnimation, and also correct state for 'running'. Task-number: QTBUG-21549 Change-Id: I0f97813294cca22fb7a273e222fa0549c6de9ca7 Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com>
-rw-r--r--src/quick/util/qquickbehavior.cpp8
-rw-r--r--tests/auto/quick/qquickbehaviors/data/qtbug21549-2.qml71
-rw-r--r--tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp60
3 files changed, 119 insertions, 20 deletions
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index d649f9ff97..407b80915d 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -185,7 +185,8 @@ void QQuickBehavior::write(const QVariant &value)
return;
}
- if (d->animation->isRunning() && value == d->targetValue)
+ bool behaviorActive = d->animation->isRunning();
+ if (behaviorActive && value == d->targetValue)
return;
d->targetValue = value;
@@ -201,7 +202,10 @@ void QQuickBehavior::write(const QVariant &value)
// to the item, so we need to read the value after.
const QVariant &currentValue = d->property.read();
- if (d->targetValue == currentValue) {
+ // Don't unnecessarily wake up the animation system if no real animation
+ // is needed (value has not changed). If the Behavior was already
+ // running, let it continue as normal to ensure correct behavior and state.
+ if (!behaviorActive && d->targetValue == currentValue) {
QQmlPropertyPrivate::write(d->property, value, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
return;
}
diff --git a/tests/auto/quick/qquickbehaviors/data/qtbug21549-2.qml b/tests/auto/quick/qquickbehaviors/data/qtbug21549-2.qml
new file mode 100644
index 0000000000..9cf22dc7a1
--- /dev/null
+++ b/tests/auto/quick/qquickbehaviors/data/qtbug21549-2.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 400; height: 400
+
+ property alias animRunning: springAnim.running
+
+ Rectangle {
+ objectName: "myRect"
+ color: "green"
+ width: 20; height: 20
+
+ property bool triggered: false
+
+ onXChanged: {
+ if (!triggered && x > 50 && x < 80) {
+ triggered = true
+ x = x //set same value
+ }
+ }
+
+ Behavior on x {
+ SpringAnimation {
+ id: springAnim
+ spring: 3
+ damping: 0.2
+ mass: .5
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp
index 8ec76c94e9..5deda2d96b 100644
--- a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp
+++ b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp
@@ -499,30 +499,54 @@ void tst_qquickbehaviors::multipleChangesToValueType()
//QTBUG-21549
void tst_qquickbehaviors::currentValue()
{
- QQmlEngine engine;
- QQmlComponent c(&engine, testFileUrl("qtbug21549.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
- QVERIFY(item);
+ {
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("qtbug21549.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item);
- QQuickRectangle *target = item->findChild<QQuickRectangle*>("myRect");
- QVERIFY(target);
+ QQuickRectangle *target = item->findChild<QQuickRectangle*>("myRect");
+ QVERIFY(target);
- QCOMPARE(target->x(), qreal(0));
+ QCOMPARE(target->x(), qreal(0));
- target->setProperty("x", 50);
- QCOMPARE(item->property("behaviorCount").toInt(), 1);
- QCOMPARE(target->x(), qreal(50));
+ target->setProperty("x", 50);
+ QCOMPARE(item->property("behaviorCount").toInt(), 1);
+ QCOMPARE(target->x(), qreal(50));
- target->setProperty("x", 50);
- QCOMPARE(item->property("behaviorCount").toInt(), 1);
- QCOMPARE(target->x(), qreal(50));
+ target->setProperty("x", 50);
+ QCOMPARE(item->property("behaviorCount").toInt(), 1);
+ QCOMPARE(target->x(), qreal(50));
- target->setX(100);
- target->setProperty("x", 100);
- QCOMPARE(item->property("behaviorCount").toInt(), 1);
- QCOMPARE(target->x(), qreal(100));
+ target->setX(100);
+ target->setProperty("x", 100);
+ QCOMPARE(item->property("behaviorCount").toInt(), 1);
+ QCOMPARE(target->x(), qreal(100));
+
+ delete item;
+ }
- delete item;
+ {
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("qtbug21549-2.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item);
+
+ QQuickRectangle *target = item->findChild<QQuickRectangle*>("myRect");
+ QVERIFY(target);
+
+ QCOMPARE(target->x(), qreal(0));
+
+ target->setProperty("x", 100);
+
+ // the spring animation should smoothly transition to the new value triggered
+ // in the QML (which should be between 50 and 80);
+ QTRY_COMPARE(item->property("animRunning").toBool(), true);
+ QTRY_COMPARE(item->property("animRunning").toBool(), false);
+ QVERIFY(target->x() > qreal(50) && target->x() < qreal(80));
+
+ delete item;
+ }
}
QTEST_MAIN(tst_qquickbehaviors)