summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-07-08 06:11:21 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-07-08 06:11:21 (GMT)
commit239c3581bb84b6484547918fbb1672fed08970dd (patch)
tree2a4305f528d10c1ff359ec3d17e6f4e9c4b40633
parentf727b2fd8d29907f59e11fc18c48329588fa4284 (diff)
downloadQt-239c3581bb84b6484547918fbb1672fed08970dd.zip
Qt-239c3581bb84b6484547918fbb1672fed08970dd.tar.gz
Qt-239c3581bb84b6484547918fbb1672fed08970dd.tar.bz2
Add a modulus property to Follow to allow "wrapping".
Also add clock example to demonstrate.
-rw-r--r--examples/declarative/clock/Clock.qml78
-rw-r--r--examples/declarative/clock/background.pngbin0 -> 46895 bytes
-rw-r--r--examples/declarative/clock/display.qml5
-rw-r--r--examples/declarative/clock/hour.pngbin0 -> 391 bytes
-rw-r--r--examples/declarative/clock/minute.pngbin0 -> 445 bytes
-rw-r--r--examples/declarative/clock/second.pngbin0 -> 345 bytes
-rw-r--r--src/declarative/util/qmlfollow.cpp57
-rw-r--r--src/declarative/util/qmlfollow.h4
8 files changed, 139 insertions, 5 deletions
diff --git a/examples/declarative/clock/Clock.qml b/examples/declarative/clock/Clock.qml
new file mode 100644
index 0000000..4779bd5
--- /dev/null
+++ b/examples/declarative/clock/Clock.qml
@@ -0,0 +1,78 @@
+Item {
+ id: Clock
+ width: 200; height: 200
+ property var time
+ property var hours
+ property var minutes
+ property var seconds
+ onTimeChanged: {
+ var date = new Date;
+ hours = date.getHours();
+ minutes = date.getMinutes();
+ seconds = date.getSeconds();
+ }
+ Timer {
+ interval: 500; running: true; repeat: true; triggeredOnStart: true
+ onTriggered: Clock.time = new Date()
+ }
+
+ Image { source: "background.png" }
+ Image {
+ x: 95
+ y: 54
+ source: "hour.png"
+ smooth: true
+ transform: Rotation {
+ id: HourRotation
+ originX: 4; originY: 45
+ angle: 0
+ angle: Follow {
+ spring: 2
+ damping: .2
+ source: Clock.hours * 50 * 3 + Clock.minutes / 2
+ }
+ }
+ }
+ Image {
+ x: 95
+ y: 30
+ source: "minute.png"
+ smooth: true
+ transform: Rotation {
+ id: MinuteRotation
+ originX: 4; originY: 70
+ angle: 0
+ angle: Follow {
+ spring: 2
+ damping: .2
+ source: Clock.minutes * 6
+ }
+ }
+ }
+ Image {
+ x: 96
+ y: 40
+ source: "second.png"
+ smooth: true
+ transform: Rotation {
+ id: SecondRotation
+ originX: 2; originY: 60
+ angle: 0
+ angle: Follow {
+ spring: 5
+ damping: .25
+ modulus: 360
+ source: Clock.seconds * 6
+ }
+ }
+ }
+
+ Rect {
+ x: 93
+ y: 94
+ width: 11
+ height: 11
+ radius: 5
+ color: "black"
+ }
+}
diff --git a/examples/declarative/clock/background.png b/examples/declarative/clock/background.png
new file mode 100644
index 0000000..a885950
--- /dev/null
+++ b/examples/declarative/clock/background.png
Binary files differ
diff --git a/examples/declarative/clock/display.qml b/examples/declarative/clock/display.qml
new file mode 100644
index 0000000..0187a7e
--- /dev/null
+++ b/examples/declarative/clock/display.qml
@@ -0,0 +1,5 @@
+Rect {
+ width: contents.width
+ height: contents.height
+ Clock { id: Clock }
+}
diff --git a/examples/declarative/clock/hour.png b/examples/declarative/clock/hour.png
new file mode 100644
index 0000000..603466b
--- /dev/null
+++ b/examples/declarative/clock/hour.png
Binary files differ
diff --git a/examples/declarative/clock/minute.png b/examples/declarative/clock/minute.png
new file mode 100644
index 0000000..0207405
--- /dev/null
+++ b/examples/declarative/clock/minute.png
Binary files differ
diff --git a/examples/declarative/clock/second.png b/examples/declarative/clock/second.png
new file mode 100644
index 0000000..bfcef68
--- /dev/null
+++ b/examples/declarative/clock/second.png
Binary files differ
diff --git a/src/declarative/util/qmlfollow.cpp b/src/declarative/util/qmlfollow.cpp
index c6d806a..b8e6685 100644
--- a/src/declarative/util/qmlfollow.cpp
+++ b/src/declarative/util/qmlfollow.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <limits.h>
+#include <math.h>
#include <QtCore/qdebug.h>
#include "private/qobject_p.h"
#include "qmlfollow.h"
@@ -55,7 +56,7 @@ class QmlFollowPrivate : public QObjectPrivate
public:
QmlFollowPrivate()
: sourceValue(0), maxVelocity(0), lastTime(0)
- , mass(1.0), spring(0.), damping(0.), velocity(0), epsilon(0.005), enabled(true), mode(Track), clock(this) {}
+ , mass(1.0), spring(0.), damping(0.), velocity(0), epsilon(0.005), modulus(0.0), enabled(true), mode(Track), clock(this) {}
QmlMetaProperty property;
qreal currentValue;
@@ -68,6 +69,7 @@ public:
qreal damping;
qreal velocity;
qreal epsilon;
+ qreal modulus;
bool enabled;
enum Mode {
@@ -92,6 +94,11 @@ void QmlFollowPrivate::tick(int time)
int elapsed = time - lastTime;
if (!elapsed)
return;
+ qreal srcVal = sourceValue;
+ if (modulus != 0.0) {
+ currentValue = fmod(currentValue, modulus);
+ srcVal = fmod(srcVal, modulus);
+ }
if (mode == Spring) {
if (elapsed < 16) // capped at 62fps.
return;
@@ -99,7 +106,13 @@ void QmlFollowPrivate::tick(int time)
// We'll do something much simpler which gives a result that looks fine.
int count = (elapsed+8) / 16;
for (int i = 0; i < count; ++i) {
- qreal diff = sourceValue - currentValue;
+ qreal diff = srcVal - currentValue;
+ if (modulus != 0.0 && qAbs(diff) > modulus / 2) {
+ if (diff < 0)
+ diff += modulus;
+ else
+ diff -= modulus;
+ }
velocity = velocity + spring * diff - damping * velocity;
// The following line supports mass. Not sure its worth the extra divisions.
// velocity = velocity + spring / mass * diff - damping / mass * velocity;
@@ -111,24 +124,39 @@ void QmlFollowPrivate::tick(int time)
velocity = -maxVelocity;
}
currentValue += velocity * 16.0 / 1000.0;
+ if (modulus != 0.0) {
+ currentValue = fmod(currentValue, modulus);
+ if (currentValue < 0.0)
+ currentValue += modulus;
+ }
}
- if (qAbs(velocity) < epsilon && qAbs(sourceValue - currentValue) < epsilon) {
+ if (qAbs(velocity) < epsilon && qAbs(srcVal - currentValue) < epsilon) {
velocity = 0.0;
- currentValue = sourceValue;
+ currentValue = srcVal;
clock.stop();
}
lastTime = time - (elapsed - count * 16);
} else {
qreal moveBy = elapsed * velocityms;
- qreal diff = sourceValue - currentValue;
+ qreal diff = srcVal - currentValue;
+ if (modulus != 0.0 && qAbs(diff) > modulus / 2) {
+ if (diff < 0)
+ diff += modulus;
+ else
+ diff -= modulus;
+ }
if (diff > 0) {
currentValue += moveBy;
+ if (modulus != 0.0)
+ currentValue = fmod(currentValue, modulus);
if (currentValue > sourceValue) {
currentValue = sourceValue;
clock.stop();
}
} else {
currentValue -= moveBy;
+ if (modulus != 0.0 && currentValue < 0.0)
+ currentValue = fmod(currentValue, modulus) + modulus;
if (currentValue < sourceValue) {
currentValue = sourceValue;
clock.stop();
@@ -326,6 +354,25 @@ void QmlFollow::setEpsilon(qreal epsilon)
}
/*!
+ \qmlproperty qreal Follow::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 QmlFollow::modulus() const
+{
+ Q_D(const QmlFollow);
+ return d->modulus;
+}
+
+void QmlFollow::setModulus(qreal modulus)
+{
+ Q_D(QmlFollow);
+ d->modulus = modulus;
+}
+
+/*!
\qmlproperty qreal Follow::followValue
The current value.
*/
diff --git a/src/declarative/util/qmlfollow.h b/src/declarative/util/qmlfollow.h
index 0953f2c..07e15e9 100644
--- a/src/declarative/util/qmlfollow.h
+++ b/src/declarative/util/qmlfollow.h
@@ -64,8 +64,10 @@ class Q_DECLARATIVE_EXPORT QmlFollow : public QmlPropertyValueSource,
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)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
Q_PROPERTY(qreal followValue READ value NOTIFY valueChanged)
+ Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged)
public:
QmlFollow(QObject *parent=0);
@@ -83,6 +85,8 @@ public:
void setDamping(qreal damping);
qreal epsilon() const;
void setEpsilon(qreal epsilon);
+ qreal modulus() const;
+ void setModulus(qreal modulus);
bool enabled() const;
void setEnabled(bool enabled);