summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThierry Bastian <thierry.bastian@nokia.com>2009-08-12 12:19:15 (GMT)
committerThierry Bastian <thierry.bastian@nokia.com>2009-08-12 12:21:23 (GMT)
commit657de489549bab1f9d2ba759739dd55f65a8532e (patch)
treead1878a9bd11bfe0b7b7f03eddf44cfca5bf7dc7 /src/corelib
parent4cf8deb5da96b00a3b89c5c328aab3d47e1dfbb3 (diff)
downloadQt-657de489549bab1f9d2ba759739dd55f65a8532e.zip
Qt-657de489549bab1f9d2ba759739dd55f65a8532e.tar.gz
Qt-657de489549bab1f9d2ba759739dd55f65a8532e.tar.bz2
Make QPropertyAnimation symetric wrt direction
It is now possible to set a start value and no end value and starting the animation will pick the default end value from the current value of the property that's being animated.
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qvariantanimation.cpp77
-rw-r--r--src/corelib/animation/qvariantanimation_p.h1
2 files changed, 39 insertions, 39 deletions
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 61321c8..04e0980 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -178,8 +178,7 @@ template<> Q_INLINE_TEMPLATE QLineF _q_interpolate(const QLineF &f, const QLineF
return QLineF( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress));
}
-QVariantAnimationPrivate::QVariantAnimationPrivate() : duration(250), hasStartValue(false),
- interpolator(&defaultInterpolator),
+QVariantAnimationPrivate::QVariantAnimationPrivate() : duration(250), interpolator(&defaultInterpolator),
changedSignalMask(1 << QVariantAnimation::staticMetaObject.indexOfSignal("valueChanged(QVariant)"))
{
//we keep the mask so that we emit valueChanged only when needed (for performance reasons)
@@ -222,34 +221,52 @@ void QVariantAnimationPrivate::updateInterpolator()
void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/)
{
// can't interpolate if we have only 1 key value
- if (keyValues.count() <= 1)
+ if ((keyValues.count() + (defaultStartValue.isValid() ? 1 : 0)) <=1)
return;
const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration)));
if (force || progress < currentInterval.start.first || progress > currentInterval.end.first) {
//let's update currentInterval
- QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(),
+ QVariantAnimation::KeyValues::const_iterator it = 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).
- // 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
- if (itStart == keyValues.constBegin()) {
- ++itEnd;
+ if (it == keyValues.constEnd()) {
+ if (direction == QVariantAnimation::Backward && defaultStartValue.isValid()) {
+ --it;
+ if (it->first == 1) {
+ //we have an end value (item with progress = 1)
+ currentInterval.start = *(it-1);
+ currentInterval.end = *it;
+ } else if (direction == QVariantAnimation::Backward && defaultStartValue.isValid()) {
+ //the default start value should be used as the default end value
+ currentInterval.start = *it;
+ currentInterval.end = qMakePair(qreal(1), defaultStartValue);
+ } else {
+ ///This should not happen
+ }
+ }
+ } else if (it == keyValues.constBegin()) {
+ if (it->first == progress || it->first == 0) {
+ //the item pointed to by it is the start element in the range
+ //we also test if the current element is for progress 0 (ie the real start) because
+ //some easing curves might get the progress below 0.
+ currentInterval.start = *it;
+ currentInterval.end = *(it+1);
+ } else if (direction == QVariantAnimation::Forward && defaultStartValue.isValid()) {
+ currentInterval.start = qMakePair(qreal(0), defaultStartValue);
+ currentInterval.end = *it;
} else {
- --itStart;
+ ///this should not happen
}
-
- // update all the values of the currentInterval
- currentInterval.start = *itStart;
- currentInterval.end = *itEnd;
- updateInterpolator();
+ } else {
+ currentInterval.start = *(it-1);
+ currentInterval.end = *it;
}
+
+ // update all the values of the currentInterval
+ updateInterpolator();
}
setCurrentValueForProgress(progress);
}
@@ -298,8 +315,6 @@ void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value)
} else {
if (value.isValid())
result->second = value; // replaces the previous value
- else if (step == 0 && !hasStartValue && defaultStartValue.isValid())
- result->second = defaultStartValue; // resets to the default start value
else
keyValues.erase(result); // removes the previous value
}
@@ -310,8 +325,7 @@ void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value)
void QVariantAnimationPrivate::setDefaultStartValue(const QVariant &value)
{
defaultStartValue = value;
- if (!hasStartValue)
- setValueAt(0, value);
+ recalculateCurrentInterval(/*force=*/true);
}
/*!
@@ -526,11 +540,7 @@ void QVariantAnimation::setEndValue(const QVariant &value)
*/
QVariant QVariantAnimation::keyValueAt(qreal step) const
{
- Q_D(const QVariantAnimation);
- if (step == 0 && !d->hasStartValue)
- return QVariant(); //special case where we don't have an explicit startValue
-
- return d->valueAt(step);
+ return d_func()->valueAt(step);
}
/*!
@@ -552,10 +562,7 @@ QVariant QVariantAnimation::keyValueAt(qreal step) const
*/
void QVariantAnimation::setKeyValueAt(qreal step, const QVariant &value)
{
- Q_D(QVariantAnimation);
- if (step == 0)
- d->hasStartValue = value.isValid();
- d->setValueAt(step, value);
+ d_func()->setValueAt(step, value);
}
/*!
@@ -565,12 +572,7 @@ void QVariantAnimation::setKeyValueAt(qreal step, const QVariant &value)
*/
QVariantAnimation::KeyValues QVariantAnimation::keyValues() const
{
- Q_D(const QVariantAnimation);
- QVariantAnimation::KeyValues ret = d->keyValues;
- //in case we added the default start value, we remove it
- if (!d->hasStartValue && !ret.isEmpty() && ret.at(0).first == 0)
- ret.remove(0);
- return ret;
+ return d_func()->keyValues;
}
/*!
@@ -584,7 +586,6 @@ void QVariantAnimation::setKeyValues(const KeyValues &keyValues)
Q_D(QVariantAnimation);
d->keyValues = keyValues;
qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan);
- d->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0;
d->recalculateCurrentInterval(/*force=*/true);
}
diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h
index dbfd956..9c9d25b 100644
--- a/src/corelib/animation/qvariantanimation_p.h
+++ b/src/corelib/animation/qvariantanimation_p.h
@@ -84,7 +84,6 @@ public:
QVariantAnimation::KeyValues keyValues;
QVariant currentValue;
QVariant defaultStartValue;
- bool hasStartValue;
//this is used to keep track of the KeyValue interval in which we currently are
struct