diff options
25 files changed, 609 insertions, 386 deletions
diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 8091f95..fcfc7d6 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -77,11 +77,11 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l PauseAnimation \o \l ParentAnimation \o \l AnchorAnimation +\o \l SmoothedAnimation \o \l PropertyAction \o \l ScriptAction \o \l Transition \o \l SpringFollow -\o \l EaseFollow \o \l Behavior \endlist diff --git a/examples/declarative/progressbar/content/ProgressBar.qml b/examples/declarative/progressbar/content/ProgressBar.qml index 65c80b2..aafb12e 100644 --- a/examples/declarative/progressbar/content/ProgressBar.qml +++ b/examples/declarative/progressbar/content/ProgressBar.qml @@ -21,7 +21,8 @@ Item { id: highlight; radius: 1 anchors.left: parent.left; anchors.top: parent.top; anchors.bottom: parent.bottom anchors.leftMargin: 3; anchors.topMargin: 3; anchors.bottomMargin: 3 - EaseFollow on width { source: highlight.widthDest; velocity: 1200 } + width: highlight.widthDest + Behavior on width { SmoothedAnimation { velocity: 1200 } } gradient: Gradient { GradientStop { id: g1; position: 0.0 } GradientStop { id: g2; position: 1.0 } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 250832b..6d1dec6 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -44,7 +44,7 @@ #include "qdeclarativevisualitemmodel_p.h" #include "qdeclarativeflickable_p_p.h" -#include <qdeclarativeeasefollow_p.h> +#include "qdeclarativeeasefollow_p_p.h" #include <qdeclarativeguard_p.h> #include <qlistmodelinterface_p.h> @@ -324,8 +324,8 @@ public: enum MovementReason { Other, SetIndex, Mouse }; MovementReason moveReason; int buffer; - QDeclarativeEaseFollow *highlightXAnimator; - QDeclarativeEaseFollow *highlightYAnimator; + QSmoothedAnimation *highlightXAnimator; + QSmoothedAnimation *highlightYAnimator; enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; BufferMode bufferMode; QDeclarativeGridView::SnapMode snapMode; @@ -660,14 +660,14 @@ void QDeclarativeGridViewPrivate::createHighlight() QDeclarative_setParent_noEvent(item, q->viewport()); item->setParentItem(q->viewport()); highlight = new FxGridItem(item, q); - highlightXAnimator = new QDeclarativeEaseFollow(q); - highlightXAnimator->setTarget(QDeclarativeProperty(highlight->item, QLatin1String("x"))); - highlightXAnimator->setDuration(150); - highlightXAnimator->setEnabled(autoHighlight); - highlightYAnimator = new QDeclarativeEaseFollow(q); - highlightYAnimator->setTarget(QDeclarativeProperty(highlight->item, QLatin1String("y"))); - highlightYAnimator->setDuration(150); - highlightYAnimator->setEnabled(autoHighlight); + highlightXAnimator = new QSmoothedAnimation(q); + highlightXAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("x")); + highlightXAnimator->userDuration = 150; + highlightYAnimator = new QSmoothedAnimation(q); + highlightYAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("y")); + highlightYAnimator->userDuration = 150; + highlightXAnimator->restart(); + highlightYAnimator->restart(); changed = true; } } @@ -681,10 +681,12 @@ void QDeclarativeGridViewPrivate::updateHighlight() createHighlight(); if (currentItem && autoHighlight && highlight && !moving) { // auto-update highlight - highlightXAnimator->setSourceValue(currentItem->item->x()); - highlightYAnimator->setSourceValue(currentItem->item->y()); + highlightXAnimator->to = currentItem->item->x(); + highlightYAnimator->to = currentItem->item->y(); highlight->item->setWidth(currentItem->item->width()); highlight->item->setHeight(currentItem->item->height()); + highlightXAnimator->restart(); + highlightYAnimator->restart(); } updateTrackedItem(); } @@ -1190,10 +1192,6 @@ void QDeclarativeGridView::setHighlightFollowsCurrentItem(bool autoHighlight) Q_D(QDeclarativeGridView); if (d->autoHighlight != autoHighlight) { d->autoHighlight = autoHighlight; - if (d->highlightXAnimator) { - d->highlightXAnimator->setEnabled(d->autoHighlight); - d->highlightYAnimator->setEnabled(d->autoHighlight); - } d->updateHighlight(); } } @@ -1484,9 +1482,9 @@ void QDeclarativeGridView::viewportMoved() d->updateCurrent(idx); if (d->currentItem && d->currentItem->colPos() != d->highlight->colPos() && d->autoHighlight) { if (d->flow == LeftToRight) - d->highlightXAnimator->setSourceValue(d->currentItem->item->x()); + d->highlightXAnimator->to = d->currentItem->item->x(); else - d->highlightYAnimator->setSourceValue(d->currentItem->item->y()); + d->highlightYAnimator->to = d->currentItem->item->y(); } } } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index ef8d2fd..6a4f4b9 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -44,7 +44,7 @@ #include "qdeclarativeflickable_p_p.h" #include "qdeclarativevisualitemmodel_p.h" -#include <qdeclarativeeasefollow_p.h> +#include "qdeclarativeeasefollow_p_p.h" #include <qdeclarativeexpression.h> #include <qdeclarativeengine.h> #include <qdeclarativeguard_p.h> @@ -455,8 +455,8 @@ public: enum MovementReason { Other, SetIndex, Mouse }; MovementReason moveReason; int buffer; - QDeclarativeEaseFollow *highlightPosAnimator; - QDeclarativeEaseFollow *highlightSizeAnimator; + QSmoothedAnimation *highlightPosAnimator; + QSmoothedAnimation *highlightSizeAnimator; QDeclarativeViewSection *sectionCriteria; QString currentSection; static const int sectionCacheSize = 3; @@ -825,15 +825,15 @@ void QDeclarativeListViewPrivate::createHighlight() } } const QLatin1String posProp(orient == QDeclarativeListView::Vertical ? "y" : "x"); - highlightPosAnimator = new QDeclarativeEaseFollow(q); - highlightPosAnimator->setTarget(QDeclarativeProperty(highlight->item, posProp)); - highlightPosAnimator->setVelocity(highlightMoveSpeed); - highlightPosAnimator->setEnabled(autoHighlight); + highlightPosAnimator = new QSmoothedAnimation(q); + highlightPosAnimator->target = QDeclarativeProperty(highlight->item, posProp); + highlightPosAnimator->velocity = highlightMoveSpeed; + highlightPosAnimator->restart(); const QLatin1String sizeProp(orient == QDeclarativeListView::Vertical ? "height" : "width"); - highlightSizeAnimator = new QDeclarativeEaseFollow(q); - highlightSizeAnimator->setVelocity(highlightResizeSpeed); - highlightSizeAnimator->setTarget(QDeclarativeProperty(highlight->item, sizeProp)); - highlightSizeAnimator->setEnabled(autoHighlight); + highlightSizeAnimator = new QSmoothedAnimation(q); + highlightSizeAnimator->velocity = highlightResizeSpeed; + highlightSizeAnimator->target = QDeclarativeProperty(highlight->item, sizeProp); + highlightSizeAnimator->restart(); changed = true; } } @@ -847,8 +847,8 @@ void QDeclarativeListViewPrivate::updateHighlight() createHighlight(); if (currentItem && autoHighlight && highlight && !moving) { // auto-update highlight - highlightPosAnimator->setSourceValue(currentItem->position()); - highlightSizeAnimator->setSourceValue(currentItem->size()); + highlightPosAnimator->to = currentItem->position(); + highlightSizeAnimator->to = currentItem->size(); if (orient == QDeclarativeListView::Vertical) { if (highlight->item->width() == 0) highlight->item->setWidth(currentItem->item->width()); @@ -856,6 +856,8 @@ void QDeclarativeListViewPrivate::updateHighlight() if (highlight->item->height() == 0) highlight->item->setHeight(currentItem->item->height()); } + highlightPosAnimator->restart(); + highlightSizeAnimator->restart(); } updateTrackedItem(); } @@ -1604,10 +1606,6 @@ void QDeclarativeListView::setHighlightFollowsCurrentItem(bool autoHighlight) Q_D(QDeclarativeListView); if (d->autoHighlight != autoHighlight) { d->autoHighlight = autoHighlight; - if (d->highlightPosAnimator) { - d->highlightPosAnimator->setEnabled(d->autoHighlight); - d->highlightSizeAnimator->setEnabled(d->autoHighlight); - } d->updateHighlight(); emit highlightFollowsCurrentItemChanged(); } @@ -1867,7 +1865,7 @@ void QDeclarativeListView::setHighlightMoveSpeed(qreal speed) if (d->highlightMoveSpeed != speed) { d->highlightMoveSpeed = speed; if (d->highlightPosAnimator) - d->highlightPosAnimator->setVelocity(d->highlightMoveSpeed); + d->highlightPosAnimator->velocity = d->highlightMoveSpeed; emit highlightMoveSpeedChanged(); } } @@ -1884,7 +1882,7 @@ void QDeclarativeListView::setHighlightResizeSpeed(qreal speed) if (d->highlightResizeSpeed != speed) { d->highlightResizeSpeed = speed; if (d->highlightSizeAnimator) - d->highlightSizeAnimator->setVelocity(d->highlightResizeSpeed); + d->highlightSizeAnimator->velocity = d->highlightResizeSpeed; emit highlightResizeSpeedChanged(); } } diff --git a/src/declarative/qml/qdeclarativeproperty.h b/src/declarative/qml/qdeclarativeproperty.h index 73bccf3..8f6ea48 100644 --- a/src/declarative/qml/qdeclarativeproperty.h +++ b/src/declarative/qml/qdeclarativeproperty.h @@ -131,6 +131,11 @@ private: }; typedef QList<QDeclarativeProperty> QDeclarativeProperties; +inline uint qHash (const QDeclarativeProperty &key) +{ + return qHash(key.object()) + qHash(key.name()); +} + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index bad142c..ba1444e 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1078,15 +1078,26 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QObject *parent) : QDeclarativePropertyAnimation(parent) { - Q_D(QDeclarativePropertyAnimation); - d->interpolatorType = QMetaType::QReal; - d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); + init(); +} + +QDeclarativeNumberAnimation::QDeclarativeNumberAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent) +: QDeclarativePropertyAnimation(dd, parent) +{ + init(); } QDeclarativeNumberAnimation::~QDeclarativeNumberAnimation() { } +void QDeclarativeNumberAnimation::init() +{ + Q_D(QDeclarativePropertyAnimation); + d->interpolatorType = QMetaType::QReal; + d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); +} + /*! \qmlproperty real NumberAnimation::from This property holds the starting value. @@ -2237,8 +2248,10 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions } d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped); d->va->setFromSourcedValue(&data->fromSourced); + d->actions = &data->actions; } else { delete data; + d->actions = 0; } } diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 816520e..f620786 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -251,8 +251,8 @@ public: QDeclarativePropertyAnimation(QObject *parent=0); virtual ~QDeclarativePropertyAnimation(); - int duration() const; - void setDuration(int); + virtual int duration() const; + virtual void setDuration(int); QVariant from() const; void setFrom(const QVariant &); @@ -326,6 +326,12 @@ public: qreal to() const; void setTo(qreal); + +protected: + QDeclarativeNumberAnimation(QDeclarativePropertyAnimationPrivate &dd, QObject *parent); + +private: + void init(); }; class Q_AUTOTEST_EXPORT QDeclarativeVector3dAnimation : public QDeclarativePropertyAnimation diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 2a66c8a..8bcbeff 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -304,7 +304,7 @@ class QDeclarativePropertyAnimationPrivate : public QDeclarativeAbstractAnimatio public: QDeclarativePropertyAnimationPrivate() : QDeclarativeAbstractAnimationPrivate(), target(0), fromSourced(false), fromIsDefined(false), toIsDefined(false), - rangeIsSet(false), defaultToInterpolatorType(0), interpolatorType(0), interpolator(0), va(0) {} + rangeIsSet(false), defaultToInterpolatorType(0), interpolatorType(0), interpolator(0), va(0), actions(0) {} void init(); @@ -330,6 +330,9 @@ public: QDeclarativeBulkValueAnimator *va; + // for animations that dont use the QDeclarativeBulkValueAnimator + QDeclarativeStateActions *actions; + static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress); static void convertVariant(QVariant &variant, int type); }; diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp index 7181777..87d6836 100644 --- a/src/declarative/util/qdeclarativebehavior.cpp +++ b/src/declarative/util/qdeclarativebehavior.cpp @@ -163,7 +163,8 @@ void QDeclarativeBehavior::write(const QVariant &value) d->currentValue = d->property.read(); - d->animation->qtAnimation()->stop(); + if (d->animation->qtAnimation()->duration() != -1) + d->animation->qtAnimation()->stop(); QDeclarativeStateOperation::ActionList actions; QDeclarativeAction action; diff --git a/src/declarative/util/qdeclarativeeasefollow.cpp b/src/declarative/util/qdeclarativeeasefollow.cpp index ee181dd..ce2c496 100644 --- a/src/declarative/util/qdeclarativeeasefollow.cpp +++ b/src/declarative/util/qdeclarativeeasefollow.cpp @@ -40,86 +40,79 @@ ****************************************************************************/ #include "qdeclarativeeasefollow_p.h" +#include "qdeclarativeeasefollow_p_p.h" #include "qdeclarativeanimation_p_p.h" #include <qdeclarativeproperty.h> +#include "qdeclarativeproperty_p.h" + +#include "qdeclarativeglobal_p.h" #include <QtCore/qdebug.h> #include <math.h> +#include <QTimer> + +#define DELAY_STOP_TIMER_INTERVAL 32 QT_BEGIN_NAMESPACE +QSmoothedAnimation::QSmoothedAnimation(QObject *parent) + : QAbstractAnimation(parent), to(0), velocity(200), userDuration(-1), maximumEasingTime(-1), + reversingMode(QDeclarativeSmoothedAnimation::Eased), initialVelocity(0), + trackVelocity(0), initialValue(0), invert(false), finalDuration(-1), lastTime(0) +{ + delayedStopTimer.setInterval(DELAY_STOP_TIMER_INTERVAL); + delayedStopTimer.setSingleShot(true); + connect(&delayedStopTimer, SIGNAL(timeout()), this, SLOT(stop())); +} +void QSmoothedAnimation::restart() +{ + if (state() != QAbstractAnimation::Running) + start(); + else + init(); +} -class QDeclarativeEaseFollowPrivate : public QObjectPrivate +void QSmoothedAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/) { - Q_DECLARE_PUBLIC(QDeclarativeEaseFollow) -public: - QDeclarativeEaseFollowPrivate() - : source(0), velocity(200), duration(-1), maximumEasingTime(-1), - reversingMode(QDeclarativeEaseFollow::Eased), initialVelocity(0), - initialValue(0), invert(false), enabled(true), trackVelocity(0), clockOffset(0), - lastTick(0), clock(this) - {} - - qreal source; - qreal velocity; - qreal duration; - qreal maximumEasingTime; - QDeclarativeEaseFollow::ReversingMode reversingMode; - - qreal initialVelocity; - qreal initialValue; - bool invert; - bool enabled; - - qreal trackVelocity; - - QDeclarativeProperty target; - - int clockOffset; - int lastTick; - void tick(int); - void clockStart(); - void clockStop(); - QTickAnimationProxy<QDeclarativeEaseFollowPrivate, &QDeclarativeEaseFollowPrivate::tick> clock; - - void restart(); - - // Parameters for use in tick() - qreal a; // Acceleration - qreal d; // Deceleration - qreal tf; // Total time - qreal tp; // Time at which peak velocity occurs - qreal td; // Time at which decelleration begins - qreal vp; // Velocity at tp - qreal sp; // Displacement at tp - qreal sd; // Displacement at td - qreal vi; // "Normalized" initialvelocity - bool recalc(); -}; - -bool QDeclarativeEaseFollowPrivate::recalc() + if (newState == QAbstractAnimation::Running) + init(); +} + +void QSmoothedAnimation::delayedStop() { - qreal s = source - initialValue; + if (!delayedStopTimer.isActive()) + delayedStopTimer.start(); +} + +int QSmoothedAnimation::duration() const +{ + return -1; +} + +bool QSmoothedAnimation::recalc() +{ + s = to - initialValue; vi = initialVelocity; - s = (invert?-1.0:1.0) * s; - vi = (invert?-1.0:1.0) * vi; + s = (invert? -1.0: 1.0) * s; - if (duration > 0 && velocity > 0) { + if (userDuration > 0 && velocity > 0) { tf = s / velocity; - if (tf > (duration / 1000.)) tf = (duration / 1000.); - } else if (duration > 0) { - tf = duration / 1000.; + if (tf > (userDuration / 1000.)) tf = (userDuration / 1000.); + } else if (userDuration > 0) { + tf = userDuration / 1000.; } else if (velocity > 0) { tf = s / velocity; } else { return false; } + finalDuration = ceil(tf * 1000.0); + if (maximumEasingTime == 0) { a = 0; d = 0; @@ -129,7 +122,6 @@ bool QDeclarativeEaseFollowPrivate::recalc() sp = 0; sd = s; } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / 1000.)) { - qreal met = maximumEasingTime / 1000.; td = tf - met; @@ -138,7 +130,6 @@ bool QDeclarativeEaseFollowPrivate::recalc() qreal c3 = -0.5 * (tf - td) * vi * vi; qreal vp1 = (-c2 + sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); - // qreal vp2 = (-c2 - sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); vp = vp1; a = vp / met; @@ -147,21 +138,16 @@ bool QDeclarativeEaseFollowPrivate::recalc() sp = vi * tp + 0.5 * a * tp * tp; sd = sp + (td - tp) * vp; } else { - qreal c1 = 0.25 * tf * tf; qreal c2 = 0.5 * vi * tf - s; qreal c3 = -0.25 * vi * vi; qreal a1 = (-c2 + sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); - //qreal a2 = (-c2 - sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); qreal tp1 = 0.5 * tf - 0.5 * vi / a1; - //qreal tp2 = 0.5 * tf - 0.5 * vi / a2; qreal vp1 = a1 * tp1 + vi; - //qreal vp2 = a2 * tp2 + vi; qreal sp1 = 0.5 * a1 * tp1 * tp1 + vi * tp1; - //qreal sp2 = 0.5 * a2 * tp2 * tp2 + vi * tp2; a = a1; d = a1; @@ -171,92 +157,103 @@ bool QDeclarativeEaseFollowPrivate::recalc() sp = sp1; sd = sp1; } - - /* - qWarning() << "a:" << a << "tf:" << tf << "tp:" << tp << "vp:" - << vp << "sp:" << sp << "vi:" << vi << "invert:" << invert; - */ return true; } -void QDeclarativeEaseFollowPrivate::clockStart() +qreal QSmoothedAnimation::easeFollow(qreal time_seconds) { - if (clock.state() == QAbstractAnimation::Running) { - clockOffset = lastTick; - return; + qreal value; + if (time_seconds < tp) { + trackVelocity = vi + time_seconds * a; + value = 0.5 * a * time_seconds * time_seconds + vi * time_seconds; + } else if (time_seconds < td) { + time_seconds -= tp; + trackVelocity = vp; + value = sp + time_seconds * vp; + } else if (time_seconds < tf) { + time_seconds -= td; + trackVelocity = vp - time_seconds * a; + value = sd - 0.5 * d * time_seconds * time_seconds + vp * time_seconds; } else { - clockOffset = 0; - lastTick = 0; - clock.start(); + trackVelocity = 0; + value = s; + delayedStop(); } -} -void QDeclarativeEaseFollowPrivate::clockStop() -{ - clockOffset = 0; - lastTick = 0; - clock.stop(); + // to normalize 's' between [0..1], divide 'value' by 's' + return value; } -void QDeclarativeEaseFollowPrivate::tick(int t) +void QSmoothedAnimation::updateCurrentTime(int t) { - lastTick = t; - t -= clockOffset; - - qreal time_seconds = qreal(t) / 1000.; - - qreal out = 0; - if (time_seconds < tp) { - - trackVelocity = vi + time_seconds * a; - trackVelocity = (invert?-1.0:1.0) * trackVelocity; - - qreal value = 0.5 * a * time_seconds * time_seconds + vi * time_seconds; - value = (invert?-1.0:1.0) * value; - target.write(initialValue + value); - out = initialValue + value; - } else if (time_seconds < td) { + qreal time_seconds = qreal(t - lastTime) / 1000.; - time_seconds -= tp; - trackVelocity = (invert?-1.0:1.0) * vp; - qreal value = sp + time_seconds * vp; - value = (invert?-1.0:1.0) * value; + qreal value = easeFollow(time_seconds); + value *= (invert? -1.0: 1.0); + QDeclarativePropertyPrivate::write(target, initialValue + value, + QDeclarativePropertyPrivate::BypassInterceptor + | QDeclarativePropertyPrivate::DontRemoveBinding); +} - target.write(initialValue + value); +void QSmoothedAnimation::init() +{ + if (velocity == 0) { + stop(); + return; + } - out = initialValue + value; - } else if (time_seconds < tf) { + if (delayedStopTimer.isActive()) + delayedStopTimer.stop(); - time_seconds -= td; + initialValue = target.read().toReal(); + lastTime = this->currentTime(); - trackVelocity = vp - time_seconds * a; - trackVelocity = (invert?-1.0:1.0) * trackVelocity; + if (to == initialValue) { + stop(); + return; + } - qreal value = sd - 0.5 * d * time_seconds * time_seconds + vp * time_seconds; - value = (invert?-1.0:1.0) * value; + bool hasReversed = trackVelocity != 0. && + ((trackVelocity > 0) == ((initialValue - to) > 0)); - target.write(initialValue + value); + if (hasReversed) { + switch (reversingMode) { + default: + case QDeclarativeSmoothedAnimation::Eased: + break; + case QDeclarativeSmoothedAnimation::Sync: + QDeclarativePropertyPrivate::write(target, to, + QDeclarativePropertyPrivate::BypassInterceptor + | QDeclarativePropertyPrivate::DontRemoveBinding); + return; + case QDeclarativeSmoothedAnimation::Immediate: + initialVelocity = 0; + delayedStop(); + break; + } + } - out = initialValue + value; - } else { + trackVelocity = initialVelocity; - clock.stop(); + invert = (to < initialValue); - trackVelocity = 0; - target.write(source); + if (!recalc()) { + QDeclarativePropertyPrivate::write(target, to, + QDeclarativePropertyPrivate::BypassInterceptor + | QDeclarativePropertyPrivate::DontRemoveBinding); + stop(); + return; } - - //qWarning() << out << trackVelocity << t << a; } /*! - \qmlclass EaseFollow QDeclarativeEaseFollow + \qmlclass SmoothedAnimation QDeclarativeSmoothedAnimation \since 4.7 - \brief The EaseFollow element allows a property to smoothly track a value. + \brief The SmoothedAnimation element allows a property to smoothly track a value. - The EaseFollow smoothly animates a property's value to a set target value - using an ease in/out quad easing curve. If the target value changes while - the animation is in progress, the easing curves used to animate to the old + The SmoothedAnimation smoothly animates a property's value to a set target value + using an ease in/out quad easing curve. If the animation is restarted + with a different target value, the easing curves used to animate to the old and the new target values are spliced together to avoid any obvious visual glitches. @@ -282,9 +279,9 @@ Rectangle { Rectangle { color: "green" width: 60; height: 60; - x: -5; y: -5; - EaseFollow on x { source: rect1.x - 5; velocity: 200 } - EaseFollow on y { source: rect1.y - 5; velocity: 200 } + x: rect1.x - 5; y: rect1.y - 5; + Behavior on x { SmoothedAnimation { velocity: 200 } } + Behavior on y { SmoothedAnimation { velocity: 200 } } } Rectangle { @@ -301,7 +298,7 @@ Rectangle { } \endcode - The default velocity of EaseFollow is 200 units/second. Note that if the range of the + The default velocity of SmoothedAnimation is 200 units/second. Note that if the range of the value being animated is small, then the velocity will need to be adjusted appropriately. For example, the opacity of an item ranges from 0 - 1.0. To enable a smooth animation in this range the velocity will need to be @@ -311,226 +308,176 @@ Rectangle { \sa SpringFollow */ -QDeclarativeEaseFollow::QDeclarativeEaseFollow(QObject *parent) -: QObject(*(new QDeclarativeEaseFollowPrivate), parent) +QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent) +: QDeclarativeNumberAnimation(*(new QDeclarativeSmoothedAnimationPrivate), parent) { } -QDeclarativeEaseFollow::~QDeclarativeEaseFollow() +QDeclarativeSmoothedAnimation::~QDeclarativeSmoothedAnimation() { } -/*! - \qmlproperty qreal EaseFollow::source - This property holds the source value which will be tracked. - - Bind to a property in order to track its changes. -*/ -qreal QDeclarativeEaseFollow::sourceValue() const +QDeclarativeSmoothedAnimationPrivate::QDeclarativeSmoothedAnimationPrivate() + : wrapperGroup(new QParallelAnimationGroup), anim(new QSmoothedAnimation) { - Q_D(const QDeclarativeEaseFollow); - return d->source; + Q_Q(QDeclarativeSmoothedAnimation); + QDeclarative_setParent_noEvent(wrapperGroup, q); + QDeclarative_setParent_noEvent(anim, q); } -/*! - \qmlproperty enumeration EaseFollow::reversingMode - - Sets how the EaseFollow behaves if an animation direction is reversed. - - If reversing mode is \c Eased, the animation will smoothly decelerate, and - then reverse direction. If the reversing mode is \c Immediate, the - animation will immediately begin accelerating in the reverse direction, - begining with a velocity of 0. If the reversing mode is \c Sync, the - property is immediately set to the target value. -*/ -QDeclarativeEaseFollow::ReversingMode QDeclarativeEaseFollow::reversingMode() const +QAbstractAnimation* QDeclarativeSmoothedAnimation::qtAnimation() { - Q_D(const QDeclarativeEaseFollow); - return d->reversingMode; + Q_D(QDeclarativeSmoothedAnimation); + return d->wrapperGroup; } -void QDeclarativeEaseFollow::setReversingMode(ReversingMode m) +void QDeclarativeSmoothedAnimation::transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction) { - Q_D(QDeclarativeEaseFollow); - if (d->reversingMode == m) + Q_D(QDeclarativeSmoothedAnimation); + QDeclarativeNumberAnimation::transition(actions, modified, direction); + + if (!d->actions) return; - d->reversingMode = m; - emit reversingModeChanged(); -} + QSet<QAbstractAnimation*> anims; + for (int i = 0; i < d->actions->size(); i++) { + QSmoothedAnimation *ease; + qreal trackVelocity; + bool needsRestart; + if (!d->activeAnimations.contains((*d->actions)[i].property)) { + ease = new QSmoothedAnimation(); + d->wrapperGroup->addAnimation(ease); + d->activeAnimations.insert((*d->actions)[i].property, ease); + trackVelocity = 0.0; + needsRestart = false; + } else { + ease = d->activeAnimations.value((*d->actions)[i].property); + trackVelocity = ease->trackVelocity; + needsRestart = true; + } -void QDeclarativeEaseFollowPrivate::restart() -{ - if (!enabled || velocity == 0) { - clockStop(); - return; - } + ease->target = (*d->actions)[i].property; + ease->to = (*d->actions)[i].toValue.toReal(); - initialValue = target.read().toReal(); + // copying public members from main value holder animation + ease->maximumEasingTime = d->anim->maximumEasingTime; + ease->reversingMode = d->anim->reversingMode; + ease->velocity = d->anim->velocity; + ease->userDuration = d->anim->userDuration; - if (source == initialValue) { - clockStop(); - return; - } + ease->trackVelocity = trackVelocity; + ease->initialVelocity = trackVelocity; - bool hasReversed = trackVelocity != 0. && - ((trackVelocity > 0) == ((initialValue - source) > 0)); + if (needsRestart) + ease->init(); + anims.insert(ease); + } - if (hasReversed) { - switch (reversingMode) { - default: - case QDeclarativeEaseFollow::Eased: - break; - case QDeclarativeEaseFollow::Sync: - target.write(source); - return; - case QDeclarativeEaseFollow::Immediate: - initialVelocity = 0; - clockStop(); - break; + for (int i = d->wrapperGroup->animationCount() - 1; i >= 0 ; --i) { + if (!anims.contains(d->wrapperGroup->animationAt(i))) { + QSmoothedAnimation *ease = static_cast<QSmoothedAnimation*>(d->wrapperGroup->animationAt(i)); + d->activeAnimations.remove(ease->target); + d->wrapperGroup->takeAnimation(i); + delete ease; } } +} - trackVelocity = initialVelocity; - - invert = (source < initialValue); +/*! + \qmlproperty enumeration SmoothedAnimation::reversingMode - if (!recalc()) { - target.write(source); - clockStop(); - return; - } + Sets how the SmoothedAnimation behaves if an animation direction is reversed. - clockStart(); + If reversing mode is \c Eased, the animation will smoothly decelerate, and + then reverse direction. If the reversing mode is \c Immediate, the + animation will immediately begin accelerating in the reverse direction, + begining with a velocity of 0. If the reversing mode is \c Sync, the + property is immediately set to the target value. +*/ +QDeclarativeSmoothedAnimation::ReversingMode QDeclarativeSmoothedAnimation::reversingMode() const +{ + Q_D(const QDeclarativeSmoothedAnimation); + return (QDeclarativeSmoothedAnimation::ReversingMode) d->anim->reversingMode; } -void QDeclarativeEaseFollow::setSourceValue(qreal s) +void QDeclarativeSmoothedAnimation::setReversingMode(ReversingMode m) { - Q_D(QDeclarativeEaseFollow); - - if (d->clock.state() == QAbstractAnimation::Running && d->source == s) + Q_D(QDeclarativeSmoothedAnimation); + if (d->anim->reversingMode == m) return; - d->source = s; - d->initialVelocity = d->trackVelocity; - d->restart(); - - emit sourceChanged(); + d->anim->reversingMode = m; + emit reversingModeChanged(); } /*! - \qmlproperty qreal EaseFollow::duration + \qmlproperty int SmoothedAnimation::duration - This property holds the animation duration used when tracking the source. + This property holds the animation duration, in msecs, used when tracking the source. Setting this to -1 (the default) disables the duration value. */ -qreal QDeclarativeEaseFollow::duration() const +int QDeclarativeSmoothedAnimation::duration() const { - Q_D(const QDeclarativeEaseFollow); - return d->duration; + Q_D(const QDeclarativeSmoothedAnimation); + return d->anim->userDuration; } -void QDeclarativeEaseFollow::setDuration(qreal v) +void QDeclarativeSmoothedAnimation::setDuration(int duration) { - Q_D(QDeclarativeEaseFollow); - if (d->duration == v) - return; - - d->duration = v; - d->trackVelocity = 0; - - if (d->clock.state() == QAbstractAnimation::Running) - d->restart(); - - emit durationChanged(); + Q_D(QDeclarativeSmoothedAnimation); + if (duration != -1) + QDeclarativeNumberAnimation::setDuration(duration); + d->anim->userDuration = duration; } -qreal QDeclarativeEaseFollow::velocity() const +qreal QDeclarativeSmoothedAnimation::velocity() const { - Q_D(const QDeclarativeEaseFollow); - return d->velocity; + Q_D(const QDeclarativeSmoothedAnimation); + return d->anim->velocity; } /*! - \qmlproperty qreal EaseFollow::velocity + \qmlproperty qreal SmoothedAnimation::velocity - This property holds the average velocity allowed when tracking the source. + This property holds the average velocity allowed when tracking the 'to' value. - The default velocity of EaseFollow is 200 units/second. + The default velocity of SmoothedAnimation is 200 units/second. Setting this to -1 disables the velocity value. */ -void QDeclarativeEaseFollow::setVelocity(qreal v) +void QDeclarativeSmoothedAnimation::setVelocity(qreal v) { - Q_D(QDeclarativeEaseFollow); - if (d->velocity == v) + Q_D(QDeclarativeSmoothedAnimation); + if (d->anim->velocity == v) return; - d->velocity = v; - d->trackVelocity = 0; - - if (d->clock.state() == QAbstractAnimation::Running) - d->restart(); - + d->anim->velocity = v; emit velocityChanged(); } /*! - \qmlproperty bool EaseFollow::enabled - This property holds whether the target will track the source. -*/ -bool QDeclarativeEaseFollow::enabled() const -{ - Q_D(const QDeclarativeEaseFollow); - return d->enabled; -} - -void QDeclarativeEaseFollow::setEnabled(bool enabled) -{ - Q_D(QDeclarativeEaseFollow); - if (d->enabled == enabled) - return; - - d->enabled = enabled; - if (enabled) - d->restart(); - else - d->clockStop(); - - emit enabledChanged(); -} - -void QDeclarativeEaseFollow::setTarget(const QDeclarativeProperty &t) -{ - Q_D(QDeclarativeEaseFollow); - d->target = t; -} +\qmlproperty qreal SmoothedAnimation::maximumEasingTime -/*! -\qmlproperty qreal EaseFollow::maximumEasingTime - -This property specifies the maximum time an "eases" during the follow should take. +This property specifies the maximum time, in msecs, an "eases" during the follow should take. Setting this property causes the velocity to "level out" after at a time. Setting a negative value reverts to the normal mode of easing over the entire animation duration. The default value is -1. */ -qreal QDeclarativeEaseFollow::maximumEasingTime() const +int QDeclarativeSmoothedAnimation::maximumEasingTime() const { - Q_D(const QDeclarativeEaseFollow); - return d->maximumEasingTime; + Q_D(const QDeclarativeSmoothedAnimation); + return d->anim->maximumEasingTime; } -void QDeclarativeEaseFollow::setMaximumEasingTime(qreal v) +void QDeclarativeSmoothedAnimation::setMaximumEasingTime(int v) { - Q_D(QDeclarativeEaseFollow); - d->maximumEasingTime = v; - - if (d->clock.state() == QAbstractAnimation::Running) - d->restart(); - + Q_D(QDeclarativeSmoothedAnimation); + d->anim->maximumEasingTime = v; emit maximumEasingTimeChanged(); } diff --git a/src/declarative/util/qdeclarativeeasefollow_p.h b/src/declarative/util/qdeclarativeeasefollow_p.h index 83d1eff..6c17d4f 100644 --- a/src/declarative/util/qdeclarativeeasefollow_p.h +++ b/src/declarative/util/qdeclarativeeasefollow_p.h @@ -43,7 +43,7 @@ #define QDECLARATIVEEASEFOLLOW_H #include <qdeclarative.h> -#include <qdeclarativepropertyvaluesource.h> +#include "qdeclarativeanimation_p.h" #include <QtCore/qobject.h> @@ -54,60 +54,50 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeProperty; -class QDeclarativeEaseFollowPrivate; -class Q_DECLARATIVE_EXPORT QDeclarativeEaseFollow : public QObject, - public QDeclarativePropertyValueSource +class QDeclarativeSmoothedAnimationPrivate; +class Q_DECLARATIVE_EXPORT QDeclarativeSmoothedAnimation : public QDeclarativeNumberAnimation { Q_OBJECT - Q_DECLARE_PRIVATE(QDeclarativeEaseFollow) - Q_INTERFACES(QDeclarativePropertyValueSource) + Q_DECLARE_PRIVATE(QDeclarativeSmoothedAnimation) Q_ENUMS(ReversingMode) - Q_PROPERTY(qreal source READ sourceValue WRITE setSourceValue NOTIFY sourceChanged) Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) - Q_PROPERTY(qreal duration READ duration WRITE setDuration NOTIFY durationChanged) Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged) - Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged) public: enum ReversingMode { Eased, Immediate, Sync }; - QDeclarativeEaseFollow(QObject *parent = 0); - ~QDeclarativeEaseFollow(); + QDeclarativeSmoothedAnimation(QObject *parent = 0); + ~QDeclarativeSmoothedAnimation(); ReversingMode reversingMode() const; void setReversingMode(ReversingMode); - qreal sourceValue() const; - void setSourceValue(qreal); + virtual int duration() const; + virtual void setDuration(int); qreal velocity() const; void setVelocity(qreal); - qreal duration() const; - void setDuration(qreal); + int maximumEasingTime() const; + void setMaximumEasingTime(int); - bool enabled() const; - void setEnabled(bool enabled); - - qreal maximumEasingTime() const; - void setMaximumEasingTime(qreal); - - virtual void setTarget(const QDeclarativeProperty &); +public: + virtual void transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction); + QAbstractAnimation* qtAnimation(); Q_SIGNALS: - void sourceChanged(); void velocityChanged(); - void durationChanged(); void reversingModeChanged(); - void enabledChanged(); void maximumEasingTimeChanged(); }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QDeclarativeEaseFollow); +QML_DECLARE_TYPE(QDeclarativeSmoothedAnimation); QT_END_HEADER diff --git a/src/declarative/util/qdeclarativeeasefollow_p_p.h b/src/declarative/util/qdeclarativeeasefollow_p_p.h new file mode 100644 index 0000000..e71a009 --- /dev/null +++ b/src/declarative/util/qdeclarativeeasefollow_p_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVESMOOTHEDANIMATION_P_H +#define QDECLARATIVESMOOTHEDANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qdeclarativeanimation_p.h" +#include "qdeclarativeeasefollow_p.h" + +#include "qdeclarativeanimation_p_p.h" + +#include <qparallelanimationgroup.h> + +#include <private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +class QSmoothedAnimation : public QAbstractAnimation +{ +public: + QSmoothedAnimation(QObject *parent=0); + + qreal to; + qreal velocity; + int userDuration; + + int maximumEasingTime; + QDeclarativeSmoothedAnimation::ReversingMode reversingMode; + + qreal initialVelocity; + qreal trackVelocity; + + QDeclarativeProperty target; + + int duration() const; + void restart(); + void init(); + +protected: + virtual void updateCurrentTime(int); + virtual void updateState(QAbstractAnimation::State, QAbstractAnimation::State); + +private: + qreal easeFollow(qreal); + qreal initialValue; + + bool invert; + + int finalDuration; + + // Parameters for use in updateCurrentTime() + qreal a; // Acceleration + qreal d; // Deceleration + qreal tf; // Total time + qreal tp; // Time at which peak velocity occurs + qreal td; // Time at which decelleration begins + qreal vp; // Velocity at tp + qreal sp; // Displacement at tp + qreal sd; // Displacement at td + qreal vi; // "Normalized" initialvelocity + qreal s; // Total s + + int lastTime; + + bool recalc(); + void delayedStop(); + + QTimer delayedStopTimer; +}; + +class QDeclarativeSmoothedAnimationPrivate : public QDeclarativePropertyAnimationPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativeSmoothedAnimation) +public: + QDeclarativeSmoothedAnimationPrivate(); + + QParallelAnimationGroup *wrapperGroup; + QSmoothedAnimation *anim; + QHash<QDeclarativeProperty, QSmoothedAnimation*> activeAnimations; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVESMOOTHEDANIMATION_P_H diff --git a/src/declarative/util/qdeclarativespringfollow.cpp b/src/declarative/util/qdeclarativespringfollow.cpp index 76d7c98..063c3df 100644 --- a/src/declarative/util/qdeclarativespringfollow.cpp +++ b/src/declarative/util/qdeclarativespringfollow.cpp @@ -242,8 +242,6 @@ void QDeclarativeSpringFollowPrivate::stop() SpringFollow on y { source: rect1.y; velocity: 200 } } \endcode - - \sa EaseFollow */ QDeclarativeSpringFollow::QDeclarativeSpringFollow(QObject *parent) diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index 4326a55..1e8be7f 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -116,9 +116,9 @@ void QDeclarativeTransitionPrivate::append_animation(QDeclarativeListProperty<QD void ParallelAnimationWrapper::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) { QParallelAnimationGroup::updateState(newState, oldState); - if (newState == Stopped && - ((direction() == QAbstractAnimation::Forward && currentLoopTime() == duration()) || - (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0))) + if (newState == Stopped && (duration() == -1 + || (direction() == QAbstractAnimation::Forward && currentLoopTime() == duration()) + || (direction() == QAbstractAnimation::Backward && currentLoopTime() == 0))) { trans->complete(); } diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 2a02ffe..bf50a8b 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -111,7 +111,7 @@ void QDeclarativeUtilModule::defineModule() qmlRegisterType<QDeclarativeBind>("Qt",4,6,"Binding"); qmlRegisterType<QDeclarativeColorAnimation>("Qt",4,6,"ColorAnimation"); qmlRegisterType<QDeclarativeConnections>("Qt",4,6,"Connections"); - qmlRegisterType<QDeclarativeEaseFollow>("Qt",4,6,"EaseFollow"); + qmlRegisterType<QDeclarativeSmoothedAnimation>("Qt",4,6,"SmoothedAnimation"); qmlRegisterType<QDeclarativeFontLoader>("Qt",4,6,"FontLoader"); qmlRegisterType<QDeclarativeListElement>("Qt",4,6,"ListElement"); qmlRegisterType<QDeclarativeNumberAnimation>("Qt",4,6,"NumberAnimation"); diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index f537806..249465a 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -38,6 +38,7 @@ HEADERS += \ $$PWD/qdeclarativesystempalette_p.h \ $$PWD/qdeclarativespringfollow_p.h \ $$PWD/qdeclarativeeasefollow_p.h \ + $$PWD/qdeclarativeeasefollow_p_p.h \ $$PWD/qdeclarativestate_p.h\ $$PWD/qdeclarativestateoperations_p.h \ $$PWD/qdeclarativepropertychanges_p.h \ diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml index 0cc19eb..cfece41 100644 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml +++ b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml @@ -1,3 +1,3 @@ import Qt 4.6 -EaseFollow {} +SmoothedAnimation {} diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml index b65964e..74a110d 100644 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml +++ b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml @@ -1,5 +1,5 @@ import Qt 4.6 -EaseFollow { - source: 10; duration: 300; enabled: true; reversingMode: EaseFollow.Immediate +SmoothedAnimation { + to: 10; duration: 300; reversingMode: SmoothedAnimation.Immediate } diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow3.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow3.qml index f8886e9..3111e82 100644 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow3.qml +++ b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow3.qml @@ -1,6 +1,6 @@ import Qt 4.6 -EaseFollow { - source: 10; velocity: 250; enabled: false; reversingMode: EaseFollow.Sync +SmoothedAnimation { + to: 10; velocity: 250; reversingMode: SmoothedAnimation.Sync maximumEasingTime: 150 } diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowBehavior.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowBehavior.qml new file mode 100644 index 0000000..eb06344 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowBehavior.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Rectangle { + width: 400; height: 400; color: "blue" + + Rectangle { + id: rect1 + color: "red" + width: 60; height: 60; + x: 100; y: 100; + SmoothedAnimation on x { to: 200; velocity: 500 } + SmoothedAnimation on y { to: 200; velocity: 500 } + } + + Rectangle { + objectName: "theRect" + color: "green" + width: 60; height: 60; + x: rect1.x; y: rect1.y; + Behavior on x { SmoothedAnimation { objectName: "easeX"; velocity: 400 } } + Behavior on y { SmoothedAnimation { objectName: "easeY"; velocity: 400 } } + } + } diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowValueSource.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowValueSource.qml new file mode 100644 index 0000000..9ae744c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowValueSource.qml @@ -0,0 +1,13 @@ +import Qt 4.6 + +Rectangle { + width: 300; height: 300; + Rectangle { + objectName: "theRect" + color: "red" + width: 60; height: 60; + x: 100; y: 100; + SmoothedAnimation on x { objectName: "easeX"; to: 200; velocity: 500 } + SmoothedAnimation on y { objectName: "easeY"; to: 200; duration: 250; velocity: 500 } + } +} diff --git a/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp b/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp index 036eec0..401688b 100644 --- a/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp +++ b/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp @@ -42,6 +42,7 @@ #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> #include <private/qdeclarativeeasefollow_p.h> +#include <private/qdeclarativerectangle_p.h> #include <private/qdeclarativevaluetype_p.h> #include "../../../shared/util.h" @@ -55,6 +56,9 @@ private slots: void defaultValues(); void values(); void disabled(); + void simpleAnimation(); + void valueSource(); + void behavior(); private: QDeclarativeEngine engine; @@ -68,16 +72,15 @@ void tst_qdeclarativeeasefollow::defaultValues() { QDeclarativeEngine engine; QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollow1.qml")); - QDeclarativeEaseFollow *obj = qobject_cast<QDeclarativeEaseFollow*>(c.create()); + QDeclarativeSmoothedAnimation *obj = qobject_cast<QDeclarativeSmoothedAnimation*>(c.create()); QVERIFY(obj != 0); - QCOMPARE(obj->sourceValue(), 0.); + QCOMPARE(obj->to(), 0.); QCOMPARE(obj->velocity(), 200.); - QCOMPARE(obj->enabled(), true); - QCOMPARE(obj->duration(), -1.); - QCOMPARE(obj->maximumEasingTime(), -1.); - QCOMPARE(obj->reversingMode(), QDeclarativeEaseFollow::Eased); + QCOMPARE(obj->duration(), -1); + QCOMPARE(obj->maximumEasingTime(), -1); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Eased); delete obj; } @@ -86,16 +89,15 @@ void tst_qdeclarativeeasefollow::values() { QDeclarativeEngine engine; QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollow2.qml")); - QDeclarativeEaseFollow *obj = qobject_cast<QDeclarativeEaseFollow*>(c.create()); + QDeclarativeSmoothedAnimation *obj = qobject_cast<QDeclarativeSmoothedAnimation*>(c.create()); QVERIFY(obj != 0); - QCOMPARE(obj->sourceValue(), 10.); + QCOMPARE(obj->to(), 10.); QCOMPARE(obj->velocity(), 200.); - QCOMPARE(obj->enabled(), true); - QCOMPARE(obj->duration(), 300.); - QCOMPARE(obj->maximumEasingTime(), -1.); - QCOMPARE(obj->reversingMode(), QDeclarativeEaseFollow::Immediate); + QCOMPARE(obj->duration(), 300); + QCOMPARE(obj->maximumEasingTime(), -1); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Immediate); delete obj; } @@ -104,19 +106,102 @@ void tst_qdeclarativeeasefollow::disabled() { QDeclarativeEngine engine; QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollow3.qml")); - QDeclarativeEaseFollow *obj = qobject_cast<QDeclarativeEaseFollow*>(c.create()); + QDeclarativeSmoothedAnimation *obj = qobject_cast<QDeclarativeSmoothedAnimation*>(c.create()); QVERIFY(obj != 0); - QCOMPARE(obj->sourceValue(), 10.); + QCOMPARE(obj->to(), 10.); QCOMPARE(obj->velocity(), 250.); - QCOMPARE(obj->enabled(), false); - QCOMPARE(obj->maximumEasingTime(), 150.); - QCOMPARE(obj->reversingMode(), QDeclarativeEaseFollow::Sync); + QCOMPARE(obj->maximumEasingTime(), 150); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Sync); delete obj; } +void tst_qdeclarativeeasefollow::simpleAnimation() +{ + QDeclarativeRectangle rect; + QDeclarativeSmoothedAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(250); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "x"); + QVERIFY(animation.to() == 200); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTRY_COMPARE(rect.x(), qreal(200)); + + rect.setX(0); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.x(), qreal(100)); +} + +void tst_qdeclarativeeasefollow::valueSource() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollowValueSource.qml")); + + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create()); + QVERIFY(rect); + + QDeclarativeRectangle *theRect = rect->findChild<QDeclarativeRectangle*>("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild<QDeclarativeSmoothedAnimation*>("easeX"); + QVERIFY(easeX); + QVERIFY(easeX->isRunning()); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild<QDeclarativeSmoothedAnimation*>("easeY"); + QVERIFY(easeY); + QVERIFY(easeY->isRunning()); + + // XXX get the proper duration + QTest::qWait(100); + + QTRY_VERIFY(!easeX->isRunning()); + QTRY_VERIFY(!easeY->isRunning()); + + QTRY_COMPARE(theRect->x(), qreal(200)); + QTRY_COMPARE(theRect->y(), qreal(200)); +} + +void tst_qdeclarativeeasefollow::behavior() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollowBehavior.qml")); + + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create()); + QVERIFY(rect); + + QDeclarativeRectangle *theRect = rect->findChild<QDeclarativeRectangle*>("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild<QDeclarativeSmoothedAnimation*>("easeX"); + QVERIFY(easeX); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild<QDeclarativeSmoothedAnimation*>("easeY"); + QVERIFY(easeY); + + // XXX get the proper duration + QTest::qWait(400); + + QTRY_VERIFY(!easeX->isRunning()); + QTRY_VERIFY(!easeY->isRunning()); + + QTRY_COMPARE(theRect->x(), qreal(200)); + QTRY_COMPARE(theRect->y(), qreal(200)); +} + QTEST_MAIN(tst_qdeclarativeeasefollow) #include "tst_qdeclarativeeasefollow.moc" diff --git a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml index cc64c3f..40fc436 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml @@ -98,7 +98,7 @@ Rectangle { }, Component { id: invalidHl - EaseFollow {} + SmoothedAnimation {} } ] ListView { diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml index 121328b..ee94857 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml @@ -15,26 +15,31 @@ Rectangle { Rectangle { width: 50; height: 20; y: 60; color: "red" - EaseFollow on x { source: rect.x; velocity: 400 } + x: rect.x + Behavior on x { SmoothedAnimation { velocity: 400 } } } Rectangle { width: 50; height: 20; y: 90; color: "yellow" - EaseFollow on x { source: rect.x; velocity: 300; reversingMode: EaseFollow.Immediate } + x: rect.x + Behavior on x { SmoothedAnimation { velocity: 300; reversingMode: SmoothedAnimation.Immediate } } } Rectangle { width: 50; height: 20; y: 120; color: "green" - EaseFollow on x { source: rect.x; reversingMode: EaseFollow.Sync } + x: rect.x + Behavior on x { SmoothedAnimation { reversingMode: SmoothedAnimation.Sync } } } Rectangle { width: 50; height: 20; y: 150; color: "purple" - EaseFollow on x { source: rect.x; maximumEasingTime: 200 } + x: rect.x + Behavior on x { SmoothedAnimation { maximumEasingTime: 200 } } } Rectangle { width: 50; height: 20; y: 180; color: "blue" - EaseFollow on x { source: rect.x; duration: 300 } + x: rect.x + Behavior on x { SmoothedAnimation { duration: 300 } } } } diff --git a/tests/auto/declarative/qmlvisual/qdeclarativegridview/gridview2.qml b/tests/auto/declarative/qmlvisual/qdeclarativegridview/gridview2.qml index f4fb863..d8512eb 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativegridview/gridview2.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativegridview/gridview2.qml @@ -48,9 +48,12 @@ Rectangle { flickableData: [ Rectangle { color: "transparent"; border.color: "white"; border.width: 8; z: 3000 - height: 100; width: 100; x: 4; y: 4 - EaseFollow on x { source: gridView.currentItem.x; velocity: 500 } - EaseFollow on y { source: gridView.currentItem.y; velocity: 500 } + height: 100; width: 100 + x: gridView.currentItem.x + y: gridView.currentItem.y + + Behavior on x { SmoothedAnimation { velocity: 500 } } + Behavior on y { SmoothedAnimation { velocity: 500 } } } ] } |