summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/declarative/qml-intro.qdoc14
-rw-r--r--examples/declarative/ui-components/dialcontrol/content/Dial.qml19
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp10
-rw-r--r--src/declarative/util/qdeclarativeanimation_p.h1
-rw-r--r--src/declarative/util/qdeclarativebehavior.cpp27
-rw-r--r--src/declarative/util/qdeclarativebehavior_p.h3
-rw-r--r--src/declarative/util/qdeclarativespringanimation.cpp435
-rw-r--r--src/declarative/util/qdeclarativespringanimation_p.h126
-rw-r--r--src/declarative/util/qdeclarativeutilmodule.cpp2
-rw-r--r--src/declarative/util/util.pri2
10 files changed, 622 insertions, 17 deletions
diff --git a/doc/src/declarative/qml-intro.qdoc b/doc/src/declarative/qml-intro.qdoc
index 21ce2dd..fbab001 100644
--- a/doc/src/declarative/qml-intro.qdoc
+++ b/doc/src/declarative/qml-intro.qdoc
@@ -923,16 +923,18 @@ the rotation of the needle image. Notice this piece of code in Dial where
the change in \c value modifies the position of the needle.
\code
- SpringFollow on angle {
- spring: 1.4
- damping: .15
- to: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
+ angle: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
+ Behavior on angle {
+ SpringAnimation {
+ spring: 1.4
+ damping: .15
+ }
}
\endcode
This is part of the \c needleRotation that rotates the needle and causes the
-rotation of its shadow. \l SpringFollow is an element that modifies the value
-of that rotation angle \e to and mimics the oscillatory behavior of a spring,
+rotation of its shadow. \l SpringAnimation is an element that modifies the value
+of that rotation \e angle and mimics the oscillatory behavior of a spring,
with the appropriate \e spring constant to control the acceleration and the \e
damping to control how quickly the effect dies away.
diff --git a/examples/declarative/ui-components/dialcontrol/content/Dial.qml b/examples/declarative/ui-components/dialcontrol/content/Dial.qml
index 2b421bf..b5074a64 100644
--- a/examples/declarative/ui-components/dialcontrol/content/Dial.qml
+++ b/examples/declarative/ui-components/dialcontrol/content/Dial.qml
@@ -50,11 +50,11 @@ Item {
//! [needle_shadow]
Image {
- x: 93
+ x: 96
y: 35
source: "needle_shadow.png"
transform: Rotation {
- origin.x: 11; origin.y: 67
+ origin.x: 9; origin.y: 67
angle: needleRotation.angle
}
}
@@ -62,17 +62,18 @@ Item {
//! [needle]
Image {
id: needle
- x: 95; y: 33
+ x: 98; y: 33
smooth: true
source: "needle.png"
transform: Rotation {
id: needleRotation
- origin.x: 7; origin.y: 65
- angle: -130
- SpringFollow on angle {
- spring: 1.4
- damping: .15
- to: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
+ origin.x: 5; origin.y: 65
+ angle: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
+ Behavior on angle {
+ SpringAnimation {
+ spring: 1.4
+ damping: .15
+ }
}
}
}
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index add27f3..6559bd5 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -142,6 +142,16 @@ bool QDeclarativeAbstractAnimation::isRunning() const
return d->running;
}
+// the behavior connects the animation to this slot
+void QDeclarativeAbstractAnimation::behaviorControlRunningChanged(bool running)
+{
+ Q_D(QDeclarativeAbstractAnimation);
+ if (d->disableUserControl && d->running != running) {
+ d->running = running;
+ emit runningChanged(running);
+ }
+}
+
//commence is called to start an animation when it is used as a
//simple animation, and not as part of a transition
void QDeclarativeAbstractAnimationPrivate::commence()
diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h
index 3f8fbdd..2279b0e 100644
--- a/src/declarative/util/qdeclarativeanimation_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p.h
@@ -134,6 +134,7 @@ public:
private Q_SLOTS:
void timelineComplete();
void componentFinalized();
+ void behaviorControlRunningChanged(bool running);
private:
virtual void setTarget(const QDeclarativeProperty &);
diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp
index 047993e..4480e75 100644
--- a/src/declarative/util/qdeclarativebehavior.cpp
+++ b/src/declarative/util/qdeclarativebehavior.cpp
@@ -58,7 +58,8 @@ class QDeclarativeBehaviorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QDeclarativeBehavior)
public:
- QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false) {}
+ QDeclarativeBehaviorPrivate() : animation(0), enabled(true), finalized(false)
+ , blockRunningChanged(false) {}
QDeclarativeProperty property;
QVariant currentValue;
@@ -66,6 +67,7 @@ public:
QDeclarativeGuard<QDeclarativeAbstractAnimation> animation;
bool enabled;
bool finalized;
+ bool blockRunningChanged;
};
/*!
@@ -132,9 +134,26 @@ void QDeclarativeBehavior::setAnimation(QDeclarativeAbstractAnimation *animation
if (d->animation) {
d->animation->setDefaultTarget(d->property);
d->animation->setDisableUserControl();
+ connect(d->animation->qtAnimation(),
+ SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
+ this,
+ SLOT(qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
+ connect(this,
+ SIGNAL(qtAnimationRunningChanged(bool)),
+ d->animation,
+ SLOT(behaviorControlRunningChanged(bool)));
}
}
+
+void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State newState,QAbstractAnimation::State)
+{
+ Q_D(QDeclarativeBehavior);
+ if (!d->blockRunningChanged)
+ emit qtAnimationRunningChanged(newState == QAbstractAnimation::Running);
+}
+
+
/*!
\qmlproperty bool Behavior::enabled
Whether the Behavior will be triggered when the property it is tracking changes.
@@ -173,8 +192,11 @@ void QDeclarativeBehavior::write(const QVariant &value)
d->currentValue = d->property.read();
d->targetValue = value;
- if (d->animation->qtAnimation()->duration() != -1)
+ if (d->animation->qtAnimation()->duration() != -1
+ && d->animation->qtAnimation()->state() != QAbstractAnimation::Stopped) {
+ d->blockRunningChanged = true;
d->animation->qtAnimation()->stop();
+ }
QDeclarativeStateOperation::ActionList actions;
QDeclarativeAction action;
@@ -186,6 +208,7 @@ void QDeclarativeBehavior::write(const QVariant &value)
QList<QDeclarativeProperty> after;
d->animation->transition(actions, after, QDeclarativeAbstractAnimation::Forward);
d->animation->qtAnimation()->start();
+ d->blockRunningChanged = false;
if (!after.contains(d->property))
QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
}
diff --git a/src/declarative/util/qdeclarativebehavior_p.h b/src/declarative/util/qdeclarativebehavior_p.h
index 6c10eec..a3132d9 100644
--- a/src/declarative/util/qdeclarativebehavior_p.h
+++ b/src/declarative/util/qdeclarativebehavior_p.h
@@ -47,6 +47,7 @@
#include <qdeclarativepropertyvaluesource.h>
#include <qdeclarativepropertyvalueinterceptor.h>
#include <qdeclarative.h>
+#include <QtCore/QAbstractAnimation>
QT_BEGIN_HEADER
@@ -82,9 +83,11 @@ public:
Q_SIGNALS:
void enabledChanged();
+ void qtAnimationRunningChanged(bool running);
private Q_SLOTS:
void componentFinalized();
+ void qtAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State);
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp
new file mode 100644
index 0000000..314b82b
--- /dev/null
+++ b/src/declarative/util/qdeclarativespringanimation.cpp
@@ -0,0 +1,435 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "private/qdeclarativespringanimation_p.h"
+
+#include "private/qdeclarativeanimation_p_p.h"
+#include <qdeclarativeproperty_p.h>
+
+#include <QtCore/qdebug.h>
+
+#include <private/qobject_p.h>
+
+#include <limits.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+
+
+class QDeclarativeSpringAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeSpringAnimation)
+public:
+ QDeclarativeSpringAnimationPrivate()
+ : currentValue(0), to(0), from(0), maxVelocity(0), lastTime(0)
+ , mass(1.0), spring(0.), damping(0.), velocity(0), epsilon(0.01)
+ , modulus(0.0), useMass(false), haveModulus(false), enabled(true)
+ , fromDefined(false), toDefined(false)
+ , mode(Track), clock(this) {}
+
+ qreal currentValue;
+ qreal to;
+ qreal from;
+ qreal maxVelocity;
+ qreal velocityms;
+ int lastTime;
+ qreal mass;
+ qreal spring;
+ qreal damping;
+ qreal velocity;
+ qreal epsilon;
+ qreal modulus;
+
+ bool useMass : 1;
+ bool haveModulus : 1;
+ bool enabled : 1;
+ bool fromDefined : 1;
+ bool toDefined : 1;
+
+ enum Mode {
+ Track,
+ Velocity,
+ Spring
+ };
+ Mode mode;
+
+ void tick(int);
+ void updateMode();
+
+ QTickAnimationProxy<QDeclarativeSpringAnimationPrivate, &QDeclarativeSpringAnimationPrivate::tick> clock;
+};
+
+void QDeclarativeSpringAnimationPrivate::tick(int time)
+{
+ if (mode == Track) {
+ clock.stop();
+ return;
+ }
+
+ int elapsed = time - lastTime;
+ if (!elapsed)
+ return;
+ qreal srcVal = to;
+
+ bool stop = false;
+
+ if (haveModulus) {
+ currentValue = fmod(currentValue, modulus);
+ srcVal = fmod(srcVal, modulus);
+ }
+ if (mode == Spring) {
+ if (elapsed < 16) // capped at 62fps.
+ return;
+ // Real men solve the spring DEs using RK4.
+ // We'll do something much simpler which gives a result that looks fine.
+ int count = elapsed / 16;
+ for (int i = 0; i < count; ++i) {
+ qreal diff = srcVal - currentValue;
+ if (haveModulus && qAbs(diff) > modulus / 2) {
+ if (diff < 0)
+ diff += modulus;
+ else
+ diff -= modulus;
+ }
+ if (useMass)
+ velocity = velocity + (spring * diff - damping * velocity) / mass;
+ else
+ velocity = velocity + spring * diff - damping * velocity;
+ if (maxVelocity > 0.) {
+ // limit velocity
+ if (velocity > maxVelocity)
+ velocity = maxVelocity;
+ else if (velocity < -maxVelocity)
+ velocity = -maxVelocity;
+ }
+ currentValue += velocity * 16.0 / 1000.0;
+ if (haveModulus) {
+ currentValue = fmod(currentValue, modulus);
+ if (currentValue < 0.0)
+ currentValue += modulus;
+ }
+ }
+ if (qAbs(velocity) < epsilon && qAbs(srcVal - currentValue) < epsilon) {
+ velocity = 0.0;
+ currentValue = srcVal;
+ stop = true;
+ }
+ lastTime = time - (elapsed - count * 16);
+ } else {
+ qreal moveBy = elapsed * velocityms;
+ qreal diff = srcVal - currentValue;
+ if (haveModulus && qAbs(diff) > modulus / 2) {
+ if (diff < 0)
+ diff += modulus;
+ else
+ diff -= modulus;
+ }
+ if (diff > 0) {
+ currentValue += moveBy;
+ if (haveModulus)
+ currentValue = fmod(currentValue, modulus);
+ if (currentValue > to) {
+ currentValue = to;
+ stop = true;
+ }
+ } else {
+ currentValue -= moveBy;
+ if (haveModulus && currentValue < 0.0)
+ currentValue = fmod(currentValue, modulus) + modulus;
+ if (currentValue < to) {
+ currentValue = to;
+ stop = true;
+ }
+ }
+ lastTime = time;
+ }
+
+ QDeclarativePropertyPrivate::write(defaultProperty, currentValue,
+ QDeclarativePropertyPrivate::BypassInterceptor |
+ QDeclarativePropertyPrivate::DontRemoveBinding);
+
+ if (stop)
+ clock.stop();
+}
+
+void QDeclarativeSpringAnimationPrivate::updateMode()
+{
+ if (spring == 0. && maxVelocity == 0.)
+ mode = Track;
+ else if (spring > 0.)
+ mode = Spring;
+ else
+ mode = Velocity;
+}
+
+/*!
+ \qmlclass SpringAnimation QDeclarativeSpringAnimation
+ \since 4.7
+*/
+
+QDeclarativeSpringAnimation::QDeclarativeSpringAnimation(QObject *parent)
+: QDeclarativeAbstractAnimation(*(new QDeclarativeSpringAnimationPrivate),parent)
+{
+}
+
+QDeclarativeSpringAnimation::~QDeclarativeSpringAnimation()
+{
+}
+
+void QDeclarativeSpringAnimation::setTarget(const QDeclarativeProperty &property)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ d->defaultProperty = property;
+ d->currentValue = property.read().toReal();
+ if (!d->avoidPropertyValueSourceStart) {
+ setRunning(true);
+ }
+}
+
+qreal QDeclarativeSpringAnimation::to() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->toDefined ? d->to : 0;
+}
+
+/*!
+ \qmlproperty real SpringFollow::to
+*/
+
+void QDeclarativeSpringAnimation::setTo(qreal value)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ if (d->to == value)
+ return;
+
+ d->to = value;
+ d->toDefined = true;
+ d->lastTime = 0;
+ emit toChanged(value);
+}
+
+qreal QDeclarativeSpringAnimation::from() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->fromDefined ? d->from : 0;
+}
+
+/*!
+ \qmlproperty real SpringFollow::from
+*/
+
+void QDeclarativeSpringAnimation::setFrom(qreal value)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ if (d->from == value)
+ return;
+
+ d->currentValue = d->from = value;
+ d->fromDefined = true;
+ d->lastTime = 0;
+ emit fromChanged(value);
+}
+
+
+/*!
+ \qmlproperty real SpringAnimation::velocity
+ This property holds the maximum velocity allowed when tracking the source.
+*/
+
+qreal QDeclarativeSpringAnimation::velocity() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->maxVelocity;
+}
+
+void QDeclarativeSpringAnimation::setVelocity(qreal velocity)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ d->maxVelocity = velocity;
+ d->velocityms = velocity / 1000.0;
+ d->updateMode();
+}
+
+/*!
+ \qmlproperty real SpringAnimation::spring
+ This property holds the spring constant
+
+ The spring constant describes how strongly the target is pulled towards the
+ source. Setting spring to 0 turns off spring tracking. Useful values 0 - 5.0
+
+ When a spring constant is set and the velocity property is greater than 0,
+ velocity limits the maximum speed.
+*/
+qreal QDeclarativeSpringAnimation::spring() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->spring;
+}
+
+void QDeclarativeSpringAnimation::setSpring(qreal spring)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ d->spring = spring;
+ d->updateMode();
+}
+
+/*!
+ \qmlproperty real SpringAnimation::damping
+ This property holds the spring damping constant
+
+ The damping constant describes how quickly a sprung follower comes to rest.
+ Useful range is 0 - 1.0
+*/
+qreal QDeclarativeSpringAnimation::damping() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->damping;
+}
+
+void QDeclarativeSpringAnimation::setDamping(qreal damping)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ if (damping > 1.)
+ damping = 1.;
+
+ d->damping = damping;
+}
+
+
+/*!
+ \qmlproperty real SpringAnimation::epsilon
+ This property holds the spring epsilon
+
+ The epsilon is the rate and amount of change in the value which is close enough
+ to 0 to be considered equal to zero. This will depend on the usage of the value.
+ For pixel positions, 0.25 would suffice. For scale, 0.005 will suffice.
+
+ The default is 0.01. Tuning this value can provide small performance improvements.
+*/
+qreal QDeclarativeSpringAnimation::epsilon() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->epsilon;
+}
+
+void QDeclarativeSpringAnimation::setEpsilon(qreal epsilon)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ d->epsilon = epsilon;
+}
+
+/*!
+ \qmlproperty real SpringAnimation::modulus
+ This property holds the modulus value.
+
+ Setting a \a modulus forces the target value to "wrap around" at the modulus.
+ For example, setting the modulus to 360 will cause a value of 370 to wrap around to 10.
+*/
+qreal QDeclarativeSpringAnimation::modulus() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->modulus;
+}
+
+void QDeclarativeSpringAnimation::setModulus(qreal modulus)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ if (d->modulus != modulus) {
+ d->haveModulus = modulus != 0.0;
+ d->modulus = modulus;
+ emit modulusChanged();
+ }
+}
+
+/*!
+ \qmlproperty real SpringAnimation::mass
+ This property holds the "mass" of the property being moved.
+
+ mass is 1.0 by default. Setting a different mass changes the dynamics of
+ a \l spring follow.
+*/
+qreal QDeclarativeSpringAnimation::mass() const
+{
+ Q_D(const QDeclarativeSpringAnimation);
+ return d->mass;
+}
+
+void QDeclarativeSpringAnimation::setMass(qreal mass)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ if (d->mass != mass && mass > 0.0) {
+ d->useMass = mass != 1.0;
+ d->mass = mass;
+ emit massChanged();
+ }
+}
+
+void QDeclarativeSpringAnimation::transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QDeclarativeSpringAnimation);
+ Q_UNUSED(direction);
+
+ if (d->clock.state() != QAbstractAnimation::Running)
+ d->lastTime = 0;
+
+ if (!actions.isEmpty()) {
+ for (int i = 0; i < actions.size(); ++i) {
+ if (!d->toDefined)
+ d->to = actions.at(i).toValue.toReal();
+ if (!d->fromDefined)
+ d->currentValue = actions.at(i).fromValue.toReal();
+ if (d->mode != QDeclarativeSpringAnimationPrivate::Track)
+ modified << d->defaultProperty;
+ }
+ }
+}
+
+
+QAbstractAnimation *QDeclarativeSpringAnimation::qtAnimation()
+{
+ Q_D(QDeclarativeSpringAnimation);
+ return &d->clock;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativespringanimation_p.h b/src/declarative/util/qdeclarativespringanimation_p.h
new file mode 100644
index 0000000..6f574ef
--- /dev/null
+++ b/src/declarative/util/qdeclarativespringanimation_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 QDECLARATIVESPRINGANIMATION_H
+#define QDECLARATIVESPRINGANIMATION_H
+
+#include <qdeclarative.h>
+#include "private/qdeclarativeanimation_p.h"
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeSpringAnimationPrivate;
+class Q_AUTOTEST_EXPORT QDeclarativeSpringAnimation : public QDeclarativeAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDeclarativeSpringAnimation)
+ Q_INTERFACES(QDeclarativePropertyValueSource)
+
+ Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
+ Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
+ Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity)
+ Q_PROPERTY(qreal spring READ spring WRITE setSpring)
+ Q_PROPERTY(qreal damping READ damping WRITE setDamping)
+ Q_PROPERTY(qreal epsilon READ epsilon WRITE setEpsilon)
+ Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged)
+ Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged)
+
+public:
+ QDeclarativeSpringAnimation(QObject *parent=0);
+ ~QDeclarativeSpringAnimation();
+
+ virtual void setTarget(const QDeclarativeProperty &);
+
+ qreal to() const;
+ void setTo(qreal value);
+
+ qreal from() const;
+ void setFrom(qreal value);
+
+ qreal velocity() const;
+ void setVelocity(qreal velocity);
+
+ qreal spring() const;
+ void setSpring(qreal spring);
+
+ qreal damping() const;
+ void setDamping(qreal damping);
+
+ qreal epsilon() const;
+ void setEpsilon(qreal epsilon);
+
+ qreal mass() const;
+ void setMass(qreal modulus);
+
+ qreal modulus() const;
+ void setModulus(qreal modulus);
+
+ bool enabled() const;
+ void setEnabled(bool enabled);
+
+ virtual void transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction);
+
+protected:
+ virtual QAbstractAnimation *qtAnimation();
+
+Q_SIGNALS:
+ void toChanged(qreal);
+ void fromChanged(qreal);
+ void modulusChanged();
+ void massChanged();
+ void syncChanged();
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeSpringAnimation)
+
+QT_END_HEADER
+
+#endif // QDECLARATIVESPRINGANIMATION_H
diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp
index 3cf07a7..74fdac6 100644
--- a/src/declarative/util/qdeclarativeutilmodule.cpp
+++ b/src/declarative/util/qdeclarativeutilmodule.cpp
@@ -57,6 +57,7 @@
#include "private/qdeclarativepropertychanges_p.h"
#include "qdeclarativepropertymap.h"
#include "private/qdeclarativespringfollow_p.h"
+#include "private/qdeclarativespringanimation_p.h"
#include "private/qdeclarativestategroup_p.h"
#include "private/qdeclarativestateoperations_p.h"
#include "private/qdeclarativestate_p.h"
@@ -98,6 +99,7 @@ void QDeclarativeUtilModule::defineModule()
qmlRegisterType<QDeclarativeScriptAction>("Qt",4,7,"ScriptAction");
qmlRegisterType<QDeclarativeSequentialAnimation>("Qt",4,7,"SequentialAnimation");
qmlRegisterType<QDeclarativeSpringFollow>("Qt",4,7,"SpringFollow");
+ qmlRegisterType<QDeclarativeSpringAnimation>("Qt",4,7,"SpringAnimation");
qmlRegisterType<QDeclarativeStateChangeScript>("Qt",4,7,"StateChangeScript");
qmlRegisterType<QDeclarativeStateGroup>("Qt",4,7,"StateGroup");
qmlRegisterType<QDeclarativeState>("Qt",4,7,"State");
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index 04cfc68..0cbcbd7 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -8,6 +8,7 @@ SOURCES += \
$$PWD/qdeclarativeanimation.cpp \
$$PWD/qdeclarativesystempalette.cpp \
$$PWD/qdeclarativespringfollow.cpp \
+ $$PWD/qdeclarativespringanimation.cpp \
$$PWD/qdeclarativesmoothedanimation.cpp \
$$PWD/qdeclarativesmoothedfollow.cpp \
$$PWD/qdeclarativestate.cpp\
@@ -39,6 +40,7 @@ HEADERS += \
$$PWD/qdeclarativeanimation_p_p.h \
$$PWD/qdeclarativesystempalette_p.h \
$$PWD/qdeclarativespringfollow_p.h \
+ $$PWD/qdeclarativespringanimation_p.h \
$$PWD/qdeclarativesmoothedanimation_p.h \
$$PWD/qdeclarativesmoothedfollow_p.h \
$$PWD/qdeclarativesmoothedanimation_p_p.h \