summaryrefslogtreecommitdiffstats
path: root/src/corelib/animation/qvariantanimation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/animation/qvariantanimation.cpp')
-rw-r--r--src/corelib/animation/qvariantanimation.cpp99
1 files changed, 55 insertions, 44 deletions
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 331024e..e27cde8 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -64,13 +64,15 @@ QT_BEGIN_NAMESPACE
shared functionality.
QVariantAnimation cannot be used directly as it is an abstract
- class; it does not implement \l{updateCurrentValue()}. The class
- performs interpolation over \l{QVariant}s, but leaves using the
- interpolated values to its subclasses. Currently, Qt provides
- QPropertyAnimation, which animates Qt \l{Qt's Property System}
- {properties}. See the QPropertyAnimation class description if you
- wish to animate such properties.
-
+ class; it does not implement
+ \l{QAbstractAnimation::}{updateCurrentValue()} from
+ QAbstractAnimation. The class performs interpolation over
+ \l{QVariant}s, but leaves using the interpolated values to its
+ subclasses. Currently, Qt provides QPropertyAnimation, which
+ 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
@@ -109,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
@@ -150,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));
}
@@ -172,47 +174,61 @@ void QVariantAnimationPrivate::convertValues(int t)
if (pair.second.userType() != t)
pair.second.convert(static_cast<QVariant::Type>(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*/)
{
- Q_Q(QVariantAnimation);
+ // can't interpolate if we have only 1 key value
+ if (keyValues.count() <= 1)
+ return;
+
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(), 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).
// 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.begin()) {
+ // this can't happen because we always prepend the default start value there
+ if (itStart == keyValues.constBegin()) {
++itEnd;
- if (itEnd == keyValues.constEnd())
- return; //there is no upper bound
} 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);
+}
- const qreal startProgress = currentInterval.start.first,
- endProgress = currentInterval.end.first;
+void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+{
+ Q_Q(QVariantAnimation);
+
+ 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,
@@ -225,11 +241,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 =
@@ -240,7 +255,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)) {
@@ -255,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)
@@ -322,7 +335,7 @@ void QVariantAnimation::setEasingCurve(const QEasingCurve &easing)
{
Q_D(QVariantAnimation);
d->easing = easing;
- d->updateCurrentValue();
+ d->recalculateCurrentInterval();
}
Q_GLOBAL_STATIC(QVector<QVariantAnimation::Interpolator>, registeredInterpolators)
@@ -433,7 +446,7 @@ void QVariantAnimation::setDuration(int msecs)
if (d->duration == msecs)
return;
d->duration = msecs;
- d->updateCurrentValue();
+ d->recalculateCurrentInterval();
}
/*!
@@ -543,8 +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->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0;
+ d->recalculateCurrentInterval(/*force=*/true);
}
/*!
@@ -569,7 +582,7 @@ QVariant QVariantAnimation::currentValue() const
{
Q_D(const QVariantAnimation);
if (!d->currentValue.isValid())
- const_cast<QVariantAnimationPrivate*>(d)->updateCurrentValue();
+ const_cast<QVariantAnimationPrivate*>(d)->recalculateCurrentInterval();
return d->currentValue;
}
@@ -585,12 +598,10 @@ bool QVariantAnimation::event(QEvent *event)
\reimp
*/
void QVariantAnimation::updateState(QAbstractAnimation::State oldState,
- QAbstractAnimation::State newState)
+ QAbstractAnimation::State newState)
{
Q_UNUSED(oldState);
Q_UNUSED(newState);
- Q_D(QVariantAnimation);
- d->currentValue = QVariant(); // this will force the refresh
}
/*!
@@ -633,7 +644,7 @@ void QVariantAnimation::updateCurrentTime(int msecs)
{
Q_D(QVariantAnimation);
Q_UNUSED(msecs);
- d->updateCurrentValue();
+ d->recalculateCurrentInterval();
}
QT_END_NAMESPACE