summaryrefslogtreecommitdiffstats
path: root/src/declarative/util
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-07-09 07:10:11 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-07-09 07:10:11 (GMT)
commit5b56189c9a6c322fa595b716a9f17e39a35bcbc0 (patch)
tree2e8b4fc397d631207aa32a8c68c94100a54f0f61 /src/declarative/util
parent888f57107e698731c4a1dd2c46745c6293b2222e (diff)
parent7343bbb230161d563b0226011e4519f695fdc593 (diff)
downloadQt-5b56189c9a6c322fa595b716a9f17e39a35bcbc0.zip
Qt-5b56189c9a6c322fa595b716a9f17e39a35bcbc0.tar.gz
Qt-5b56189c9a6c322fa595b716a9f17e39a35bcbc0.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Conflicts: src/declarative/qml/qmlengine.cpp
Diffstat (limited to 'src/declarative/util')
-rw-r--r--src/declarative/util/qfxperf.cpp2
-rw-r--r--src/declarative/util/qfxperf_p.h (renamed from src/declarative/util/qfxperf.h)13
-rw-r--r--src/declarative/util/qfxview.cpp4
-rw-r--r--src/declarative/util/qmlanimation.cpp70
-rw-r--r--src/declarative/util/qmlanimation_p.h4
-rw-r--r--src/declarative/util/qmlfollow.cpp57
-rw-r--r--src/declarative/util/qmlfollow.h4
-rw-r--r--src/declarative/util/qmlscript.cpp2
-rw-r--r--src/declarative/util/qmltimeline.cpp940
-rw-r--r--src/declarative/util/qmltimeline_p.h224
-rw-r--r--src/declarative/util/qperformancelog.cpp2
-rw-r--r--src/declarative/util/qperformancelog_p.h (renamed from src/declarative/util/qperformancelog.h)0
-rw-r--r--src/declarative/util/util.pri6
13 files changed, 1273 insertions, 55 deletions
diff --git a/src/declarative/util/qfxperf.cpp b/src/declarative/util/qfxperf.cpp
index 9ac9e8d..db56b37 100644
--- a/src/declarative/util/qfxperf.cpp
+++ b/src/declarative/util/qfxperf.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qfxperf.h"
+#include "private/qfxperf_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qfxperf.h b/src/declarative/util/qfxperf_p.h
index 0bc0cc9..a1e38b7 100644
--- a/src/declarative/util/qfxperf.h
+++ b/src/declarative/util/qfxperf_p.h
@@ -41,7 +41,18 @@
#ifndef QFXPERF_H
#define QFXPERF_H
-#include "qperformancelog.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 "private/qperformancelog_p.h"
QT_BEGIN_HEADER
diff --git a/src/declarative/util/qfxview.cpp b/src/declarative/util/qfxview.cpp
index 0855224..0a3afda 100644
--- a/src/declarative/util/qfxview.cpp
+++ b/src/declarative/util/qfxview.cpp
@@ -54,8 +54,8 @@
#include "qmlbindablevalue.h"
#include "qml.h"
#include "qfxitem.h"
-#include "qperformancelog.h"
-#include "qfxperf.h"
+#include "private/qperformancelog_p.h"
+#include "private/qfxperf_p.h"
#include "qfxview.h"
#include <QtDeclarative/qmlengine.h>
diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp
index 6ad47f5..ff070c1 100644
--- a/src/declarative/util/qmlanimation.cpp
+++ b/src/declarative/util/qmlanimation.cpp
@@ -58,12 +58,6 @@
#include <private/qmlstringconverters_p.h>
#include <private/qvariantanimation_p.h>
-/* TODO:
- Check for any memory leaks
- easing should be a QEasingCurve-type property
- All other XXXs and ###s
-*/
-
QT_BEGIN_NAMESPACE
QEasingCurve stringToCurve(const QString &curve)
@@ -1108,7 +1102,7 @@ void QmlParentChangeActionPrivate::init()
void QmlParentChangeActionPrivate::doAction()
{
- //XXX property.write(value);
+ //### property.write(value);
}
void QmlParentChangeAction::prepare(QmlMetaProperty &p)
@@ -1120,7 +1114,7 @@ void QmlParentChangeAction::prepare(QmlMetaProperty &p)
else
d->property = d->userProperty;
- //XXX
+ //###
}
QAbstractAnimation *QmlParentChangeAction::qtAnimation()
@@ -1239,7 +1233,7 @@ QmlNumberAnimation::~QmlNumberAnimation()
qreal QmlNumberAnimation::from() const
{
Q_D(const QmlPropertyAnimation);
- return d->from.toDouble(); //### toFloat?
+ return d->from.toDouble();
}
void QmlNumberAnimation::setFrom(qreal f)
@@ -1259,7 +1253,7 @@ void QmlNumberAnimation::setFrom(qreal f)
qreal QmlNumberAnimation::to() const
{
Q_D(const QmlPropertyAnimation);
- return d->to.toDouble(); //### toFloat?
+ return d->to.toDouble();
}
void QmlNumberAnimation::setTo(qreal t)
@@ -1346,7 +1340,7 @@ void QmlSequentialAnimation::transition(QmlStateActions &actions,
from = d->animations.count() - 1;
}
- //### needed for Behavior
+ //needed for Behavior
if (d->userProperty.isValid() && d->propertyName.isEmpty() && !target()) {
for (int i = 0; i < d->animations.count(); ++i)
d->animations.at(i)->setTarget(d->userProperty);
@@ -1428,7 +1422,7 @@ void QmlParallelAnimation::transition(QmlStateActions &actions,
{
Q_D(QmlAnimationGroup);
- //### needed for Behavior
+ //needed for Behavior
if (d->userProperty.isValid() && d->propertyName.isEmpty() && !target()) {
for (int i = 0; i < d->animations.count(); ++i)
d->animations.at(i)->setTarget(d->userProperty);
@@ -1441,26 +1435,12 @@ void QmlParallelAnimation::transition(QmlStateActions &actions,
QML_DEFINE_TYPE(QmlParallelAnimation,ParallelAnimation)
-//### profile and optimize
-QVariant QmlPropertyAnimationPrivate::interpolateVariant(const QVariant &from, const QVariant &to, qreal progress)
-{
- if (from.userType() != to.userType())
- return QVariant();
-
- QVariantAnimation::Interpolator interpolator = QVariantAnimationPrivate::getInterpolator(from.userType());
- if (interpolator)
- return interpolator(from.constData(), to.constData(), progress);
- else
- return QVariant();
-}
-
//convert a variant from string type to another animatable type
-//### should use any registered string convertor
-//### profile and optimize
-void QmlPropertyAnimationPrivate::convertVariant(QVariant &variant, QVariant::Type type)
+void QmlPropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
{
if (variant.type() != QVariant::String) {
- variant.convert(type);
+ if ((uint)type < QVariant::UserType)
+ variant.convert((QVariant::Type)type);
return;
}
@@ -1494,7 +1474,12 @@ void QmlPropertyAnimationPrivate::convertVariant(QVariant &variant, QVariant::Ty
break;
}
default:
- variant.convert(type);
+ if ((uint)type >= QVariant::UserType) {
+ QmlMetaType::StringConverter converter = QmlMetaType::customStringConverter(type);
+ if (converter)
+ variant = converter(variant.toString());
+ } else
+ variant.convert((QVariant::Type)type);
break;
}
}
@@ -1742,7 +1727,8 @@ void QmlPropertyAnimationPrivate::valueChanged(qreal r)
if (!fromSourced) {
if (!fromIsDefined) {
from = property.read();
- convertVariant(from, (QVariant::Type)(interpolatorType ? interpolatorType : property.propertyType()));
+ convertVariant(from, interpolatorType ? interpolatorType : property.propertyType());
+ //### check for invalid variant if using property type
}
fromSourced = true;
}
@@ -1752,8 +1738,6 @@ void QmlPropertyAnimationPrivate::valueChanged(qreal r)
} else {
if (interpolator)
property.write(interpolator(from.constData(), to.constData(), r));
- else
- property.write(interpolateVariant(from, to, r)); //### optimize
}
}
@@ -1771,9 +1755,15 @@ void QmlPropertyAnimation::prepare(QmlMetaProperty &p)
else
d->property = d->userProperty;
- d->convertVariant(d->to, (QVariant::Type)(d->interpolatorType ? d->interpolatorType : d->property.propertyType()));
+ int propType = d->property.propertyType();
+ d->convertVariant(d->to, d->interpolatorType ? d->interpolatorType : propType);
if (d->fromIsDefined)
- d->convertVariant(d->from, (QVariant::Type)(d->interpolatorType ? d->interpolatorType : d->property.propertyType()));
+ d->convertVariant(d->from, d->interpolatorType ? d->interpolatorType : propType);
+
+ if (!d->interpolatorType) {
+ //### check for invalid variants
+ d->interpolator = QVariantAnimationPrivate::getInterpolator(propType);
+ }
d->fromSourced = false;
d->value.QmlTimeLineValue::setValue(0.);
@@ -1810,7 +1800,7 @@ void QmlPropertyAnimation::transition(QmlStateActions &actions,
if (action.fromValue.isNull()) {
action.fromValue = action.property.read();
if (interpolatorType)
- QmlPropertyAnimationPrivate::convertVariant(action.fromValue, (QVariant::Type)interpolatorType);
+ QmlPropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType);
}
if (!interpolatorType) {
int propType = action.property.propertyType();
@@ -1871,8 +1861,8 @@ void QmlPropertyAnimation::transition(QmlStateActions &actions,
if (d->toIsDefined)
myAction.toValue = d->to;
- d->convertVariant(myAction.fromValue, (QVariant::Type)(d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()));
- d->convertVariant(myAction.toValue, (QVariant::Type)(d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()));
+ d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
+ d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
modified << action.property;
@@ -1890,10 +1880,10 @@ void QmlPropertyAnimation::transition(QmlStateActions &actions,
continue;
if (d->fromIsDefined) {
- d->convertVariant(d->from, (QVariant::Type)(d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()));
+ d->convertVariant(d->from, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
myAction.fromValue = d->from;
}
- d->convertVariant(d->to, (QVariant::Type)(d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()));
+ d->convertVariant(d->to, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType());
myAction.toValue = d->to;
data->actions << myAction;
}
diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h
index fce5eca..87d480f 100644
--- a/src/declarative/util/qmlanimation_p.h
+++ b/src/declarative/util/qmlanimation_p.h
@@ -63,7 +63,7 @@
#include <QtDeclarative/qmlanimation.h>
#include <QtDeclarative/qml.h>
#include <QtDeclarative/qmlcontext.h>
-#include <QtDeclarative/qmltimelinevalueproxy.h>
+#include <private/qmltimeline_p.h>
QT_BEGIN_NAMESPACE
@@ -346,7 +346,7 @@ public:
QmlTimeLineValueProxy<QmlPropertyAnimationPrivate> value;
static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress);
- static void convertVariant(QVariant &variant, QVariant::Type type);
+ static void convertVariant(QVariant &variant, int type);
};
QT_END_NAMESPACE
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);
diff --git a/src/declarative/util/qmlscript.cpp b/src/declarative/util/qmlscript.cpp
index f8cbf96..8d03804 100644
--- a/src/declarative/util/qmlscript.cpp
+++ b/src/declarative/util/qmlscript.cpp
@@ -55,7 +55,7 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QtDeclarative/qmlinfo.h>
-#include <qfxperf.h>
+#include <private/qfxperf_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qmltimeline.cpp b/src/declarative/util/qmltimeline.cpp
new file mode 100644
index 0000000..5ba310d
--- /dev/null
+++ b/src/declarative/util/qmltimeline.cpp
@@ -0,0 +1,940 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmltimeline_p.h"
+#include <QDebug>
+#include <QMutex>
+#include <QThread>
+#include <QWaitCondition>
+#include <QEvent>
+#include <QCoreApplication>
+#include <QEasingCurve>
+#include <QTime>
+
+QT_BEGIN_NAMESPACE
+
+struct Update {
+ Update(QmlTimeLineValue *_g, qreal _v)
+ : g(_g), v(_v) {}
+ Update(const QmlTimeLineEvent &_e)
+ : g(0), v(0), e(_e) {}
+
+ QmlTimeLineValue *g;
+ qreal v;
+ QmlTimeLineEvent e;
+};
+
+struct QmlTimeLinePrivate
+{
+ QmlTimeLinePrivate(QmlTimeLine *);
+
+ struct Op {
+ enum Type {
+ Pause,
+ Set,
+ Move,
+ MoveBy,
+ Accel,
+ AccelDistance,
+ Execute
+ };
+ Op() {}
+ Op(Type t, int l, qreal v, qreal v2, int o,
+ const QmlTimeLineEvent &ev = QmlTimeLineEvent(), const QEasingCurve &es = QEasingCurve())
+ : type(t), length(l), value(v), value2(v2), order(o), event(ev),
+ easing(es) {}
+ Op(const Op &o)
+ : type(o.type), length(o.length), value(o.value), value2(o.value2),
+ order(o.order), event(o.event), easing(o.easing) {}
+ Op &operator=(const Op &o) {
+ type = o.type; length = o.length; value = o.value;
+ value2 = o.value2; order = o.order; event = o.event;
+ easing = o.easing;
+ return *this;
+ }
+
+ Type type;
+ int length;
+ qreal value;
+ qreal value2;
+
+ int order;
+ QmlTimeLineEvent event;
+ QEasingCurve easing;
+ };
+ struct TimeLine
+ {
+ TimeLine() : length(0), consumedOpLength(0), base(0.) {}
+ QList<Op> ops;
+ int length;
+ int consumedOpLength;
+ qreal base;
+ };
+
+ int length;
+ int syncPoint;
+ typedef QHash<QmlTimeLineObject *, TimeLine> Ops;
+ Ops ops;
+ QmlTimeLine *q;
+
+ void add(QmlTimeLineObject &, const Op &);
+ qreal value(const Op &op, int time, qreal base, bool *) const;
+
+ int advance(int);
+
+ bool clockRunning;
+ int prevTime;
+
+ int order;
+
+ QmlTimeLine::SyncMode syncMode;
+ int syncAdj;
+ QList<QPair<int, Update> > *updateQueue;
+};
+
+QmlTimeLinePrivate::QmlTimeLinePrivate(QmlTimeLine *parent)
+: length(0), syncPoint(0), q(parent), clockRunning(false), prevTime(0), order(0), syncMode(QmlTimeLine::LocalSync), syncAdj(0), updateQueue(0)
+{
+}
+
+void QmlTimeLinePrivate::add(QmlTimeLineObject &g, const Op &o)
+{
+ if (g._t && g._t != q) {
+ qWarning() << "QmlTimeLine: Cannot modify a QmlTimeLineValue owned by"
+ << "another timeline.";
+ return;
+ }
+ g._t = q;
+
+ Ops::Iterator iter = ops.find(&g);
+ if (iter == ops.end()) {
+ iter = ops.insert(&g, TimeLine());
+ if (syncPoint > 0)
+ q->pause(g, syncPoint);
+ }
+ if (!iter->ops.isEmpty() &&
+ o.type == Op::Pause &&
+ iter->ops.last().type == Op::Pause) {
+ iter->ops.last().length += o.length;
+ iter->length += o.length;
+ } else {
+ iter->ops.append(o);
+ iter->length += o.length;
+ }
+
+ if (iter->length > length)
+ length = iter->length;
+
+ if (!clockRunning) {
+ q->stop();
+ prevTime = 0;
+ clockRunning = true;
+
+ if (syncMode == QmlTimeLine::LocalSync) {
+ syncAdj = -1;
+ } else {
+ syncAdj = 0;
+ }
+ q->start();
+/* q->tick(0);
+ if (syncMode == QmlTimeLine::LocalSync) {
+ syncAdj = -1;
+ } else {
+ syncAdj = 0;
+ }
+ */
+ }
+}
+
+qreal QmlTimeLinePrivate::value(const Op &op, int time, qreal base, bool *changed) const
+{
+ Q_ASSERT(time >= 0);
+ Q_ASSERT(time <= op.length);
+ *changed = true;
+
+ switch(op.type) {
+ case Op::Pause:
+ *changed = false;
+ return base;
+ case Op::Set:
+ return op.value;
+ case Op::Move:
+ if (time == 0) {
+ return base;
+ } else if (time == (op.length)) {
+ return op.value;
+ } else {
+ qreal delta = op.value - base;
+ qreal pTime = (qreal)(time) / (qreal)op.length;
+ if (op.easing.type() == QEasingCurve::Linear)
+ return base + delta * pTime;
+ else
+ return base + delta * op.easing.valueForProgress(pTime);
+ }
+ case Op::MoveBy:
+ if (time == 0) {
+ return base;
+ } else if (time == (op.length)) {
+ return base + op.value;
+ } else {
+ qreal delta = op.value;
+ qreal pTime = (qreal)(time) / (qreal)op.length;
+ if (op.easing.type() == QEasingCurve::Linear)
+ return base + delta * pTime;
+ else
+ return base + delta * op.easing.valueForProgress(pTime);
+ }
+ case Op::Accel:
+ if (time == 0) {
+ return base;
+ } else {
+ qreal t = (qreal)(time) / 1000.0f;
+ qreal delta = op.value * t + 0.5f * op.value2 * t * t;
+ return base + delta;
+ }
+ case Op::AccelDistance:
+ if (time == 0) {
+ return base;
+ } else if (time == (op.length)) {
+ return base + op.value2;
+ } else {
+ qreal t = (qreal)(time) / 1000.0f;
+ qreal accel = -1.0f * 1000.0f * op.value / (qreal)op.length;
+ qreal delta = op.value * t + 0.5f * accel * t * t;
+ return base + delta;
+
+ }
+ case Op::Execute:
+ op.event.execute();
+ *changed = false;
+ return -1;
+ }
+
+ return base;
+}
+
+/*!
+ \internal
+ \class QmlTimeLine
+ \ingroup group_animation
+ \brief The QmlTimeLine class provides a timeline for controlling animations.
+
+ QmlTimeLine is similar to QTimeLine except:
+ \list
+ \i It updates QmlTimeLineValue instances directly, rather than maintaining a single
+ current value.
+
+ For example, the following animates a simple value over 200 milliseconds:
+ \code
+ QmlTimeLineValue v(<starting value>);
+ QmlTimeLine tl;
+ tl.move(v, 100., 200);
+ tl.start()
+ \endcode
+
+ If your program needs to know when values are changed, it can either
+ connect to the QmlTimeLine's updated() signal, or inherit from QmlTimeLineValue
+ and reimplement the QmlTimeLineValue::setValue() method.
+
+ \i Supports multiple QmlTimeLineValue, arbitrary start and end values and allows
+ animations to be strung together for more complex effects.
+
+ For example, the following animation moves the x and y coordinates of
+ an object from wherever they are to the position (100, 100) in 50
+ milliseconds and then further animates them to (100, 200) in 50
+ milliseconds:
+
+ \code
+ QmlTimeLineValue x(<starting value>);
+ QmlTimeLineValue y(<starting value>);
+
+ QmlTimeLine tl;
+ tl.start();
+
+ tl.move(x, 100., 50);
+ tl.move(y, 100., 50);
+ tl.move(y, 200., 50);
+ \endcode
+
+ \i All QmlTimeLine instances share a single, synchronized clock.
+
+ Actions scheduled within the same event loop tick are scheduled
+ synchronously against each other, regardless of the wall time between the
+ scheduling. Synchronized scheduling applies both to within the same
+ QmlTimeLine and across separate QmlTimeLine's within the same process.
+
+ \endlist
+
+ Currently easing functions are not supported.
+*/
+
+
+/*!
+ Construct a new QmlTimeLine with the specified \a parent.
+*/
+QmlTimeLine::QmlTimeLine(QObject *parent)
+: QAbstractAnimation(parent)
+{
+ d = new QmlTimeLinePrivate(this);
+}
+
+/*!
+ Destroys the time line. Any inprogress animations are canceled, but not
+ completed.
+*/
+QmlTimeLine::~QmlTimeLine()
+{
+ for (QmlTimeLinePrivate::Ops::Iterator iter = d->ops.begin();
+ iter != d->ops.end();
+ ++iter)
+ iter.key()->_t = 0;
+
+ delete d; d = 0;
+}
+
+/*!
+ \enum QmlTimeLine::SyncMode
+ */
+
+/*!
+ Return the timeline's synchronization mode.
+ */
+QmlTimeLine::SyncMode QmlTimeLine::syncMode() const
+{
+ return d->syncMode;
+}
+
+/*!
+ Set the timeline's synchronization mode to \a syncMode.
+ */
+void QmlTimeLine::setSyncMode(SyncMode syncMode)
+{
+ d->syncMode = syncMode;
+}
+
+/*!
+ Pause \a obj for \a time milliseconds.
+*/
+void QmlTimeLine::pause(QmlTimeLineObject &obj, int time)
+{
+ if (time <= 0) return;
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Pause, time, 0., 0., d->order++);
+ d->add(obj, op);
+}
+
+/*!
+ Execute the \a event.
+ */
+void QmlTimeLine::execute(const QmlTimeLineEvent &event)
+{
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Execute, 0, 0, 0., d->order++, event);
+ d->add(*event.eventObject(), op);
+}
+
+/*!
+ Set the \a value of \a timeLineValue.
+*/
+void QmlTimeLine::set(QmlTimeLineValue &timeLineValue, qreal value)
+{
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Set, 0, value, 0., d->order++);
+ d->add(timeLineValue, op);
+}
+
+/*!
+ Decelerate \a timeLineValue from the starting \a velocity to zero at the
+ given \a acceleration rate. Although the \a acceleration is technically
+ a deceleration, it should always be positive. The QmlTimeLine will ensure
+ that the deceleration is in the opposite direction to the initial velocity.
+*/
+int QmlTimeLine::accel(QmlTimeLineValue &timeLineValue, qreal velocity, qreal acceleration)
+{
+ if ((velocity > 0.0f) == (acceleration > 0.0f))
+ acceleration = acceleration * -1.0f;
+
+ int time = static_cast<int>(-1000 * velocity / acceleration);
+
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Accel, time, velocity, acceleration, d->order++);
+ d->add(timeLineValue, op);
+
+ return time;
+}
+
+/*!
+ \overload
+
+ Decelerate \a timeLineValue from the starting \a velocity to zero at the
+ given \a acceleration rate over a maximum distance of maxDistance.
+
+ If necessary, QmlTimeLine will reduce the acceleration to ensure that the
+ entire operation does not require a move of more than \a maxDistance.
+ \a maxDistance should always be positive.
+*/
+int QmlTimeLine::accel(QmlTimeLineValue &timeLineValue, qreal velocity, qreal acceleration, qreal maxDistance)
+{
+ Q_ASSERT(acceleration >= 0.0f && maxDistance >= 0.0f);
+
+ qreal maxAccel = (velocity * velocity) / (2.0f * maxDistance);
+ if (maxAccel > acceleration)
+ acceleration = maxAccel;
+
+ if ((velocity > 0.0f) == (acceleration > 0.0f))
+ acceleration = acceleration * -1.0f;
+
+ int time = static_cast<int>(-1000 * velocity / acceleration);
+
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Accel, time, velocity, acceleration, d->order++);
+ d->add(timeLineValue, op);
+
+ return time;
+}
+
+/*!
+ Decelerate \a timeLineValue from the starting \a velocity to zero over the given
+ \a distance. This is like accel(), but the QmlTimeLine calculates the exact
+ deceleration to use.
+
+ \a distance should be positive.
+*/
+int QmlTimeLine::accelDistance(QmlTimeLineValue &timeLineValue, qreal velocity, qreal distance)
+{
+ if (distance == 0.0f || velocity == 0.0f)
+ return -1;
+ Q_ASSERT((distance >= 0.0f) == (velocity >= 0.0f));
+
+ int time = static_cast<int>(1000 * (2.0f * distance) / velocity);
+
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::AccelDistance, time, velocity, distance, d->order++);
+ d->add(timeLineValue, op);
+
+ return time;
+}
+
+/*!
+ Linearly change the \a timeLineValue from its current value to the given
+ \a destination value over \a time milliseconds.
+*/
+void QmlTimeLine::move(QmlTimeLineValue &timeLineValue, qreal destination, int time)
+{
+ if (time <= 0) return;
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Move, time, destination, 0.0f, d->order++);
+ d->add(timeLineValue, op);
+}
+
+/*!
+ Change the \a timeLineValue from its current value to the given \a destination
+ value over \a time milliseconds using the \a easing curve.
+ */
+void QmlTimeLine::move(QmlTimeLineValue &timeLineValue, qreal destination, const QEasingCurve &easing, int time)
+{
+ if (time <= 0) return;
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::Move, time, destination, 0.0f, d->order++, QmlTimeLineEvent(), easing);
+ d->add(timeLineValue, op);
+}
+
+/*!
+ Linearly change the \a timeLineValue from its current value by the \a change amount
+ over \a time milliseconds.
+*/
+void QmlTimeLine::moveBy(QmlTimeLineValue &timeLineValue, qreal change, int time)
+{
+ if (time <= 0) return;
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::MoveBy, time, change, 0.0f, d->order++);
+ d->add(timeLineValue, op);
+}
+
+/*!
+ Change the \a timeLineValue from its current value by the \a change amount over
+ \a time milliseconds using the \a easing curve.
+ */
+void QmlTimeLine::moveBy(QmlTimeLineValue &timeLineValue, qreal change, const QEasingCurve &easing, int time)
+{
+ if (time <= 0) return;
+ QmlTimeLinePrivate::Op op(QmlTimeLinePrivate::Op::MoveBy, time, change, 0.0f, d->order++, QmlTimeLineEvent(), easing);
+ d->add(timeLineValue, op);
+}
+
+/*!
+ Cancel (but don't complete) all scheduled actions for \a timeLineValue.
+*/
+void QmlTimeLine::reset(QmlTimeLineValue &timeLineValue)
+{
+ if (!timeLineValue._t)
+ return;
+ if (timeLineValue._t != this) {
+ qWarning() << "QmlTimeLine: Cannot reset a QmlTimeLineValue owned by another timeline.";
+ return;
+ }
+ remove(&timeLineValue);
+ timeLineValue._t = 0;
+}
+
+int QmlTimeLine::duration() const
+{
+ return -1;
+}
+
+/*!
+ Synchronize the end point of \a timeLineValue to the endpoint of \a syncTo
+ within this timeline.
+
+ Following operations on \a timeLineValue in this timeline will be scheduled after
+ all the currently scheduled actions on \a syncTo are complete. In
+ psuedo-code this is equivalent to:
+ \code
+ QmlTimeLine::pause(timeLineValue, min(0, length_of(syncTo) - length_of(timeLineValue)))
+ \endcode
+*/
+void QmlTimeLine::sync(QmlTimeLineValue &timeLineValue, QmlTimeLineValue &syncTo)
+{
+ QmlTimeLinePrivate::Ops::Iterator iter = d->ops.find(&syncTo);
+ if (iter == d->ops.end())
+ return;
+ int length = iter->length;
+
+ iter = d->ops.find(&timeLineValue);
+ if (iter == d->ops.end()) {
+ pause(timeLineValue, length);
+ } else {
+ int glength = iter->length;
+ pause(timeLineValue, length - glength);
+ }
+}
+
+/*!
+ Synchronize the end point of \a timeLineValue to the endpoint of the longest
+ action cursrently scheduled in the timeline.
+
+ In psuedo-code, this is equivalent to:
+ \code
+ QmlTimeLine::pause(timeLineValue, length_of(timeline) - length_of(timeLineValue))
+ \endcode
+*/
+void QmlTimeLine::sync(QmlTimeLineValue &timeLineValue)
+{
+ QmlTimeLinePrivate::Ops::Iterator iter = d->ops.find(&timeLineValue);
+ if (iter == d->ops.end()) {
+ pause(timeLineValue, d->length);
+ } else {
+ pause(timeLineValue, d->length - iter->length);
+ }
+}
+
+/*
+ Synchronize all currently and future scheduled values in this timeline to
+ the longest action currently scheduled.
+
+ For example:
+ \code
+ value1->setValue(0.);
+ value2->setValue(0.);
+ value3->setValue(0.);
+ QmlTimeLine tl;
+ ...
+ tl.move(value1, 10, 200);
+ tl.move(value2, 10, 100);
+ tl.sync();
+ tl.move(value2, 20, 100);
+ tl.move(value3, 20, 100);
+ \endcode
+
+ will result in:
+
+ \table
+ \header \o \o 0ms \o 50ms \o 100ms \o 150ms \o 200ms \o 250ms \o 300ms
+ \row \o value1 \o 0 \o 2.5 \o 5.0 \o 7.5 \o 10 \o 10 \o 10
+ \row \o value2 \o 0 \o 5.0 \o 10.0 \o 10.0 \o 10.0 \o 15.0 \o 20.0
+ \row \o value2 \o 0 \o 0 \o 0 \o 0 \o 0 \o 10.0 \o 20.0
+ \endtable
+*/
+
+/*void QmlTimeLine::sync()
+{
+ for (QmlTimeLinePrivate::Ops::Iterator iter = d->ops.begin();
+ iter != d->ops.end();
+ ++iter)
+ pause(*iter.key(), d->length - iter->length);
+ d->syncPoint = d->length;
+}*/
+
+/*!
+ \internal
+
+ Temporary hack.
+ */
+void QmlTimeLine::setSyncPoint(int sp)
+{
+ d->syncPoint = sp;
+}
+
+/*!
+ \internal
+
+ Temporary hack.
+ */
+int QmlTimeLine::syncPoint() const
+{
+ return d->syncPoint;
+}
+
+/*!
+ Returns true if the timeline is active. An active timeline is one where
+ QmlTimeLineValue actions are still pending.
+*/
+bool QmlTimeLine::isActive() const
+{
+ return !d->ops.isEmpty();
+}
+
+/*!
+ Completes the timeline. All queued actions are played to completion, and then discarded. For example,
+ \code
+ QmlTimeLineValue v(0.);
+ QmlTimeLine tl;
+ tl.move(v, 100., 1000.);
+ // 500 ms passes
+ // v.value() == 50.
+ tl.complete();
+ // v.value() == 100.
+ \endcode
+*/
+void QmlTimeLine::complete()
+{
+ d->advance(d->length);
+}
+
+/*!
+ Resets the timeline. All queued actions are discarded and QmlTimeLineValue's retain their current value. For example,
+ \code
+ QmlTimeLineValue v(0.);
+ QmlTimeLine tl;
+ tl.move(v, 100., 1000.);
+ // 500 ms passes
+ // v.value() == 50.
+ tl.clear();
+ // v.value() == 50.
+ \endcode
+*/
+void QmlTimeLine::clear()
+{
+ for (QmlTimeLinePrivate::Ops::ConstIterator iter = d->ops.begin(); iter != d->ops.end(); ++iter)
+ iter.key()->_t = 0;
+ d->ops.clear();
+ d->length = 0;
+ d->syncPoint = 0;
+ //XXX need stop here?
+}
+
+int QmlTimeLine::time() const
+{
+ return d->prevTime;
+}
+
+/*!
+ \fn void QmlTimeLine::updated()
+
+ Emitted each time the timeline modifies QmlTimeLineValues. Even if multiple
+ QmlTimeLineValues are changed, this signal is only emitted once for each clock tick.
+*/
+
+void QmlTimeLine::updateCurrentTime(int v)
+{
+ if (d->syncAdj == -1)
+ d->syncAdj = v;
+ v -= d->syncAdj;
+
+ int timeChanged = v - d->prevTime;
+#if 0
+ if (!timeChanged)
+ return;
+#endif
+ d->prevTime = v;
+ d->advance(timeChanged);
+ emit updated();
+
+ // Do we need to stop the clock?
+ if (d->ops.isEmpty()) {
+ stop();
+ d->prevTime = 0;
+ d->clockRunning = false;
+ emit completed();
+ } /*else if (pauseTime > 0) {
+ GfxClock::cancelClock();
+ d->prevTime = 0;
+ GfxClock::pauseFor(pauseTime);
+ d->syncAdj = 0;
+ d->clockRunning = false;
+ }*/ else if (/*!GfxClock::isActive()*/ state() != Running) {
+ stop();
+ d->prevTime = 0;
+ d->clockRunning = true;
+ d->syncAdj = 0;
+ start();
+ }
+}
+
+bool operator<(const QPair<int, Update> &lhs,
+ const QPair<int, Update> &rhs)
+{
+ return lhs.first < rhs.first;
+}
+
+int QmlTimeLinePrivate::advance(int t)
+{
+ int pauseTime = -1;
+
+ // XXX - surely there is a more efficient way?
+ do {
+ pauseTime = -1;
+ // Minimal advance time
+ int advanceTime = t;
+ for (Ops::Iterator iter = ops.begin(); iter != ops.end(); ++iter) {
+ TimeLine &tl = *iter;
+ Op &op = tl.ops.first();
+ int length = op.length - tl.consumedOpLength;
+
+ if (length < advanceTime) {
+ advanceTime = length;
+ if (advanceTime == 0)
+ break;
+ }
+ }
+ t -= advanceTime;
+
+ // Process until then. A zero length advance time will only process
+ // sets.
+ QList<QPair<int, Update> > updates;
+
+ for (Ops::Iterator iter = ops.begin(); iter != ops.end(); ) {
+ QmlTimeLineValue *v = static_cast<QmlTimeLineValue *>(iter.key());
+ TimeLine &tl = *iter;
+ Q_ASSERT(!tl.ops.isEmpty());
+
+ do {
+ Op &op = tl.ops.first();
+ if (advanceTime == 0 && op.length != 0)
+ continue;
+
+ if (tl.consumedOpLength == 0 &&
+ op.type != Op::Pause &&
+ op.type != Op::Execute)
+ tl.base = v->value();
+
+ if ((tl.consumedOpLength + advanceTime) == op.length) {
+ if (op.type == Op::Execute) {
+ updates << qMakePair(op.order, Update(op.event));
+ } else {
+ bool changed = false;
+ qreal val = value(op, op.length, tl.base, &changed);
+ if (changed)
+ updates << qMakePair(op.order, Update(v, val));
+ }
+ tl.length -= qMin(advanceTime, tl.length);
+ tl.consumedOpLength = 0;
+ tl.ops.removeFirst();
+ } else {
+ tl.consumedOpLength += advanceTime;
+ bool changed = false;
+ qreal val = value(op, tl.consumedOpLength, tl.base, &changed);
+ if (changed)
+ updates << qMakePair(op.order, Update(v, val));
+ tl.length -= qMin(advanceTime, tl.length);
+ break;
+ }
+
+ } while(!tl.ops.isEmpty() && advanceTime == 0 && tl.ops.first().length == 0);
+
+
+ if (tl.ops.isEmpty()) {
+ iter = ops.erase(iter);
+ v->_t = 0;
+ } else {
+ if (tl.ops.first().type == Op::Pause && pauseTime != 0) {
+ int opPauseTime = tl.ops.first().length - tl.consumedOpLength;
+ if (pauseTime == -1 || opPauseTime < pauseTime)
+ pauseTime = opPauseTime;
+ } else {
+ pauseTime = 0;
+ }
+ ++iter;
+ }
+ }
+
+ length -= qMin(length, advanceTime);
+ syncPoint -= advanceTime;
+
+ qSort(updates.begin(), updates.end());
+ updateQueue = &updates;
+ for (int ii = 0; ii < updates.count(); ++ii) {
+ const Update &v = updates.at(ii).second;
+ if (v.g)
+ v.g->setValue(v.v);
+ else
+ v.e.execute();
+ }
+ updateQueue = 0;
+ } while(t);
+
+ return pauseTime;
+}
+
+void QmlTimeLine::remove(QmlTimeLineObject *v)
+{
+ QmlTimeLinePrivate::Ops::Iterator iter = d->ops.find(v);
+ Q_ASSERT(iter != d->ops.end());
+
+ int len = iter->length;
+ d->ops.erase(iter);
+ if (len == d->length) {
+ // We need to recalculate the length
+ d->length = 0;
+ for (QmlTimeLinePrivate::Ops::Iterator iter = d->ops.begin();
+ iter != d->ops.end();
+ ++iter) {
+
+ if (iter->length > d->length)
+ d->length = iter->length;
+
+ }
+ }
+ if (d->ops.isEmpty()) {
+ stop();
+ d->clockRunning = false;
+ } else if (/*!GfxClock::isActive()*/ state() != Running) {
+ stop();
+ d->prevTime = 0;
+ d->clockRunning = true;
+
+ if (d->syncMode == QmlTimeLine::LocalSync) {
+ d->syncAdj = -1;
+ } else {
+ d->syncAdj = 0;
+ }
+ start();
+ }
+
+ if (d->updateQueue) {
+ for (int ii = 0; ii < d->updateQueue->count(); ++ii) {
+ if (d->updateQueue->at(ii).second.g == v ||
+ d->updateQueue->at(ii).second.e.eventObject() == v) {
+ d->updateQueue->removeAt(ii);
+ --ii;
+ }
+ }
+ }
+
+
+}
+
+/*!
+ \internal
+ \class QmlTimeLineValue
+ \ingroup group_animation
+ \brief The QmlTimeLineValue class provides a value that can be modified by QmlTimeLine.
+*/
+
+/*!
+ \fn QmlTimeLineValue::QmlTimeLineValue(qreal value = 0)
+
+ Construct a new QmlTimeLineValue with an initial \a value.
+*/
+
+/*!
+ \fn qreal QmlTimeLineValue::value() const
+
+ Return the current value.
+*/
+
+/*!
+ \fn void QmlTimeLineValue::setValue(qreal value)
+
+ Set the current \a value.
+*/
+
+/*!
+ \fn QmlTimeLine *QmlTimeLineValue::timeLine() const
+
+ If a QmlTimeLine is operating on this value, return a pointer to it,
+ otherwise return null.
+*/
+
+
+QmlTimeLineObject::QmlTimeLineObject()
+: _t(0)
+{
+}
+
+QmlTimeLineObject::~QmlTimeLineObject()
+{
+ if (_t) {
+ _t->remove(this);
+ _t = 0;
+ }
+}
+
+QmlTimeLineEvent::QmlTimeLineEvent()
+: d0(0), d1(0), d2(0)
+{
+}
+
+QmlTimeLineEvent::QmlTimeLineEvent(const QmlTimeLineEvent &o)
+: d0(o.d0), d1(o.d1), d2(o.d2)
+{
+}
+
+QmlTimeLineEvent &QmlTimeLineEvent::operator=(const QmlTimeLineEvent &o)
+{
+ d0 = o.d0;
+ d1 = o.d1;
+ d2 = o.d2;
+ return *this;
+}
+
+void QmlTimeLineEvent::execute() const
+{
+ d0(d1);
+}
+
+QmlTimeLineObject *QmlTimeLineEvent::eventObject() const
+{
+ return d2;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmltimeline_p.h b/src/declarative/util/qmltimeline_p.h
new file mode 100644
index 0000000..abed80a
--- /dev/null
+++ b/src/declarative/util/qmltimeline_p.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLTIMELINE_H
+#define QMLTIMELINE_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 <QtCore/QObject>
+#include <QtCore/QAbstractAnimation>
+#include <QtDeclarative/qfxglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEasingCurve;
+class QmlTimeLineValue;
+class QmlTimeLineEvent;
+struct QmlTimeLinePrivate;
+class QmlTimeLineObject;
+class Q_DECLARATIVE_EXPORT QmlTimeLine : public QAbstractAnimation
+{
+Q_OBJECT
+public:
+ QmlTimeLine(QObject *parent = 0);
+ ~QmlTimeLine();
+
+ enum SyncMode { LocalSync, GlobalSync };
+ SyncMode syncMode() const;
+ void setSyncMode(SyncMode);
+
+ void pause(QmlTimeLineObject &, int);
+ void execute(const QmlTimeLineEvent &);
+ void set(QmlTimeLineValue &, qreal);
+
+ int accel(QmlTimeLineValue &, qreal velocity, qreal accel);
+ int accel(QmlTimeLineValue &, qreal velocity, qreal accel, qreal maxDistance);
+ int accelDistance(QmlTimeLineValue &, qreal velocity, qreal distance);
+
+ void move(QmlTimeLineValue &, qreal destination, int time = 500);
+ void move(QmlTimeLineValue &, qreal destination, const QEasingCurve &, int time = 500);
+ void moveBy(QmlTimeLineValue &, qreal change, int time = 500);
+ void moveBy(QmlTimeLineValue &, qreal change, const QEasingCurve &, int time = 500);
+
+ void sync();
+ void setSyncPoint(int);
+ int syncPoint() const;
+
+ void sync(QmlTimeLineValue &);
+ void sync(QmlTimeLineValue &, QmlTimeLineValue &);
+
+ void reset(QmlTimeLineValue &);
+
+ void complete();
+ void clear();
+ bool isActive() const;
+
+ int time() const;
+
+ virtual int duration() const;
+Q_SIGNALS:
+ void updated();
+ void completed();
+
+protected:
+ virtual void updateCurrentTime(int);
+
+private:
+ void remove(QmlTimeLineObject *);
+ friend class QmlTimeLineObject;
+ friend struct QmlTimeLinePrivate;
+ QmlTimeLinePrivate *d;
+};
+
+class Q_DECLARATIVE_EXPORT QmlTimeLineObject
+{
+public:
+ QmlTimeLineObject();
+ virtual ~QmlTimeLineObject();
+
+protected:
+ friend class QmlTimeLine;
+ friend struct QmlTimeLinePrivate;
+ QmlTimeLine *_t;
+};
+
+class Q_DECLARATIVE_EXPORT QmlTimeLineValue : public QmlTimeLineObject
+{
+public:
+ QmlTimeLineValue(qreal v = 0.) : _v(v) {}
+
+ virtual qreal value() const { return _v; }
+ virtual void setValue(qreal v) { _v = v; }
+
+ QmlTimeLine *timeLine() const { return _t; }
+
+ operator qreal() const { return _v; }
+ QmlTimeLineValue &operator=(qreal v) { setValue(v); return *this; }
+private:
+ friend class QmlTimeLine;
+ friend struct QmlTimeLinePrivate;
+ qreal _v;
+};
+
+class Q_DECLARATIVE_EXPORT QmlTimeLineEvent
+{
+public:
+ QmlTimeLineEvent();
+ QmlTimeLineEvent(const QmlTimeLineEvent &o);
+
+ template<class T, void (T::*method)()>
+ QmlTimeLineEvent(QmlTimeLineObject *b, T *c)
+ {
+ d0 = &callFunc<T, method>;
+ d1 = (void *)c;
+ d2 = b;
+ }
+
+ template<class T, void (T::*method)()>
+ static QmlTimeLineEvent timeLineEvent(QmlTimeLineObject *b, T *c)
+ {
+ QmlTimeLineEvent rv;
+ rv.d0 = &callFunc<T, method>;
+ rv.d1 = (void *)c;
+ rv.d2 = b;
+ return rv;
+ }
+
+ QmlTimeLineEvent &operator=(const QmlTimeLineEvent &o);
+ void execute() const;
+ QmlTimeLineObject *eventObject() const;
+
+private:
+ typedef void (*CallFunc)(void *c);
+
+ template <class T, void (T::*method)()>
+ static void callFunc(void *c)
+ {
+ T *cls = (T *)c;
+ (cls->*method)();
+ }
+ CallFunc d0;
+ void *d1;
+ QmlTimeLineObject *d2;
+};
+
+template<class T>
+class QmlTimeLineValueProxy : public QmlTimeLineValue
+{
+public:
+ QmlTimeLineValueProxy(T *cls, void (T::*func)(qreal), qreal v = 0.)
+ : QmlTimeLineValue(v), _class(cls), _setFunctionReal(func), _setFunctionInt(0)
+ {
+ Q_ASSERT(_class);
+ }
+
+ QmlTimeLineValueProxy(T *cls, void (T::*func)(int), qreal v = 0.)
+ : QmlTimeLineValue(v), _class(cls), _setFunctionReal(0), _setFunctionInt(func)
+ {
+ Q_ASSERT(_class);
+ }
+
+ virtual void setValue(qreal v)
+ {
+ QmlTimeLineValue::setValue(v);
+ if (_setFunctionReal) (_class->*_setFunctionReal)(v);
+ else if (_setFunctionInt) (_class->*_setFunctionInt)((int)v);
+ }
+
+private:
+ T *_class;
+ void (T::*_setFunctionReal)(qreal);
+ void (T::*_setFunctionInt)(int);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/util/qperformancelog.cpp b/src/declarative/util/qperformancelog.cpp
index 932e4b3..8e11997 100644
--- a/src/declarative/util/qperformancelog.cpp
+++ b/src/declarative/util/qperformancelog.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qperformancelog.h"
+#include "qperformancelog_p.h"
#include <QHash>
#include <QDebug>
diff --git a/src/declarative/util/qperformancelog.h b/src/declarative/util/qperformancelog_p.h
index 6655a8d..6655a8d 100644
--- a/src/declarative/util/qperformancelog.h
+++ b/src/declarative/util/qperformancelog_p.h
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index 0619a47..aae10af 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -17,13 +17,14 @@ SOURCES += \
util/qmllistmodel.cpp\
util/qmllistaccessor.cpp \
util/qmlopenmetaobject.cpp \
+ util/qmltimeline.cpp \
util/qmlbind.cpp
HEADERS += \
util/qfxview.h \
- util/qfxperf.h \
+ util/qfxperf_p.h \
util/qfxglobal.h \
- util/qperformancelog.h \
+ util/qperformancelog_p.h \
util/qmlconnection.h \
util/qmlpackage.h \
util/qmlscript.h \
@@ -42,4 +43,5 @@ HEADERS += \
util/qmllistaccessor.h \
util/qmlopenmetaobject.h \
util/qmlnullablevalue_p.h \
+ util/qmltimeline_p.h \
util/qmlbind.h