Fix zero-duration animations running Backwards.

If you set the duration of any variant or property animation to 0,
its progress will be stuck at 1 (0..1), and its "end" value set on
the target object, after start() has been called. If you change the
direction of the animation to QAbstractAnimation::Backward, you
would expect the progress to be 0 after start. Instead it's still
1; the code seems to assume that if the duration is 0, the
progress must be 1 always.

The fix is that if the duration is 0, the direction is checked to
determine whether progress should be 0 (Backward) or 1 (Forward).

Task-number: QTBUG-27969
Change-Id: Ibeca084bbbce41df1dca7b7d96c15b6b54394996
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Thierry Bastian <thierryb@filewave.com>
Reviewed-by: Magne Zachrisen <mazachri@cisco.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Andreas Aardal Hanssen 2012-11-12 21:10:21 +01:00 committed by The Qt Project
parent 041769d4e4
commit f3597af5ad
2 changed files with 47 additions and 1 deletions

View File

@ -240,7 +240,8 @@ void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/)
if ((keyValues.count() + (defaultStartEndValue.isValid() ? 1 : 0)) < 2)
return;
const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration)));
const qreal endProgress = (direction == QAbstractAnimation::Forward) ? qreal(1) : qreal(0);
const qreal progress = easing.valueForProgress(((duration == 0) ? endProgress : qreal(currentTime) / qreal(duration)));
//0 and 1 are still the boundaries
if (force || (currentInterval.start.first > 0 && progress < currentInterval.start.first)

View File

@ -113,6 +113,7 @@ private slots:
void setStartEndValues_data();
void setStartEndValues();
void zeroDurationStart();
void zeroDurationForwardBackward();
void operationsInStates_data();
void operationsInStates();
void oneKeyValue();
@ -873,6 +874,50 @@ void tst_QPropertyAnimation::zeroDurationStart()
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(secondChange.first()), QAbstractAnimation::Stopped);
}
void tst_QPropertyAnimation::zeroDurationForwardBackward()
{
QObject o; o.setProperty("test", 1);
QObject o2; o2.setProperty("test", 2);
QObject o3; o3.setProperty("test", 3);
QObject o4; o4.setProperty("test", 4);
QPropertyAnimation prop(&o, "test"); prop.setDuration(0); prop.setStartValue(1); prop.setEndValue(2);
prop.start();
QCOMPARE(o.property("test").toInt(), 2);
prop.setDirection(QAbstractAnimation::Backward);
prop.start();
QCOMPARE(o.property("test").toInt(), 1);
prop.setDirection(QAbstractAnimation::Forward);
QPropertyAnimation prop2(&o2, "test"); prop2.setDuration(0); prop2.setStartValue(2); prop2.setEndValue(3);
QPropertyAnimation prop3(&o3, "test"); prop3.setDuration(0); prop3.setStartValue(3); prop3.setEndValue(4);
QPropertyAnimation prop4(&o4, "test"); prop4.setDuration(0); prop4.setStartValue(4); prop4.setEndValue(5);
QSequentialAnimationGroup group;
group.addAnimation(&prop);
group.addAnimation(&prop2);
group.addAnimation(&prop3);
group.addAnimation(&prop4);
group.start();
QCOMPARE(o.property("test").toInt(), 2);
QCOMPARE(o2.property("test").toInt(), 3);
QCOMPARE(o3.property("test").toInt(), 4);
QCOMPARE(o4.property("test").toInt(), 5);
group.setDirection(QAbstractAnimation::Backward);
group.start();
QCOMPARE(o.property("test").toInt(), 1);
QCOMPARE(o2.property("test").toInt(), 2);
QCOMPARE(o3.property("test").toInt(), 3);
QCOMPARE(o4.property("test").toInt(), 4);
group.removeAnimation(&prop);
group.removeAnimation(&prop2);
group.removeAnimation(&prop3);
group.removeAnimation(&prop4);
}
#define Pause 1
#define Start 2
#define Resume 3