From 92ff29b161709f4503d628e468c0eec1daf5835a Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Thu, 14 May 2009 17:16:11 +0200 Subject: Indentation and whitespace fixes in animation api --- src/corelib/animation/qparallelanimationgroup.cpp | 2 +- src/corelib/animation/qpauseanimation.cpp | 2 +- src/corelib/animation/qpropertyanimation.cpp | 4 ++-- src/corelib/animation/qpropertyanimation_p.h | 1 - src/corelib/animation/qvariantanimation.cpp | 14 ++++++-------- tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp | 4 ++-- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index e4bce6a..48c8b3e 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -62,7 +62,7 @@ group->start(); \endcode - + In this example, \c anim1 and \c anim2 are two \l{QPropertyAnimation}s that have already been set up. diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp index 685fa98..c853745 100644 --- a/src/corelib/animation/qpauseanimation.cpp +++ b/src/corelib/animation/qpauseanimation.cpp @@ -52,7 +52,7 @@ \l{QAbstractAnimation::finished()}{finish} before a specified number of milliseconds have elapsed from when it was started. You specify the duration of the pause in the constructor. It can also - be set directly with setDuration(). + be set directly with setDuration(). It is not necessary to construct a QPauseAnimation yourself. QSequentialAnimationGroup provides the convenience functions diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 96cfa6b..1755aa7 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -48,14 +48,14 @@ QPropertyAnimation interpolates over \l{Qt's Property System}{Qt properties}. As property values are stored in \l{QVariant}s, the class inherits QVariantAnimation, and supports animation of the - same \l{QVariant::Type}{variant types} as its super class. + same \l{QVariant::Type}{variant types} as its super class. A class declaring properties must be a QObject. To make it possible to animate a property, it must provide a setter (so that QPropertyAnimation can set the property's value). Note that this makes it possible to animate many of Qt's widgets. Let's look at an example: - + \code QPropertyAnimation animation(myWidget, "geometry"); animation.setDuration(10000); diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index ed3666d..9d9dd31 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -70,7 +70,6 @@ public: { } - QPointer target; //for the QProperty diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 73ed0df..58f0e03 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE animates Qt \l{Qt's Property System}{properties}. See the QPropertyAnimation class description if you wish to animate such properties. - + You can then set start and end values for the property by calling setStartValue() and setEndValue(), and finally call start() to start the animation. QVariantAnimation will interpolate the @@ -111,12 +111,12 @@ QT_BEGIN_NAMESPACE \o \l{QMetaType::}{QSizeF} \o \l{QMetaType::}{QRect} \o \l{QMetaType::}{QRectF} - \endlist + \endlist If you need to interpolate other variant types, including custom types, you have to implement interpolation for these yourself. You do this by reimplementing interpolated(), which returns - interpolation values for the value being interpolated. + interpolation values for the value being interpolated. \omit We need some snippets around here. \endomit @@ -152,7 +152,7 @@ template<> Q_INLINE_TEMPLATE QRectF _q_interpolate(const QRectF &f, const QRectF f.getRect(&x1, &y1, &w1, &h1); qreal x2, y2, w2, h2; t.getRect(&x2, &y2, &w2, &h2); - return QRectF( _q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress), + return QRectF(_q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress), _q_interpolate(w1, w2, progress), _q_interpolate(h1, h2, progress)); } @@ -227,11 +227,10 @@ void QVariantAnimationPrivate::updateCurrentValue() #endif if (currentValue != ret) { //the value has changed - emit q->valueChanged(currentValue); + emit q->valueChanged(currentValue); } } - QVariant QVariantAnimationPrivate::valueAt(qreal step) const { QVariantAnimation::KeyValues::const_iterator result = @@ -242,7 +241,6 @@ QVariant QVariantAnimationPrivate::valueAt(qreal step) const return QVariant(); } - void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value) { if (step < qreal(0.0) || step > qreal(1.0)) { @@ -587,7 +585,7 @@ bool QVariantAnimation::event(QEvent *event) \reimp */ void QVariantAnimation::updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) + QAbstractAnimation::State newState) { Q_UNUSED(oldState); Q_UNUSED(newState); diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 2e5fd00..172950f 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -794,9 +794,9 @@ void tst_QPropertyAnimation::operationsInStates() * | pause() |start() |resume() |stop() * ----------+------------+-----------+-----------+-------------------+ * Stopped | Stopped |Running |Stopped |Stopped | - * _| qWarning | |qWarning |- | + * _| qWarning |restart |qWarning | | * Paused | Paused |Running |Running |Stopped | - * _| - | | | | + * _| | | | | * Running | Paused |Running |Running |Stopped | * | |restart |qWarning | | * ----------+------------+-----------+-----------+-------------------+ -- cgit v0.12 From 9227f6249de0e60a2a428549848c875c01dbf4d2 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Thu, 14 May 2009 17:52:09 +0200 Subject: Avoid interpolating if we have less than 2 key values in QVariantAnimation If we have less than 2 key values, we should neither try to interpolate nor set the current value. Reviewed-by: janarve --- src/corelib/animation/qvariantanimation.cpp | 14 +++++++--- .../qpropertyanimation/tst_qpropertyanimation.cpp | 31 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 58f0e03..fbce917 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -186,12 +186,20 @@ void QVariantAnimationPrivate::convertValues(int t) void QVariantAnimationPrivate::updateCurrentValue() { + // can't interpolate if we have only 1 key value + if (keyValues.count() <= 1) + return; + Q_Q(QVariantAnimation); + const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration))); if (progress < currentInterval.start.first || progress > currentInterval.end.first) { //let's update currentInterval - QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(), keyValues.constEnd(), qMakePair(progress, QVariant()), animationValueLessThan); + QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(), + keyValues.constEnd(), + qMakePair(progress, QVariant()), + animationValueLessThan); QVariantAnimation::KeyValues::const_iterator itEnd = itStart; // If we are at the end we should continue to use the last keyValues in case of extrapolation (progress > 1.0). @@ -199,10 +207,8 @@ void QVariantAnimationPrivate::updateCurrentValue() if (itStart != keyValues.constEnd()) { //this can't happen because we always prepend the default start value there - if (itStart == keyValues.begin()) { + if (itStart == keyValues.constBegin()) { ++itEnd; - if (itEnd == keyValues.constEnd()) - return; //there is no upper bound } else { --itStart; } diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 172950f..c753477 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -95,6 +95,7 @@ private slots: void zeroDurationStart(); void operationsInStates_data(); void operationsInStates(); + void oneKeyValue(); }; tst_QPropertyAnimation::tst_QPropertyAnimation() @@ -850,5 +851,35 @@ void tst_QPropertyAnimation::operationsInStates() #undef Resume #undef Stop +void tst_QPropertyAnimation::oneKeyValue() +{ + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation animation(&o, "ole"); + animation.setStartValue(43); + animation.setEndValue(44); + animation.setDuration(100); + + animation.setCurrentTime(0); + + QVERIFY(animation.currentValue().isValid()); + QCOMPARE(animation.currentValue().toInt(), 43); + QCOMPARE(o.property("ole").toInt(), 42); + + // remove the last key value + animation.setKeyValueAt(1.0, QVariant()); + + // we will neither interpolate, nor update the current value + // since there is only one 1 key value defined + animation.setCurrentTime(100); + + // the animation should not have been modified + QVERIFY(animation.currentValue().isValid()); + QCOMPARE(animation.currentValue().toInt(), 43); + QCOMPARE(o.property("ole").toInt(), 42); +} + QTEST_MAIN(tst_QPropertyAnimation) #include "tst_qpropertyanimation.moc" -- cgit v0.12 From 4f07fd724a7cc763d57f4b2e23d407b820bb8880 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Fri, 15 May 2009 12:40:00 +0200 Subject: Update current value on QVariantAnimation::setKeyValues The current value was udpated on setKeyValueAt, but not on setKeyValues and this was leading to a semantic inconsistency. Reviewed-by: janarve --- src/corelib/animation/qvariantanimation.cpp | 1 + .../qpropertyanimation/tst_qpropertyanimation.cpp | 34 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index fbce917..cad9341 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -550,6 +550,7 @@ void QVariantAnimation::setKeyValues(const KeyValues &keyValues) d->keyValues = keyValues; qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan); d->currentInterval.start.first = 2; // this will force the refresh + d->updateCurrentValue(); d->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0; } diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index c753477..7e910d4 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -42,6 +42,7 @@ #include #include +#include #include //TESTED_CLASS=QPropertyAnimation @@ -96,6 +97,7 @@ private slots: void operationsInStates_data(); void operationsInStates(); void oneKeyValue(); + void updateOnSetKeyValues(); }; tst_QPropertyAnimation::tst_QPropertyAnimation() @@ -881,5 +883,37 @@ void tst_QPropertyAnimation::oneKeyValue() QCOMPARE(o.property("ole").toInt(), 42); } +void tst_QPropertyAnimation::updateOnSetKeyValues() +{ + QObject o; + o.setProperty("ole", 100); + QCOMPARE(o.property("ole").toInt(), 100); + + QPropertyAnimation animation(&o, "ole"); + animation.setStartValue(100); + animation.setEndValue(200); + animation.setDuration(100); + + animation.setCurrentTime(50); + QCOMPARE(animation.currentValue().toInt(), 150); + animation.setKeyValueAt(0.0, 300); + QCOMPARE(animation.currentValue().toInt(), 250); + + o.setProperty("ole", 100); + QPropertyAnimation animation2(&o, "ole"); + QVariantAnimation::KeyValues kValues; + kValues << QVariantAnimation::KeyValue(0.0, 100) << QVariantAnimation::KeyValue(1.0, 200); + animation2.setKeyValues(kValues); + animation2.setDuration(100); + animation2.setCurrentTime(50); + QCOMPARE(animation2.currentValue().toInt(), 150); + + kValues.clear(); + kValues << QVariantAnimation::KeyValue(0.0, 300) << QVariantAnimation::KeyValue(1.0, 200); + animation2.setKeyValues(kValues); + + QCOMPARE(animation2.currentValue().toInt(), animation.currentValue().toInt()); +} + QTEST_MAIN(tst_QPropertyAnimation) #include "tst_qpropertyanimation.moc" -- cgit v0.12 From a90608bb1827493da578cf9ad41415fc8a7f6e65 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Fri, 15 May 2009 13:31:57 +0200 Subject: General refactors in QVariantAnimation Reviewed-by: janarve --- src/corelib/animation/qvariantanimation.cpp | 58 ++++++++++++++++------------- src/corelib/animation/qvariantanimation_p.h | 4 +- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index cad9341..9b62356 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -174,27 +174,24 @@ void QVariantAnimationPrivate::convertValues(int t) if (pair.second.userType() != t) pair.second.convert(static_cast(t)); } - currentInterval.start.first = 2; // this will force the refresh - interpolator = 0; // if the type changed we need to update the interpolator + interpolator = 0; // if the type changed we need to update the interpolator } /*! - \fn void QVariantAnimation::updateCurrentValue(const QVariant &value) = 0; - This pure virtual function is called when the animated value is changed. - \a value is the new value. + \internal + The goal of this function is to update the currentInterval member. As a consequence, we also + need to update the currentValue. + Set \a force to true to always recalculate the interval. */ - -void QVariantAnimationPrivate::updateCurrentValue() +void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) { // can't interpolate if we have only 1 key value if (keyValues.count() <= 1) return; - Q_Q(QVariantAnimation); - const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration))); - if (progress < currentInterval.start.first || progress > currentInterval.end.first) { + if (force || progress < currentInterval.start.first || progress > currentInterval.end.first) { //let's update currentInterval QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(), keyValues.constEnd(), @@ -205,22 +202,33 @@ void QVariantAnimationPrivate::updateCurrentValue() // If we are at the end we should continue to use the last keyValues in case of extrapolation (progress > 1.0). // This is because the easing function can return a value slightly outside the range [0, 1] if (itStart != keyValues.constEnd()) { - - //this can't happen because we always prepend the default start value there + // this can't happen because we always prepend the default start value there if (itStart == keyValues.constBegin()) { ++itEnd; } else { --itStart; } - //update all the values of the currentInterval + // update all the values of the currentInterval currentInterval.start = *itStart; currentInterval.end = *itEnd; } } + setCurrentValueForProgress(progress); +} + +void QVariantAnimationPrivate::setCurrentValue() +{ + const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration))); + setCurrentValueForProgress(progress); +} + +void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) +{ + Q_Q(QVariantAnimation); - const qreal startProgress = currentInterval.start.first, - endProgress = currentInterval.end.first; + const qreal startProgress = currentInterval.start.first; + const qreal endProgress = currentInterval.end.first; const qreal localProgress = (progress - startProgress) / (endProgress - startProgress); QVariant ret = q->interpolated(currentInterval.start.second, @@ -261,15 +269,14 @@ void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value) keyValues.insert(result, pair); } else { if (value.isValid()) - result->second = value; //remove the previous value + result->second = value; // replaces the previous value else if (step == 0 && !hasStartValue && defaultStartValue.isValid()) - result->second = defaultStartValue; //we reset to the default start value + result->second = defaultStartValue; // resets to the default start value else - keyValues.erase(result); //replace the previous value + keyValues.erase(result); // removes the previous value } - currentInterval.start.first = 2; // this will force the refresh - updateCurrentValue(); + recalculateCurrentInterval(/*force=*/true); } void QVariantAnimationPrivate::setDefaultStartValue(const QVariant &value) @@ -328,7 +335,7 @@ void QVariantAnimation::setEasingCurve(const QEasingCurve &easing) { Q_D(QVariantAnimation); d->easing = easing; - d->updateCurrentValue(); + d->recalculateCurrentInterval(); } Q_GLOBAL_STATIC(QVector, registeredInterpolators) @@ -439,7 +446,7 @@ void QVariantAnimation::setDuration(int msecs) if (d->duration == msecs) return; d->duration = msecs; - d->updateCurrentValue(); + d->recalculateCurrentInterval(); } /*! @@ -549,9 +556,8 @@ void QVariantAnimation::setKeyValues(const KeyValues &keyValues) Q_D(QVariantAnimation); d->keyValues = keyValues; qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan); - d->currentInterval.start.first = 2; // this will force the refresh - d->updateCurrentValue(); d->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0; + d->recalculateCurrentInterval(/*force=*/true); } /*! @@ -576,7 +582,7 @@ QVariant QVariantAnimation::currentValue() const { Q_D(const QVariantAnimation); if (!d->currentValue.isValid()) - const_cast(d)->updateCurrentValue(); + const_cast(d)->recalculateCurrentInterval(); return d->currentValue; } @@ -640,7 +646,7 @@ void QVariantAnimation::updateCurrentTime(int msecs) { Q_D(QVariantAnimation); Q_UNUSED(msecs); - d->updateCurrentValue(); + d->recalculateCurrentInterval(); } QT_END_NAMESPACE diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index 14a3ef6..9e81649 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -108,7 +108,9 @@ public: quint32 changedSignalMask; - void updateCurrentValue(); + void setCurrentValue(); + void setCurrentValueForProgress(const qreal progress); + void recalculateCurrentInterval(bool force=false); void setValueAt(qreal, const QVariant &); QVariant valueAt(qreal step) const; void convertValues(int t); -- cgit v0.12 From 3e280a737607821feeed391d7881baae33f9dcfe Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Fri, 15 May 2009 13:35:58 +0200 Subject: Avoid resetting the QVariantAnimation::currentValue when changing state Reviewed-by: janarve --- src/corelib/animation/qvariantanimation.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 9b62356..157a321 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -602,8 +602,6 @@ void QVariantAnimation::updateState(QAbstractAnimation::State oldState, { Q_UNUSED(oldState); Q_UNUSED(newState); - Q_D(QVariantAnimation); - d->currentValue = QVariant(); // this will force the refresh } /*! -- cgit v0.12 From 80fa08d3e7f109e11e67ef73ff7a98312bbca984 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Fri, 15 May 2009 16:03:01 +0200 Subject: Doc: Added a work in progress class hierarchy overview. Reviewed-by: Geir Vattekar --- doc/src/diagrams/animations-architecture.svg | 351 +++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 doc/src/diagrams/animations-architecture.svg diff --git a/doc/src/diagrams/animations-architecture.svg b/doc/src/diagrams/animations-architecture.svg new file mode 100644 index 0000000..0246510 --- /dev/null +++ b/doc/src/diagrams/animations-architecture.svg @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + QAbstractAnimation + + QVariantAnimation + + QAnimationGroup + + + + QPropertyAnimation + + + QSequentialAnimationGroup + + QParallelAnimationGroup + + + + -- cgit v0.12 From 9aba165d0ca970949bcc5fc590569ea58d992626 Mon Sep 17 00:00:00 2001 From: Geir Vattekar Date: Fri, 15 May 2009 16:30:29 +0200 Subject: Doc: Added architecture image to animation overview. Reviewed-by: David Boddie --- doc/src/animation.qdoc | 5 ++++- doc/src/images/animations-architecture.png | Bin 0 -> 27619 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 doc/src/images/animations-architecture.png diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc index 5eb2eda..f3baf71 100644 --- a/doc/src/animation.qdoc +++ b/doc/src/animation.qdoc @@ -64,7 +64,10 @@ We will in this section take a high-level look at the animation framework's architecture and how it is used to animate Qt - properties. + properties. The following diagram shows the most important classes + in the animation framework. + + \image animations-architecture.png The animation framework foundation consists of the base class QAbstractAnimation, and its two subclasses QVariantAnimation and diff --git a/doc/src/images/animations-architecture.png b/doc/src/images/animations-architecture.png new file mode 100644 index 0000000..9b581af Binary files /dev/null and b/doc/src/images/animations-architecture.png differ -- cgit v0.12 From ad17d5fcaa5984e7f11e3c8a514a24264890c827 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 18 May 2009 14:06:31 +0200 Subject: Fixed access to members of an object. Reviewed-by: David Boddie --- doc/src/animation.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc index f3baf71..b4e603c 100644 --- a/doc/src/animation.qdoc +++ b/doc/src/animation.qdoc @@ -271,10 +271,10 @@ \code QPushButton *bonnie = new QPushButton("Bonnie"); - bonnie.show(); + bonnie->show(); QPushButton *clyde = new QPushButton("Clyde"); - clyde.show(); + clyde->show(); QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); // Set up anim1 -- cgit v0.12