From 56aa9370dbafa8ee431dd2ffabef309aae01ec2f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Mar 2010 11:11:01 +1000 Subject: Don't emit onPositionChanged before onPressed Task-number: QTBUG-9383 --- src/declarative/graphicsitems/qdeclarativemousearea.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 26242bc..dde3366 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -639,7 +639,6 @@ bool QDeclarativeMouseArea::setPressed(bool p) d->pressed = p; QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress); if (d->pressed) { - emit positionChanged(&me); emit pressed(&me); } else { emit released(&me); -- cgit v0.12 From 8368e041e35ab2a79c79f651a56e6ee53a46549f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Mar 2010 12:20:58 +1000 Subject: Fix viewer resizing on reload and File->open Task-number: QTBUG-9325 --- src/declarative/util/qdeclarativeview.cpp | 1 + tools/qml/qmlruntime.cpp | 33 +++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 138fe3c..22a7873 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -157,6 +157,7 @@ void QDeclarativeViewPrivate::execute() { delete root; delete component; + initialSize = QSize(); component = new QDeclarativeComponent(&engine, source, q); if (!component->isLoading()) { diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index d4ceb0b..44cab97 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -995,8 +995,22 @@ void QDeclarativeViewer::statusChanged() if (canvas->status() == QDeclarativeView::Error && tester) tester->executefailure(); - if (canvas->status() == QDeclarativeView::Ready) - resize(sizeHint()); + if (canvas->status() == QDeclarativeView::Ready) { + if (!skin) { + canvas->updateGeometry(); + if (mb) + mb->updateGeometry(); + if (!isFullScreen() && !isMaximized()) + resize(sizeHint()); + } else { + if (scaleSkin) + canvas->resize(canvas->sizeHint()); + else { + canvas->setFixedSize(skin->standardScreenSize()); + canvas->resize(skin->standardScreenSize()); + } + } + } } void QDeclarativeViewer::launch(const QString& file_or_url) @@ -1077,21 +1091,6 @@ void QDeclarativeViewer::openQml(const QString& file_or_url) qWarning() << "Wall startup time:" << t.elapsed(); - if (!skin) { - canvas->updateGeometry(); - if (mb) - mb->updateGeometry(); - if (!isFullScreen() && !isMaximized()) - resize(sizeHint()); - } else { - if (scaleSkin) - canvas->resize(canvas->sizeHint()); - else { - canvas->setFixedSize(skin->standardScreenSize()); - canvas->resize(skin->standardScreenSize()); - } - } - #ifdef QTOPIA show(); #endif -- cgit v0.12 From 68d3e2da7719ff0fc230e8204946b27018e42c14 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 30 Mar 2010 13:28:43 +1000 Subject: Fix parenting after 6f88388db4e8e202780d789e66664ff824691948. --- .../graphicsitems/qdeclarativeflickable.cpp | 3 ++- .../graphicsitems/qdeclarativegridview.cpp | 11 ++++++----- src/declarative/graphicsitems/qdeclarativeitem.cpp | 10 +--------- src/declarative/graphicsitems/qdeclarativeitem.h | 1 - src/declarative/graphicsitems/qdeclarativeitem_p.h | 6 ++++-- .../graphicsitems/qdeclarativelistview.cpp | 22 +++++++++++++--------- .../graphicsitems/qdeclarativeloader.cpp | 8 ++------ .../graphicsitems/qdeclarativepathview.cpp | 5 +++-- 8 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 98502fd..fb22429 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -137,7 +137,8 @@ QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() void QDeclarativeFlickablePrivate::init() { Q_Q(QDeclarativeFlickable); - viewport->setParent(q); + QDeclarative_setParent_noEvent(viewport, q); + viewport->setParentItem(q); static int timelineUpdatedIdx = -1; static int timelineCompletedIdx = -1; static int flickableTickedIdx = -1; diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 17f74db..250832b 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -372,7 +372,7 @@ FxGridItem *QDeclarativeGridViewPrivate::createItem(int modelIndex) listItem->item->setZValue(1); // complete model->completeItem(); - listItem->item->setParent(q->viewport()); + listItem->item->setParentItem(q->viewport()); unrequestedItems.remove(listItem->item); } requestedIndex = -1; @@ -644,7 +644,7 @@ void QDeclarativeGridViewPrivate::createHighlight() QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q)); QObject *nobj = highlightComponent->create(highlightContext); if (nobj) { - highlightContext->setParent(nobj); + QDeclarative_setParent_noEvent(highlightContext, nobj); item = qobject_cast(nobj); if (!item) delete nobj; @@ -653,10 +653,12 @@ void QDeclarativeGridViewPrivate::createHighlight() } } else { item = new QDeclarativeItem; - item->setParent(q->viewport()); + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); } if (item) { - item->setParent(q->viewport()); + 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"))); @@ -2180,7 +2182,6 @@ void QDeclarativeGridView::modelReset() void QDeclarativeGridView::createdItem(int index, QDeclarativeItem *item) { Q_D(QDeclarativeGridView); - item->setParentItem(this); if (d->requestedIndex != index) { item->setParentItem(this); d->unrequestedItems.insert(item, index); diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index e8f3652..29490e3 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -1442,14 +1442,6 @@ void QDeclarativeItem::setParentItem(QDeclarativeItem *parent) } /*! - \fn void QDeclarativeItem::setParent(QDeclarativeItem *parent) - \overload - Sets both the parent object and parent item to \a parent. This - function avoids the programming error of calling setParent() - when you mean setParentItem(). -*/ - -/*! Returns the QDeclarativeItem parent of this item. */ QDeclarativeItem *QDeclarativeItem::parentItem() const @@ -1651,7 +1643,7 @@ QRectF QDeclarativeItem::childrenRect() Q_D(QDeclarativeItem); if (!d->_contents) { d->_contents = new QDeclarativeContents; - d->_contents->setParent(this); + QDeclarative_setParent_noEvent(d->_contents, this); d->_contents->setItem(this); } return d->_contents->rectF(); diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 712e854..917e480 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -107,7 +107,6 @@ public: QDeclarativeItem *parentItem() const; void setParentItem(QDeclarativeItem *parent); - void setParent(QDeclarativeItem *parent) { setParentItem(parent); } QDeclarativeListProperty data(); QDeclarativeListProperty resources(); diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index 10c0c25..2607137 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -129,9 +130,10 @@ public: void init(QDeclarativeItem *parent) { Q_Q(QDeclarativeItem); - - if (parent) + if (parent) { + QDeclarative_setParent_noEvent(q, parent); q->setParentItem(parent); + } _baselineOffset.invalidate(); mouseSetsFocus = false; } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 85fcc27..ef8d2fd 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -541,7 +541,7 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) listItem->item->setZValue(1); // complete model->completeItem(); - listItem->item->setParent(q->viewport()); + listItem->item->setParentItem(q->viewport()); QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); if (sectionCriteria && sectionCriteria->delegate()) { @@ -803,7 +803,7 @@ void QDeclarativeListViewPrivate::createHighlight() QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q)); QObject *nobj = highlightComponent->create(highlightContext); if (nobj) { - highlightContext->setParent(nobj); + QDeclarative_setParent_noEvent(highlightContext, nobj); item = qobject_cast(nobj); if (!item) delete nobj; @@ -814,7 +814,8 @@ void QDeclarativeListViewPrivate::createHighlight() item = new QDeclarativeItem; } if (item) { - item->setParent(q->viewport()); + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); highlight = new FxListItem(item, q); if (currentItem && autoHighlight) { if (orient == QDeclarativeListView::Vertical) { @@ -880,13 +881,14 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem) context->setContextProperty(QLatin1String("section"), listItem->attached->m_section); QObject *nobj = sectionCriteria->delegate()->create(context); if (nobj) { - context->setParent(nobj); + QDeclarative_setParent_noEvent(context, nobj); listItem->section = qobject_cast(nobj); if (!listItem->section) { delete nobj; } else { listItem->section->setZValue(1); - listItem->section->setParent(q->viewport()); + QDeclarative_setParent_noEvent(listItem->section, q->viewport()); + listItem->section->setParentItem(q->viewport()); } } else { delete context; @@ -1002,7 +1004,7 @@ void QDeclarativeListViewPrivate::updateFooter() QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); QObject *nobj = footerComponent->create(context); if (nobj) { - context->setParent(nobj); + QDeclarative_setParent_noEvent(context, nobj); item = qobject_cast(nobj); if (!item) delete nobj; @@ -1010,7 +1012,8 @@ void QDeclarativeListViewPrivate::updateFooter() delete context; } if (item) { - item->setParent(q->viewport()); + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); item->setZValue(1); footer = new FxListItem(item, q); } @@ -1039,7 +1042,7 @@ void QDeclarativeListViewPrivate::updateHeader() QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); QObject *nobj = headerComponent->create(context); if (nobj) { - context->setParent(nobj); + QDeclarative_setParent_noEvent(context, nobj); item = qobject_cast(nobj); if (!item) delete nobj; @@ -1047,7 +1050,8 @@ void QDeclarativeListViewPrivate::updateHeader() delete context; } if (item) { - item->setParent(q->viewport()); + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); item->setZValue(1); header = new FxListItem(item, q); if (visibleItems.isEmpty()) diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 0d62afa..2f1511e 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -301,12 +301,8 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() item = qobject_cast(obj); if (item) { QDeclarative_setParent_noEvent(ctxt, obj); - if (QDeclarativeItem* qmlItem = qobject_cast(item)) { - qmlItem->setParentItem(q); - } else { - item->setParentItem(q); - item->setParent(q); - } + QDeclarative_setParent_noEvent(item, q); + item->setParentItem(q); // item->setFocus(true); initResize(); } else { diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index dd1edd6..3574c9f 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -188,7 +188,7 @@ void QDeclarativePathViewPrivate::createHighlight() QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q)); QObject *nobj = highlightComponent->create(highlightContext); if (nobj) { - highlightContext->setParent(nobj); + QDeclarative_setParent_noEvent(highlightContext, nobj); item = qobject_cast(nobj); if (!item) delete nobj; @@ -199,7 +199,8 @@ void QDeclarativePathViewPrivate::createHighlight() item = new QDeclarativeItem; } if (item) { - item->setParent(q); + QDeclarative_setParent_noEvent(item, q); + item->setParentItem(q); highlightItem = item; changed = true; } -- cgit v0.12 From 7a060ca401b4e260fd08c854213024b050a67ff2 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Fri, 12 Feb 2010 17:19:51 +1000 Subject: Change and rename qml EaseFollow to SmoothedAnimation QDeclarativeSmoothedAnimation inherits from QDeclarativeNumberAnimation, as a consequence SmoothedAnimation can be used inside Behaviors and as PropertySourceValues, like any other animation. The old EaseFollow properties changed to comply with the other declarative animations ('source' changed to 'to'), so now 'to' changes are not automatically 'followed' anymore. You can achieve the following behavior by putting a SmoothedAnimation inside a Behavior of a property that is bound to another, as the following example: If you want to follow an hypothetical rect1, you should do now: Rectangle { color: "green" width: 60; height: 60; x: rect1.x - 5; y: rect1.y - 5; Behavior on x { SmoothedAnimation { velocity: 200 } } Behavior on y { SmoothedAnimation { velocity: 200 } } } SmoothedAnimation also supports animating multiple target(s)/property(ies) in the transition case. When a QDeclarativeSmoothedAnimation is restarted, it will match the QDeclarativeProperty which were being animated and transfer the corresponding track velocity to the new starting animations. QSmoothedAnimation is an uncontrolled animation, duration == -1. The duration is set as -1 to avoid consecutive animation state changes stop()/start(). This is particularly useful when using QSmoothAnimation to 'follow' another property, which is also being animated (change the 'to' property every tick). Reviewed-by: Michael Brasser --- doc/src/declarative/elements.qdoc | 2 +- .../progressbar/content/ProgressBar.qml | 3 +- .../graphicsitems/qdeclarativegridview.cpp | 36 +- .../graphicsitems/qdeclarativelistview.cpp | 36 +- src/declarative/qml/qdeclarativeproperty.h | 5 + src/declarative/util/qdeclarativeanimation.cpp | 19 +- src/declarative/util/qdeclarativeanimation_p.h | 10 +- src/declarative/util/qdeclarativeanimation_p_p.h | 5 +- src/declarative/util/qdeclarativebehavior.cpp | 3 +- src/declarative/util/qdeclarativeeasefollow.cpp | 499 +++++++++------------ src/declarative/util/qdeclarativeeasefollow_p.h | 42 +- src/declarative/util/qdeclarativeeasefollow_p_p.h | 133 ++++++ src/declarative/util/qdeclarativespringfollow.cpp | 2 - src/declarative/util/qdeclarativetransition.cpp | 6 +- src/declarative/util/qdeclarativeutilmodule.cpp | 2 +- src/declarative/util/util.pri | 1 + .../qdeclarativeeasefollow/data/easefollow1.qml | 2 +- .../qdeclarativeeasefollow/data/easefollow2.qml | 4 +- .../qdeclarativeeasefollow/data/easefollow3.qml | 4 +- .../data/easefollowBehavior.qml | 23 + .../data/easefollowValueSource.qml | 13 + .../tst_qdeclarativeeasefollow.cpp | 119 ++++- .../qdeclarativelistview/data/listviewtest.qml | 2 +- .../qdeclarativeeasefollow/easefollow.qml | 15 +- .../qmlvisual/qdeclarativegridview/gridview2.qml | 9 +- 25 files changed, 609 insertions(+), 386 deletions(-) create mode 100644 src/declarative/util/qdeclarativeeasefollow_p_p.h create mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollowBehavior.qml create mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollowValueSource.qml 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 +#include "qdeclarativeeasefollow_p_p.h" #include #include @@ -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 +#include "qdeclarativeeasefollow_p_p.h" #include #include #include @@ -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 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 +#include "qdeclarativeproperty_p.h" + +#include "qdeclarativeglobal_p.h" #include #include +#include + +#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 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 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(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 -#include +#include "qdeclarativeanimation_p.h" #include @@ -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 + +#include + +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 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(QDeclarativeListPropertycomplete(); } 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("Qt",4,6,"Binding"); qmlRegisterType("Qt",4,6,"ColorAnimation"); qmlRegisterType("Qt",4,6,"Connections"); - qmlRegisterType("Qt",4,6,"EaseFollow"); + qmlRegisterType("Qt",4,6,"SmoothedAnimation"); qmlRegisterType("Qt",4,6,"FontLoader"); qmlRegisterType("Qt",4,6,"ListElement"); qmlRegisterType("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 #include #include +#include #include #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(c.create()); + QDeclarativeSmoothedAnimation *obj = qobject_cast(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(c.create()); + QDeclarativeSmoothedAnimation *obj = qobject_cast(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(c.create()); + QDeclarativeSmoothedAnimation *obj = qobject_cast(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(c.create()); + QVERIFY(rect); + + QDeclarativeRectangle *theRect = rect->findChild("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); + QVERIFY(easeX); + QVERIFY(easeX->isRunning()); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild("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(c.create()); + QVERIFY(rect); + + QDeclarativeRectangle *theRect = rect->findChild("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); + QVERIFY(easeX); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild("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 } } } ] } -- cgit v0.12 From e2f9d31227e9a2126a99503c4285efaf8d894dd9 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Mon, 29 Mar 2010 13:58:00 +1000 Subject: Finished file rename of qdeclarative easefollow to smoothedanimation --- .../graphicsitems/qdeclarativegridview.cpp | 2 +- .../graphicsitems/qdeclarativelistview.cpp | 2 +- .../graphicsitems/qdeclarativepathview.cpp | 1 - src/declarative/util/qdeclarativeeasefollow.cpp | 484 ------ src/declarative/util/qdeclarativeeasefollow_p.h | 104 -- src/declarative/util/qdeclarativeeasefollow_p_p.h | 133 -- .../util/qdeclarativesmoothedanimation.cpp | 483 ++++++ .../util/qdeclarativesmoothedanimation_p.h | 104 ++ .../util/qdeclarativesmoothedanimation_p_p.h | 134 ++ src/declarative/util/qdeclarativeutilmodule.cpp | 2 +- src/declarative/util/util.pri | 6 +- tests/auto/declarative/declarative.pro | 2 +- .../qdeclarativeeasefollow/data/easefollow1.qml | 3 - .../qdeclarativeeasefollow/data/easefollow2.qml | 5 - .../qdeclarativeeasefollow/data/easefollow3.qml | 6 - .../data/easefollowBehavior.qml | 23 - .../data/easefollowValueSource.qml | 13 - .../qdeclarativeeasefollow.pro | 8 - .../tst_qdeclarativeeasefollow.cpp | 207 --- .../data/smoothedanimation1.qml | 3 + .../data/smoothedanimation2.qml | 5 + .../data/smoothedanimation3.qml | 6 + .../data/smoothedanimationBehavior.qml | 23 + .../data/smoothedanimationValueSource.qml | 13 + .../qdeclarativesmoothedanimation.pro | 8 + .../tst_qdeclarativesmoothedanimation.cpp | 207 +++ .../qdeclarativeeasefollow/data/easefollow.0.png | Bin 1305 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.1.png | Bin 1306 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.2.png | Bin 1305 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.3.png | Bin 1303 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.4.png | Bin 1303 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.5.png | Bin 1305 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.6.png | Bin 1306 -> 0 bytes .../qdeclarativeeasefollow/data/easefollow.qml | 1807 -------------------- .../qdeclarativeeasefollow/easefollow.qml | 45 - .../data/easefollow.0.png | Bin 0 -> 1305 bytes .../data/easefollow.1.png | Bin 0 -> 1306 bytes .../data/easefollow.2.png | Bin 0 -> 1305 bytes .../data/easefollow.3.png | Bin 0 -> 1303 bytes .../data/easefollow.4.png | Bin 0 -> 1303 bytes .../data/easefollow.5.png | Bin 0 -> 1305 bytes .../data/easefollow.6.png | Bin 0 -> 1306 bytes .../data/easefollow.qml | 1807 ++++++++++++++++++++ .../smoothedanimation.qml | 45 + 44 files changed, 2845 insertions(+), 2846 deletions(-) delete mode 100644 src/declarative/util/qdeclarativeeasefollow.cpp delete mode 100644 src/declarative/util/qdeclarativeeasefollow_p.h delete mode 100644 src/declarative/util/qdeclarativeeasefollow_p_p.h create mode 100644 src/declarative/util/qdeclarativesmoothedanimation.cpp create mode 100644 src/declarative/util/qdeclarativesmoothedanimation_p.h create mode 100644 src/declarative/util/qdeclarativesmoothedanimation_p_p.h delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollow3.qml delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollowBehavior.qml delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/data/easefollowValueSource.qml delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/qdeclarativeeasefollow.pro delete mode 100644 tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro create mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.0.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.1.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.2.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.3.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.4.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.5.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.6.png delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.qml delete mode 100644 tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.0.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.1.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.2.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.3.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.4.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.5.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.6.png create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.qml create mode 100644 tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedanimation.qml diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 6d1dec6..12ede34 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_p.h" +#include "qdeclarativesmoothedanimation_p_p.h" #include #include diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 6a4f4b9..cbf8eac 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_p.h" +#include "qdeclarativesmoothedanimation_p_p.h" #include #include #include diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 3574c9f..c2cfbb1 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -44,7 +44,6 @@ #include #include -#include #include #include #include diff --git a/src/declarative/util/qdeclarativeeasefollow.cpp b/src/declarative/util/qdeclarativeeasefollow.cpp deleted file mode 100644 index ce2c496..0000000 --- a/src/declarative/util/qdeclarativeeasefollow.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/**************************************************************************** -** -** 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 "qdeclarativeeasefollow_p.h" -#include "qdeclarativeeasefollow_p_p.h" - -#include "qdeclarativeanimation_p_p.h" - -#include -#include "qdeclarativeproperty_p.h" - -#include "qdeclarativeglobal_p.h" - -#include - -#include -#include - -#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(); -} - -void QSmoothedAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/) -{ - if (newState == QAbstractAnimation::Running) - init(); -} - -void QSmoothedAnimation::delayedStop() -{ - 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; - - if (userDuration > 0 && velocity > 0) { - tf = s / velocity; - 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; - tp = 0; - td = tf; - vp = velocity; - sp = 0; - sd = s; - } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / 1000.)) { - qreal met = maximumEasingTime / 1000.; - td = tf - met; - - qreal c1 = td; - qreal c2 = (tf - td) * vi - tf * velocity; - qreal c3 = -0.5 * (tf - td) * vi * vi; - - qreal vp1 = (-c2 + sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); - - vp = vp1; - a = vp / met; - d = a; - tp = (vp - vi) / a; - 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 tp1 = 0.5 * tf - 0.5 * vi / a1; - qreal vp1 = a1 * tp1 + vi; - - qreal sp1 = 0.5 * a1 * tp1 * tp1 + vi * tp1; - - a = a1; - d = a1; - tp = tp1; - td = tp1; - vp = vp1; - sp = sp1; - sd = sp1; - } - return true; -} - -qreal QSmoothedAnimation::easeFollow(qreal time_seconds) -{ - 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 { - trackVelocity = 0; - value = s; - delayedStop(); - } - - // to normalize 's' between [0..1], divide 'value' by 's' - return value; -} - -void QSmoothedAnimation::updateCurrentTime(int t) -{ - qreal time_seconds = qreal(t - lastTime) / 1000.; - - qreal value = easeFollow(time_seconds); - value *= (invert? -1.0: 1.0); - QDeclarativePropertyPrivate::write(target, initialValue + value, - QDeclarativePropertyPrivate::BypassInterceptor - | QDeclarativePropertyPrivate::DontRemoveBinding); -} - -void QSmoothedAnimation::init() -{ - if (velocity == 0) { - stop(); - return; - } - - if (delayedStopTimer.isActive()) - delayedStopTimer.stop(); - - initialValue = target.read().toReal(); - lastTime = this->currentTime(); - - if (to == initialValue) { - stop(); - return; - } - - bool hasReversed = trackVelocity != 0. && - ((trackVelocity > 0) == ((initialValue - to) > 0)); - - 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; - } - } - - trackVelocity = initialVelocity; - - invert = (to < initialValue); - - if (!recalc()) { - QDeclarativePropertyPrivate::write(target, to, - QDeclarativePropertyPrivate::BypassInterceptor - | QDeclarativePropertyPrivate::DontRemoveBinding); - stop(); - return; - } -} - -/*! - \qmlclass SmoothedAnimation QDeclarativeSmoothedAnimation - \since 4.7 - \brief The SmoothedAnimation element allows a property to smoothly track a value. - - 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. - - The property animation is configured by setting the velocity at which the - animation should occur, or the duration that the animation should take. - If both a velocity and a duration are specified, the one that results in - the quickest animation is chosen for each change in the target value. - - For example, animating from 0 to 800 will take 4 seconds if a velocity - of 200 is set, will take 8 seconds with a duration of 8000 set, and will - take 4 seconds with both a velocity of 200 and a duration of 8000 set. - Animating from 0 to 20000 will take 10 seconds if a velocity of 200 is set, - will take 8 seconds with a duration of 8000 set, and will take 8 seconds - with both a velocity of 200 and a duration of 8000 set. - - The follow example shows one rectangle tracking the position of another. -\code -import Qt 4.6 - -Rectangle { - width: 800; height: 600; color: "blue" - - Rectangle { - color: "green" - width: 60; height: 60; - x: rect1.x - 5; y: rect1.y - 5; - Behavior on x { SmoothedAnimation { velocity: 200 } } - Behavior on y { SmoothedAnimation { velocity: 200 } } - } - - Rectangle { - id: rect1 - color: "red" - width: 50; height: 50; - } - - focus: true - Keys.onRightPressed: rect1.x = rect1.x + 100 - Keys.onLeftPressed: rect1.x = rect1.x - 100 - Keys.onUpPressed: rect1.y = rect1.y - 100 - Keys.onDownPressed: rect1.y = rect1.y + 100 -} -\endcode - - 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 - set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity - of 0.5 will take 2000 ms to complete. - - \sa SpringFollow -*/ - -QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent) -: QDeclarativeNumberAnimation(*(new QDeclarativeSmoothedAnimationPrivate), parent) -{ -} - -QDeclarativeSmoothedAnimation::~QDeclarativeSmoothedAnimation() -{ -} - -QDeclarativeSmoothedAnimationPrivate::QDeclarativeSmoothedAnimationPrivate() - : wrapperGroup(new QParallelAnimationGroup), anim(new QSmoothedAnimation) -{ - Q_Q(QDeclarativeSmoothedAnimation); - QDeclarative_setParent_noEvent(wrapperGroup, q); - QDeclarative_setParent_noEvent(anim, q); -} - -QAbstractAnimation* QDeclarativeSmoothedAnimation::qtAnimation() -{ - Q_D(QDeclarativeSmoothedAnimation); - return d->wrapperGroup; -} - -void QDeclarativeSmoothedAnimation::transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction) -{ - Q_D(QDeclarativeSmoothedAnimation); - QDeclarativeNumberAnimation::transition(actions, modified, direction); - - if (!d->actions) - return; - - QSet 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; - } - - ease->target = (*d->actions)[i].property; - ease->to = (*d->actions)[i].toValue.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; - - ease->trackVelocity = trackVelocity; - ease->initialVelocity = trackVelocity; - - if (needsRestart) - ease->init(); - anims.insert(ease); - } - - for (int i = d->wrapperGroup->animationCount() - 1; i >= 0 ; --i) { - if (!anims.contains(d->wrapperGroup->animationAt(i))) { - QSmoothedAnimation *ease = static_cast(d->wrapperGroup->animationAt(i)); - d->activeAnimations.remove(ease->target); - d->wrapperGroup->takeAnimation(i); - delete ease; - } - } -} - -/*! - \qmlproperty enumeration SmoothedAnimation::reversingMode - - Sets how the SmoothedAnimation 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. -*/ -QDeclarativeSmoothedAnimation::ReversingMode QDeclarativeSmoothedAnimation::reversingMode() const -{ - Q_D(const QDeclarativeSmoothedAnimation); - return (QDeclarativeSmoothedAnimation::ReversingMode) d->anim->reversingMode; -} - -void QDeclarativeSmoothedAnimation::setReversingMode(ReversingMode m) -{ - Q_D(QDeclarativeSmoothedAnimation); - if (d->anim->reversingMode == m) - return; - - d->anim->reversingMode = m; - emit reversingModeChanged(); -} - -/*! - \qmlproperty int SmoothedAnimation::duration - - This property holds the animation duration, in msecs, used when tracking the source. - - Setting this to -1 (the default) disables the duration value. -*/ -int QDeclarativeSmoothedAnimation::duration() const -{ - Q_D(const QDeclarativeSmoothedAnimation); - return d->anim->userDuration; -} - -void QDeclarativeSmoothedAnimation::setDuration(int duration) -{ - Q_D(QDeclarativeSmoothedAnimation); - if (duration != -1) - QDeclarativeNumberAnimation::setDuration(duration); - d->anim->userDuration = duration; -} - -qreal QDeclarativeSmoothedAnimation::velocity() const -{ - Q_D(const QDeclarativeSmoothedAnimation); - return d->anim->velocity; -} - -/*! - \qmlproperty qreal SmoothedAnimation::velocity - - This property holds the average velocity allowed when tracking the 'to' value. - - The default velocity of SmoothedAnimation is 200 units/second. - - Setting this to -1 disables the velocity value. -*/ -void QDeclarativeSmoothedAnimation::setVelocity(qreal v) -{ - Q_D(QDeclarativeSmoothedAnimation); - if (d->anim->velocity == v) - return; - - d->anim->velocity = v; - emit velocityChanged(); -} - -/*! -\qmlproperty qreal SmoothedAnimation::maximumEasingTime - -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. -*/ -int QDeclarativeSmoothedAnimation::maximumEasingTime() const -{ - Q_D(const QDeclarativeSmoothedAnimation); - return d->anim->maximumEasingTime; -} - -void QDeclarativeSmoothedAnimation::setMaximumEasingTime(int v) -{ - Q_D(QDeclarativeSmoothedAnimation); - d->anim->maximumEasingTime = v; - emit maximumEasingTimeChanged(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativeeasefollow_p.h b/src/declarative/util/qdeclarativeeasefollow_p.h deleted file mode 100644 index 6c17d4f..0000000 --- a/src/declarative/util/qdeclarativeeasefollow_p.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** 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 QDECLARATIVEEASEFOLLOW_H -#define QDECLARATIVEEASEFOLLOW_H - -#include -#include "qdeclarativeanimation_p.h" - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class QDeclarativeProperty; -class QDeclarativeSmoothedAnimationPrivate; -class Q_DECLARATIVE_EXPORT QDeclarativeSmoothedAnimation : public QDeclarativeNumberAnimation -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QDeclarativeSmoothedAnimation) - Q_ENUMS(ReversingMode) - - Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) - Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged) - Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged) - -public: - enum ReversingMode { Eased, Immediate, Sync }; - - QDeclarativeSmoothedAnimation(QObject *parent = 0); - ~QDeclarativeSmoothedAnimation(); - - ReversingMode reversingMode() const; - void setReversingMode(ReversingMode); - - virtual int duration() const; - virtual void setDuration(int); - - qreal velocity() const; - void setVelocity(qreal); - - int maximumEasingTime() const; - void setMaximumEasingTime(int); - -public: - virtual void transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction); - QAbstractAnimation* qtAnimation(); - -Q_SIGNALS: - void velocityChanged(); - void reversingModeChanged(); - void maximumEasingTimeChanged(); -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QDeclarativeSmoothedAnimation); - -QT_END_HEADER - -#endif // QDECLARATIVEEASEFOLLOW_H diff --git a/src/declarative/util/qdeclarativeeasefollow_p_p.h b/src/declarative/util/qdeclarativeeasefollow_p_p.h deleted file mode 100644 index e71a009..0000000 --- a/src/declarative/util/qdeclarativeeasefollow_p_p.h +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** 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 - -#include - -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 activeAnimations; -}; - -QT_END_NAMESPACE - -#endif // QDECLARATIVESMOOTHEDANIMATION_P_H diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp new file mode 100644 index 0000000..b3a9b9a --- /dev/null +++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** 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 "qdeclarativesmoothedanimation_p.h" +#include "qdeclarativesmoothedanimation_p_p.h" + +#include "qdeclarativeanimation_p_p.h" + +#include +#include "qdeclarativeproperty_p.h" + +#include "qdeclarativeglobal_p.h" + +#include + +#include + +#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(); +} + +void QSmoothedAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/) +{ + if (newState == QAbstractAnimation::Running) + init(); +} + +void QSmoothedAnimation::delayedStop() +{ + 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; + + if (userDuration > 0 && velocity > 0) { + tf = s / velocity; + 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; + tp = 0; + td = tf; + vp = velocity; + sp = 0; + sd = s; + } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / 1000.)) { + qreal met = maximumEasingTime / 1000.; + td = tf - met; + + qreal c1 = td; + qreal c2 = (tf - td) * vi - tf * velocity; + qreal c3 = -0.5 * (tf - td) * vi * vi; + + qreal vp1 = (-c2 + sqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1); + + vp = vp1; + a = vp / met; + d = a; + tp = (vp - vi) / a; + 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 tp1 = 0.5 * tf - 0.5 * vi / a1; + qreal vp1 = a1 * tp1 + vi; + + qreal sp1 = 0.5 * a1 * tp1 * tp1 + vi * tp1; + + a = a1; + d = a1; + tp = tp1; + td = tp1; + vp = vp1; + sp = sp1; + sd = sp1; + } + return true; +} + +qreal QSmoothedAnimation::easeFollow(qreal time_seconds) +{ + 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 { + trackVelocity = 0; + value = s; + delayedStop(); + } + + // to normalize 's' between [0..1], divide 'value' by 's' + return value; +} + +void QSmoothedAnimation::updateCurrentTime(int t) +{ + qreal time_seconds = qreal(t - lastTime) / 1000.; + + qreal value = easeFollow(time_seconds); + value *= (invert? -1.0: 1.0); + QDeclarativePropertyPrivate::write(target, initialValue + value, + QDeclarativePropertyPrivate::BypassInterceptor + | QDeclarativePropertyPrivate::DontRemoveBinding); +} + +void QSmoothedAnimation::init() +{ + if (velocity == 0) { + stop(); + return; + } + + if (delayedStopTimer.isActive()) + delayedStopTimer.stop(); + + initialValue = target.read().toReal(); + lastTime = this->currentTime(); + + if (to == initialValue) { + stop(); + return; + } + + bool hasReversed = trackVelocity != 0. && + ((trackVelocity > 0) == ((initialValue - to) > 0)); + + 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; + } + } + + trackVelocity = initialVelocity; + + invert = (to < initialValue); + + if (!recalc()) { + QDeclarativePropertyPrivate::write(target, to, + QDeclarativePropertyPrivate::BypassInterceptor + | QDeclarativePropertyPrivate::DontRemoveBinding); + stop(); + return; + } +} + +/*! + \qmlclass SmoothedAnimation QDeclarativeSmoothedAnimation + \since 4.7 + \brief The SmoothedAnimation element allows a property to smoothly track a value. + + 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. + + The property animation is configured by setting the velocity at which the + animation should occur, or the duration that the animation should take. + If both a velocity and a duration are specified, the one that results in + the quickest animation is chosen for each change in the target value. + + For example, animating from 0 to 800 will take 4 seconds if a velocity + of 200 is set, will take 8 seconds with a duration of 8000 set, and will + take 4 seconds with both a velocity of 200 and a duration of 8000 set. + Animating from 0 to 20000 will take 10 seconds if a velocity of 200 is set, + will take 8 seconds with a duration of 8000 set, and will take 8 seconds + with both a velocity of 200 and a duration of 8000 set. + + The follow example shows one rectangle tracking the position of another. +\code +import Qt 4.6 + +Rectangle { + width: 800; height: 600; color: "blue" + + Rectangle { + color: "green" + width: 60; height: 60; + x: rect1.x - 5; y: rect1.y - 5; + Behavior on x { SmoothedAnimation { velocity: 200 } } + Behavior on y { SmoothedAnimation { velocity: 200 } } + } + + Rectangle { + id: rect1 + color: "red" + width: 50; height: 50; + } + + focus: true + Keys.onRightPressed: rect1.x = rect1.x + 100 + Keys.onLeftPressed: rect1.x = rect1.x - 100 + Keys.onUpPressed: rect1.y = rect1.y - 100 + Keys.onDownPressed: rect1.y = rect1.y + 100 +} +\endcode + + 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 + set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity + of 0.5 will take 2000 ms to complete. + + \sa SpringFollow +*/ + +QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent) +: QDeclarativeNumberAnimation(*(new QDeclarativeSmoothedAnimationPrivate), parent) +{ +} + +QDeclarativeSmoothedAnimation::~QDeclarativeSmoothedAnimation() +{ +} + +QDeclarativeSmoothedAnimationPrivate::QDeclarativeSmoothedAnimationPrivate() + : wrapperGroup(new QParallelAnimationGroup), anim(new QSmoothedAnimation) +{ + Q_Q(QDeclarativeSmoothedAnimation); + QDeclarative_setParent_noEvent(wrapperGroup, q); + QDeclarative_setParent_noEvent(anim, q); +} + +QAbstractAnimation* QDeclarativeSmoothedAnimation::qtAnimation() +{ + Q_D(QDeclarativeSmoothedAnimation); + return d->wrapperGroup; +} + +void QDeclarativeSmoothedAnimation::transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction) +{ + Q_D(QDeclarativeSmoothedAnimation); + QDeclarativeNumberAnimation::transition(actions, modified, direction); + + if (!d->actions) + return; + + QSet 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; + } + + ease->target = (*d->actions)[i].property; + ease->to = (*d->actions)[i].toValue.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; + + ease->trackVelocity = trackVelocity; + ease->initialVelocity = trackVelocity; + + if (needsRestart) + ease->init(); + anims.insert(ease); + } + + for (int i = d->wrapperGroup->animationCount() - 1; i >= 0 ; --i) { + if (!anims.contains(d->wrapperGroup->animationAt(i))) { + QSmoothedAnimation *ease = static_cast(d->wrapperGroup->animationAt(i)); + d->activeAnimations.remove(ease->target); + d->wrapperGroup->takeAnimation(i); + delete ease; + } + } +} + +/*! + \qmlproperty enumeration SmoothedAnimation::reversingMode + + Sets how the SmoothedAnimation 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. +*/ +QDeclarativeSmoothedAnimation::ReversingMode QDeclarativeSmoothedAnimation::reversingMode() const +{ + Q_D(const QDeclarativeSmoothedAnimation); + return (QDeclarativeSmoothedAnimation::ReversingMode) d->anim->reversingMode; +} + +void QDeclarativeSmoothedAnimation::setReversingMode(ReversingMode m) +{ + Q_D(QDeclarativeSmoothedAnimation); + if (d->anim->reversingMode == m) + return; + + d->anim->reversingMode = m; + emit reversingModeChanged(); +} + +/*! + \qmlproperty int SmoothedAnimation::duration + + This property holds the animation duration, in msecs, used when tracking the source. + + Setting this to -1 (the default) disables the duration value. +*/ +int QDeclarativeSmoothedAnimation::duration() const +{ + Q_D(const QDeclarativeSmoothedAnimation); + return d->anim->userDuration; +} + +void QDeclarativeSmoothedAnimation::setDuration(int duration) +{ + Q_D(QDeclarativeSmoothedAnimation); + if (duration != -1) + QDeclarativeNumberAnimation::setDuration(duration); + d->anim->userDuration = duration; +} + +qreal QDeclarativeSmoothedAnimation::velocity() const +{ + Q_D(const QDeclarativeSmoothedAnimation); + return d->anim->velocity; +} + +/*! + \qmlproperty qreal SmoothedAnimation::velocity + + This property holds the average velocity allowed when tracking the 'to' value. + + The default velocity of SmoothedAnimation is 200 units/second. + + Setting this to -1 disables the velocity value. +*/ +void QDeclarativeSmoothedAnimation::setVelocity(qreal v) +{ + Q_D(QDeclarativeSmoothedAnimation); + if (d->anim->velocity == v) + return; + + d->anim->velocity = v; + emit velocityChanged(); +} + +/*! +\qmlproperty qreal SmoothedAnimation::maximumEasingTime + +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. +*/ +int QDeclarativeSmoothedAnimation::maximumEasingTime() const +{ + Q_D(const QDeclarativeSmoothedAnimation); + return d->anim->maximumEasingTime; +} + +void QDeclarativeSmoothedAnimation::setMaximumEasingTime(int v) +{ + Q_D(QDeclarativeSmoothedAnimation); + d->anim->maximumEasingTime = v; + emit maximumEasingTimeChanged(); +} + +QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativesmoothedanimation_p.h b/src/declarative/util/qdeclarativesmoothedanimation_p.h new file mode 100644 index 0000000..50ed00c --- /dev/null +++ b/src/declarative/util/qdeclarativesmoothedanimation_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** 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_H +#define QDECLARATIVESMOOTHEDANIMATION_H + +#include +#include "qdeclarativeanimation_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeProperty; +class QDeclarativeSmoothedAnimationPrivate; +class Q_DECLARATIVE_EXPORT QDeclarativeSmoothedAnimation : public QDeclarativeNumberAnimation +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QDeclarativeSmoothedAnimation) + Q_ENUMS(ReversingMode) + + Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) + Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged) + Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged) + +public: + enum ReversingMode { Eased, Immediate, Sync }; + + QDeclarativeSmoothedAnimation(QObject *parent = 0); + ~QDeclarativeSmoothedAnimation(); + + ReversingMode reversingMode() const; + void setReversingMode(ReversingMode); + + virtual int duration() const; + virtual void setDuration(int); + + qreal velocity() const; + void setVelocity(qreal); + + int maximumEasingTime() const; + void setMaximumEasingTime(int); + +public: + virtual void transition(QDeclarativeStateActions &actions, + QDeclarativeProperties &modified, + TransitionDirection direction); + QAbstractAnimation* qtAnimation(); + +Q_SIGNALS: + void velocityChanged(); + void reversingModeChanged(); + void maximumEasingTimeChanged(); +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QDeclarativeSmoothedAnimation); + +QT_END_HEADER + +#endif // QDECLARATIVESMOOTHEDANIMATION_H diff --git a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h new file mode 100644 index 0000000..bdceeb3 --- /dev/null +++ b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** 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 "qdeclarativesmoothedanimation_p.h" +#include "qdeclarativeanimation_p.h" + +#include "qdeclarativeanimation_p_p.h" + +#include + +#include +#include + +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 activeAnimations; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVESMOOTHEDANIMATION_P_H diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index bf50a8b..7f2f64a 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -45,7 +45,7 @@ #include "qdeclarativebehavior_p.h" #include "qdeclarativebind_p.h" #include "qdeclarativeconnections_p.h" -#include "qdeclarativeeasefollow_p.h" +#include "qdeclarativesmoothedanimation_p.h" #include "qdeclarativefontloader_p.h" #include "qdeclarativelistaccessor_p.h" #include "qdeclarativelistmodel_p.h" diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index 249465a..4163596 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -8,7 +8,7 @@ SOURCES += \ $$PWD/qdeclarativeanimation.cpp \ $$PWD/qdeclarativesystempalette.cpp \ $$PWD/qdeclarativespringfollow.cpp \ - $$PWD/qdeclarativeeasefollow.cpp \ + $$PWD/qdeclarativesmoothedanimation.cpp \ $$PWD/qdeclarativestate.cpp\ $$PWD/qdeclarativetransitionmanager.cpp \ $$PWD/qdeclarativestateoperations.cpp \ @@ -37,8 +37,8 @@ HEADERS += \ $$PWD/qdeclarativeanimation_p_p.h \ $$PWD/qdeclarativesystempalette_p.h \ $$PWD/qdeclarativespringfollow_p.h \ - $$PWD/qdeclarativeeasefollow_p.h \ - $$PWD/qdeclarativeeasefollow_p_p.h \ + $$PWD/qdeclarativesmoothedanimation_p.h \ + $$PWD/qdeclarativesmoothedanimation_p_p.h \ $$PWD/qdeclarativestate_p.h\ $$PWD/qdeclarativestateoperations_p.h \ $$PWD/qdeclarativepropertychanges_p.h \ diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 6c5a75f..bebc54e 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -13,7 +13,6 @@ SUBDIRS += \ qdeclarativedebugclient \ # Cover qdeclarativedebugservice \ # Cover qdeclarativedom \ # Cover - qdeclarativeeasefollow \ # Cover qdeclarativeecmascript \ # Cover qdeclarativeengine \ # Cover qdeclarativeerror \ # Cover @@ -47,6 +46,7 @@ SUBDIRS += \ qdeclarativepixmapcache \ # Cover qdeclarativepropertymap \ # Cover qdeclarativeqt \ # Cover + qdeclarativesmoothedanimation \ # Cover qdeclarativespringfollow \ # Cover qdeclarativestates \ # Cover qdeclarativesystempalette \ # Cover diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml deleted file mode 100644 index cfece41..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow1.qml +++ /dev/null @@ -1,3 +0,0 @@ -import Qt 4.6 - -SmoothedAnimation {} diff --git a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml b/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml deleted file mode 100644 index 74a110d..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow2.qml +++ /dev/null @@ -1,5 +0,0 @@ -import Qt 4.6 - -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 deleted file mode 100644 index 3111e82..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollow3.qml +++ /dev/null @@ -1,6 +0,0 @@ -import Qt 4.6 - -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 deleted file mode 100644 index eb06344..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowBehavior.qml +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 9ae744c..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/data/easefollowValueSource.qml +++ /dev/null @@ -1,13 +0,0 @@ -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/qdeclarativeeasefollow.pro b/tests/auto/declarative/qdeclarativeeasefollow/qdeclarativeeasefollow.pro deleted file mode 100644 index 71df4f4..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/qdeclarativeeasefollow.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative gui -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativeeasefollow.cpp - -# Define SRCDIR equal to test's source directory -DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp b/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp deleted file mode 100644 index 401688b..0000000 --- a/tests/auto/declarative/qdeclarativeeasefollow/tst_qdeclarativeeasefollow.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** 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 test suite 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 -#include -#include -#include -#include -#include -#include "../../../shared/util.h" - -class tst_qdeclarativeeasefollow : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativeeasefollow(); - -private slots: - void defaultValues(); - void values(); - void disabled(); - void simpleAnimation(); - void valueSource(); - void behavior(); - -private: - QDeclarativeEngine engine; -}; - -tst_qdeclarativeeasefollow::tst_qdeclarativeeasefollow() -{ -} - -void tst_qdeclarativeeasefollow::defaultValues() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollow1.qml")); - QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 0.); - QCOMPARE(obj->velocity(), 200.); - QCOMPARE(obj->duration(), -1); - QCOMPARE(obj->maximumEasingTime(), -1); - QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Eased); - - delete obj; -} - -void tst_qdeclarativeeasefollow::values() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollow2.qml")); - QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 10.); - QCOMPARE(obj->velocity(), 200.); - QCOMPARE(obj->duration(), 300); - QCOMPARE(obj->maximumEasingTime(), -1); - QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Immediate); - - delete obj; -} - -void tst_qdeclarativeeasefollow::disabled() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/easefollow3.qml")); - QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 10.); - QCOMPARE(obj->velocity(), 250.); - 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(c.create()); - QVERIFY(rect); - - QDeclarativeRectangle *theRect = rect->findChild("theRect"); - QVERIFY(theRect); - - QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); - QVERIFY(easeX); - QVERIFY(easeX->isRunning()); - - QDeclarativeSmoothedAnimation *easeY = rect->findChild("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(c.create()); - QVERIFY(rect); - - QDeclarativeRectangle *theRect = rect->findChild("theRect"); - QVERIFY(theRect); - - QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); - QVERIFY(easeX); - - QDeclarativeSmoothedAnimation *easeY = rect->findChild("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/qdeclarativesmoothedanimation/data/smoothedanimation1.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml new file mode 100644 index 0000000..cfece41 --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +SmoothedAnimation {} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml new file mode 100644 index 0000000..74a110d --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +SmoothedAnimation { + to: 10; duration: 300; reversingMode: SmoothedAnimation.Immediate +} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml new file mode 100644 index 0000000..3111e82 --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml @@ -0,0 +1,6 @@ +import Qt 4.6 + +SmoothedAnimation { + to: 10; velocity: 250; reversingMode: SmoothedAnimation.Sync + maximumEasingTime: 150 +} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml new file mode 100644 index 0000000..eb06344 --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.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/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml new file mode 100644 index 0000000..9ae744c --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.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/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro new file mode 100644 index 0000000..b41b23a --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativesmoothedanimation.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp b/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp new file mode 100644 index 0000000..7cf318a --- /dev/null +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** 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 test suite 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 +#include +#include +#include +#include +#include +#include "../../../shared/util.h" + +class tst_qdeclarativesmoothedanimation : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativesmoothedanimation(); + +private slots: + void defaultValues(); + void values(); + void disabled(); + void simpleAnimation(); + void valueSource(); + void behavior(); + +private: + QDeclarativeEngine engine; +}; + +tst_qdeclarativesmoothedanimation::tst_qdeclarativesmoothedanimation() +{ +} + +void tst_qdeclarativesmoothedanimation::defaultValues() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimation1.qml")); + QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 0.); + QCOMPARE(obj->velocity(), 200.); + QCOMPARE(obj->duration(), -1); + QCOMPARE(obj->maximumEasingTime(), -1); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Eased); + + delete obj; +} + +void tst_qdeclarativesmoothedanimation::values() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimation2.qml")); + QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 10.); + QCOMPARE(obj->velocity(), 200.); + QCOMPARE(obj->duration(), 300); + QCOMPARE(obj->maximumEasingTime(), -1); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Immediate); + + delete obj; +} + +void tst_qdeclarativesmoothedanimation::disabled() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimation3.qml")); + QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 10.); + QCOMPARE(obj->velocity(), 250.); + QCOMPARE(obj->maximumEasingTime(), 150); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Sync); + + delete obj; +} + +void tst_qdeclarativesmoothedanimation::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_qdeclarativesmoothedanimation::valueSource() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimationValueSource.qml")); + + QDeclarativeRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeRectangle *theRect = rect->findChild("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); + QVERIFY(easeX); + QVERIFY(easeX->isRunning()); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild("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_qdeclarativesmoothedanimation::behavior() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimationBehavior.qml")); + + QDeclarativeRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeRectangle *theRect = rect->findChild("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); + QVERIFY(easeX); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild("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_qdeclarativesmoothedanimation) + +#include "tst_qdeclarativesmoothedanimation.moc" diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.0.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.0.png deleted file mode 100644 index 21b6afb..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.0.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.1.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.1.png deleted file mode 100644 index bb8a02b..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.1.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.2.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.2.png deleted file mode 100644 index da60237..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.2.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.3.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.3.png deleted file mode 100644 index 3e943e8..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.3.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.4.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.4.png deleted file mode 100644 index 4fbaf26..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.4.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.5.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.5.png deleted file mode 100644 index c10d196..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.5.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.6.png b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.6.png deleted file mode 100644 index a672c06..0000000 Binary files a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.6.png and /dev/null differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.qml b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.qml deleted file mode 100644 index 029a2fc..0000000 --- a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/data/easefollow.qml +++ /dev/null @@ -1,1807 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { - msec: 0 - } - Frame { - msec: 16 - hash: "1f60efdb8704b92c9361daa468a25391" - } - Frame { - msec: 32 - hash: "3bb6a87617e0e5d4922e573eec975886" - } - Frame { - msec: 48 - hash: "268941737e6324d580890b151de621fb" - } - Frame { - msec: 64 - hash: "99c674eccc082d7f0982257a748d93e5" - } - Frame { - msec: 80 - hash: "2970467e8262c8a3f0b11be71245d048" - } - Frame { - msec: 96 - hash: "63cbd06d6bb035d27c18dba49238d8b2" - } - Frame { - msec: 112 - hash: "49f77bb3d323f882c0ec56e1f1040b3a" - } - Frame { - msec: 128 - hash: "40263c5f9b5d2236536163785f832b4d" - } - Frame { - msec: 144 - hash: "dc63b1c21a2027c4beb9c297a3677fbd" - } - Frame { - msec: 160 - hash: "4fab52ea29a819fec032f19dbcbef012" - } - Frame { - msec: 176 - hash: "60b48407a8f8ae2cce7d3e7c8b21991c" - } - Frame { - msec: 192 - hash: "6e542c681092a5ebeef0534fa2bd2d6c" - } - Frame { - msec: 208 - hash: "c7c6471969bbf81efdb86d1695548fc6" - } - Frame { - msec: 224 - hash: "b7f4ad9a49feb400894209c02b94478a" - } - Frame { - msec: 240 - hash: "3eb58b2f5233aead976183c13f241113" - } - Frame { - msec: 256 - hash: "54f2036c50c6d8079fc0cadc01385980" - } - Frame { - msec: 272 - hash: "f297659d75f6e724d72bd548821f4c9f" - } - Frame { - msec: 288 - hash: "112798f080336fc9c603a7e9097dd8aa" - } - Frame { - msec: 304 - hash: "c432e6ec2b53ca43cb7a7325d0cc379b" - } - Frame { - msec: 320 - hash: "4a6d3db3efd665ad7f372bf3f2508ed7" - } - Frame { - msec: 336 - hash: "0befa5dc4d2cc196fed0eb1a3aa75b8f" - } - Frame { - msec: 352 - hash: "a34d010b50d59c362b54e44d69c2df91" - } - Frame { - msec: 368 - hash: "cbdacced50186c87066ce1d46548b27e" - } - Frame { - msec: 384 - hash: "a4060010ae4d3c0973bda48d68f7bd0a" - } - Frame { - msec: 400 - hash: "47353437da587f732f986004c09884d0" - } - Frame { - msec: 416 - hash: "080c348145167bbec671a04da6f7564f" - } - Frame { - msec: 432 - hash: "69dead737c717a076ae3865680341fb4" - } - Frame { - msec: 448 - hash: "1efdc31c5c8fa72fc848877deb6caaa4" - } - Frame { - msec: 464 - hash: "28d7da1e933d0585d03acf4a529e7b42" - } - Frame { - msec: 480 - hash: "bf85534124bf025b7ede0d6c80b8e443" - } - Frame { - msec: 496 - hash: "cdbeb2d51541b1b1eff060efe993db91" - } - Frame { - msec: 512 - hash: "52ad56ae16c8ab523adda8edc512dd87" - } - Frame { - msec: 528 - hash: "61b1937f4c8dd2cb0ddd7031c5bfb3ab" - } - Frame { - msec: 544 - hash: "1b109baba71b16827f90da654af093a3" - } - Frame { - msec: 560 - hash: "d56621362802c8626868f36ba1e7db22" - } - Frame { - msec: 576 - hash: "ee5555ec3ad8760f43bbf5958a925936" - } - Frame { - msec: 592 - hash: "1ed2831144a453af1978605c0e42d17c" - } - Frame { - msec: 608 - hash: "c74d5cdb3395a702269dfa88c8c9d975" - } - Frame { - msec: 624 - hash: "ea98ddd9588cc23fd82a342ec2925ba8" - } - Frame { - msec: 640 - hash: "e76b94d6d57f1a510f7649eaab892562" - } - Frame { - msec: 656 - hash: "022f40b6fe9dbaf8019855234acb3461" - } - Frame { - msec: 672 - hash: "467da4f48aa6aeb113f0797facf157e8" - } - Frame { - msec: 688 - hash: "8df407aadd4d896eb6537e1555a0242f" - } - Frame { - msec: 704 - hash: "122e4671881e31f54e617729f4fbb3b0" - } - Frame { - msec: 720 - hash: "562718f101c3cd7525b890076413df5e" - } - Frame { - msec: 736 - hash: "07feae99ecf4b70eb094fd3e10deca56" - } - Frame { - msec: 752 - hash: "0980d133b1006cc07796023880415163" - } - Frame { - msec: 768 - hash: "7112b6ac97678b3b942c64c5108f0329" - } - Frame { - msec: 784 - hash: "bb9f893a9aaee60ab6c30918552828a4" - } - Frame { - msec: 800 - hash: "65d1f29437aaaea33676757276f1e434" - } - Frame { - msec: 816 - hash: "52adcf2509f3236ac8ef571708e77206" - } - Frame { - msec: 832 - hash: "22df5e7eda8a813531d0e0366cbfbf64" - } - Frame { - msec: 848 - hash: "fe9b7b7812dd2410b8ed2eb19aa78f4d" - } - Frame { - msec: 864 - hash: "141e22de4469f316b5ef5471f3c7bba0" - } - Frame { - msec: 880 - hash: "1125c0a105fc4a2cae36b798058ce23f" - } - Frame { - msec: 896 - hash: "8c17c5da2ae867fb0016a485ba9e4166" - } - Frame { - msec: 912 - hash: "d8da9fc7ec4dcefb894c5a6a71e9d001" - } - Frame { - msec: 928 - hash: "00ff642bea89fd89de394d78f8c5db33" - } - Frame { - msec: 944 - hash: "8549063d517a3ce1ffd44c56b3b6cf5e" - } - Frame { - msec: 960 - image: "easefollow.0.png" - } - Frame { - msec: 976 - hash: "95a642caa72bb31cc1e04ecc12d07cd0" - } - Frame { - msec: 992 - hash: "e65c823476bf920d0386f62ca831e6a0" - } - Frame { - msec: 1008 - hash: "91e8913dc693c91a674a10b5b088dd8f" - } - Frame { - msec: 1024 - hash: "1a469ffa0d530f72c78dc14783891c78" - } - Frame { - msec: 1040 - hash: "6e46a83d07f8bc034b421103ef0e4f8c" - } - Frame { - msec: 1056 - hash: "8ddacab411a8b73b6c9e69576fa1b003" - } - Frame { - msec: 1072 - hash: "41f419a85fe44efe27c9a526d83a1e9a" - } - Frame { - msec: 1088 - hash: "73d4ece31b258f9caf4556ce20a5be1f" - } - Frame { - msec: 1104 - hash: "ef3ebe0acb50386cf79b9f08fbba2fbc" - } - Frame { - msec: 1120 - hash: "c11a84d2fa80f28adb1466409812e987" - } - Frame { - msec: 1136 - hash: "2e9db854b02d28b38063ff2a8e821ed1" - } - Frame { - msec: 1152 - hash: "48e073c0e6b19aea8314629a2179af87" - } - Frame { - msec: 1168 - hash: "77e518b7428d93b67a8fb0d33d85ed97" - } - Frame { - msec: 1184 - hash: "1d18323af9c62e015513451883f8b39f" - } - Frame { - msec: 1200 - hash: "df49889ba157cdc1ca240d08d2760ad7" - } - Frame { - msec: 1216 - hash: "7b8cd2bcf0a4c38ab870f27894a43d2f" - } - Frame { - msec: 1232 - hash: "84f10e0c9fd57dd1799df7fc34c5ef01" - } - Frame { - msec: 1248 - hash: "ead4e609bc4a0755032b1648485b9625" - } - Frame { - msec: 1264 - hash: "9a9829c3bd4a3a4155383c37e21e8db8" - } - Frame { - msec: 1280 - hash: "5008917f60256abad867f32c1caf954d" - } - Frame { - msec: 1296 - hash: "c21455d66ed0754177af5ce44b7c7600" - } - Frame { - msec: 1312 - hash: "e8332f2586d80a2700b610e8fe5c72d9" - } - Frame { - msec: 1328 - hash: "0d0c8af138f98bae8a370ebec4a4796c" - } - Frame { - msec: 1344 - hash: "04065e8feeb900d18deeb941572f7f10" - } - Frame { - msec: 1360 - hash: "992a225b1f25bf5b21dd7f8a55dc4b70" - } - Frame { - msec: 1376 - hash: "8ef739d91ee2a4337cbfc3dc94ce9845" - } - Frame { - msec: 1392 - hash: "46744977a26b37ab65e65e1891ceafe7" - } - Frame { - msec: 1408 - hash: "1b4c0d79eeb8d6b2e30172f3664407b9" - } - Frame { - msec: 1424 - hash: "d572831ed34d14d1125570b8b8767bdb" - } - Frame { - msec: 1440 - hash: "8b785c756d11e0fc18959d0897a45673" - } - Frame { - msec: 1456 - hash: "164a71ffcea63ceb6c1ebeb8d0d07af1" - } - Frame { - msec: 1472 - hash: "e128dc12d5117eed9f7c0a16e8348ba2" - } - Frame { - msec: 1488 - hash: "4c7db5b12d83bf22b1c88ac06ca7c385" - } - Frame { - msec: 1504 - hash: "c7283df8dbd78121e17a5893e3ea4f3c" - } - Frame { - msec: 1520 - hash: "fea768e5bb43f6d86d88ced9f73915de" - } - Frame { - msec: 1536 - hash: "b99b54f8e75452c539bb4e7b6a36e944" - } - Frame { - msec: 1552 - hash: "b7274938d16f03b376ad9739e2e893f1" - } - Frame { - msec: 1568 - hash: "e61601942193add8c1c8ebf5c5319932" - } - Frame { - msec: 1584 - hash: "8fdc2181e0120391505706716ba7e5d7" - } - Frame { - msec: 1600 - hash: "66f737ed28453da5175d6b5e807c374d" - } - Frame { - msec: 1616 - hash: "2e00a7895d61edbe794f0a8000871b30" - } - Frame { - msec: 1632 - hash: "1a279fc6b7c4105eccc4e3bc99481bef" - } - Frame { - msec: 1648 - hash: "bc1dea4d23ca9bc29b72a8c2bde4787b" - } - Frame { - msec: 1664 - hash: "8ef40e0be5fb82b32b365b3d4b85421d" - } - Frame { - msec: 1680 - hash: "ee37c68bf38d5eed4e3e9a31306f6801" - } - Frame { - msec: 1696 - hash: "303d760c87a7a833606c8e9f46cb5fc0" - } - Frame { - msec: 1712 - hash: "cc2563b47c58efd39bec6b4e0f2995bb" - } - Frame { - msec: 1728 - hash: "33f7daf09497510475283d6dc7c51228" - } - Frame { - msec: 1744 - hash: "5b5e2de9934c80bd49e0eb7afd85151d" - } - Frame { - msec: 1760 - hash: "5e6bf706336789ca6b60a82998b70113" - } - Frame { - msec: 1776 - hash: "b4d4a860f49bfb88dd2079862b40b7ec" - } - Frame { - msec: 1792 - hash: "07b571fa55327487e34a592c778beb67" - } - Frame { - msec: 1808 - hash: "cb5b349a536cf75a83734181b3eab92b" - } - Frame { - msec: 1824 - hash: "ce903bb58c5c86f2955e68412893aedf" - } - Frame { - msec: 1840 - hash: "ffa89e879558c83ed538812a93e2fe29" - } - Frame { - msec: 1856 - hash: "562aa66bf537853be82a654542c8b80e" - } - Frame { - msec: 1872 - hash: "dc45dac0cc20220bcc81210fb5506ee2" - } - Frame { - msec: 1888 - hash: "3b429eb827df0800a1ad8b906ea32ef9" - } - Frame { - msec: 1904 - hash: "d6ebaf12515d9e24cdbf6d75080c0b28" - } - Frame { - msec: 1920 - image: "easefollow.1.png" - } - Frame { - msec: 1936 - hash: "9f6d26224055c809dc2f3490cd0ff880" - } - Frame { - msec: 1952 - hash: "5630cc8f0b401f7d81bdceaaae5cce68" - } - Frame { - msec: 1968 - hash: "dafda60467e5e2b99c41543dd191ac2d" - } - Frame { - msec: 1984 - hash: "e053cb07a734278cd111d612883c165e" - } - Frame { - msec: 2000 - hash: "63870f3e99c11707004dab9439d61389" - } - Frame { - msec: 2016 - hash: "14c311a6fab45f828c3a19535ea9edc8" - } - Frame { - msec: 2032 - hash: "13e614446cbfcbfd2a7ecc5f0e8688df" - } - Frame { - msec: 2048 - hash: "173c97f59da05b9347180a4824e60c06" - } - Frame { - msec: 2064 - hash: "932e2a9bbcb7dc5befca8f63d8fa3c95" - } - Frame { - msec: 2080 - hash: "4b8f232ffe0cbc7f900de5737c9f95be" - } - Frame { - msec: 2096 - hash: "9686d294d4e931a5eed0e6b5bda63377" - } - Frame { - msec: 2112 - hash: "969c569d92e3ec51dfbdd20d64432224" - } - Frame { - msec: 2128 - hash: "0cef3550cca9fb5611b836098c517dd1" - } - Frame { - msec: 2144 - hash: "6728080a09aa5d48462a3abb8e285e8a" - } - Frame { - msec: 2160 - hash: "4b904dc671b7fc72db0b6e52543e96bd" - } - Frame { - msec: 2176 - hash: "38232f89dffc9b16db6ea60b02f8d1be" - } - Frame { - msec: 2192 - hash: "6b41f2a0f950eddad217a03e137f9a9b" - } - Frame { - msec: 2208 - hash: "be576ea74c2c404da46fcf1d22de6df9" - } - Frame { - msec: 2224 - hash: "3f44bad4b51ceff2944337064a5efa91" - } - Frame { - msec: 2240 - hash: "e1ab98ac1366e9fd8af62a6a26878c73" - } - Frame { - msec: 2256 - hash: "bd131e1725a54b3dbbb86a29ca8a56a9" - } - Frame { - msec: 2272 - hash: "4d3e8af70f228643803f780c4e36f1a6" - } - Frame { - msec: 2288 - hash: "853a5ab4271af7a7638454cfa883aa33" - } - Frame { - msec: 2304 - hash: "ede9260157000f346900153ce2409278" - } - Frame { - msec: 2320 - hash: "b2b16d8ce1ba89f0d9558ac387e25c3d" - } - Frame { - msec: 2336 - hash: "387d338910453637c5cf80fa35528e56" - } - Frame { - msec: 2352 - hash: "26deabf9cdd994455f2a8802eb0e04dc" - } - Frame { - msec: 2368 - hash: "13939659a315dae1b81e3ea166102edf" - } - Frame { - msec: 2384 - hash: "be92b55bb7562372401b25a9167abb2b" - } - Frame { - msec: 2400 - hash: "ee7bf60d7ee97b7de5e909b9af88df80" - } - Frame { - msec: 2416 - hash: "434313a3bcd1d7582b0d89b9a145ef09" - } - Frame { - msec: 2432 - hash: "0857ca59a283897e3df62b9633488f83" - } - Frame { - msec: 2448 - hash: "76718fc7e3d21b54930bc8307a57733a" - } - Frame { - msec: 2464 - hash: "93a91588b38129053a462b920fd686e3" - } - Frame { - msec: 2480 - hash: "2a2486c52fde915696fd8cbd3682e8db" - } - Frame { - msec: 2496 - hash: "b1f4ab6cc5fb4a3a1b4885f2d1b29277" - } - Frame { - msec: 2512 - hash: "4258afce8a85a2e9ead149e34b43d8fc" - } - Frame { - msec: 2528 - hash: "6672c71b98e13d51ebb523aed9036a72" - } - Frame { - msec: 2544 - hash: "eaa39af7eb78948f433e3b44a9454317" - } - Frame { - msec: 2560 - hash: "0a766bc97bea67d4b848c703eaa6777a" - } - Frame { - msec: 2576 - hash: "0b461ec1885ede1dd96b71cf38bfd3d6" - } - Frame { - msec: 2592 - hash: "15efc929370a3864529080e30db1026a" - } - Frame { - msec: 2608 - hash: "e1529e30ff1e4ea1b092a88e85f2f1f6" - } - Frame { - msec: 2624 - hash: "f29bd9dbf7317e94b885da63f0cb7374" - } - Frame { - msec: 2640 - hash: "e5294e087e2ce0d7d936c0129b6c37ae" - } - Frame { - msec: 2656 - hash: "9c63129e774b391cc398cf5da5c9339c" - } - Frame { - msec: 2672 - hash: "4371d85854419d4b00671176bb7c5a2b" - } - Frame { - msec: 2688 - hash: "dd10b3f50e2fdc56c75f00321634b1cc" - } - Frame { - msec: 2704 - hash: "aac6256b21152a5f1f8c576b667d275e" - } - Frame { - msec: 2720 - hash: "c937c44037b2228590d334df4d56a86f" - } - Frame { - msec: 2736 - hash: "f6c714db51cbd1bdb737afe612c33f9c" - } - Frame { - msec: 2752 - hash: "0bba45af79f3201bc7cf042d5c648f73" - } - Frame { - msec: 2768 - hash: "941b08ddbafea3bd46262c060b1e290b" - } - Frame { - msec: 2784 - hash: "d898918dc2023de239b4ab38f7420960" - } - Frame { - msec: 2800 - hash: "d1a16dc2282329113093d06862e7a871" - } - Frame { - msec: 2816 - hash: "bba5359475f643fbeee240e71e843d4c" - } - Frame { - msec: 2832 - hash: "03cf861f4b6bc767e723e47e95c2448b" - } - Frame { - msec: 2848 - hash: "a64bf158c6199b88bc2db3b741d342f0" - } - Frame { - msec: 2864 - hash: "cf0fe7cb42ba842f1c28c1211adb768d" - } - Frame { - msec: 2880 - image: "easefollow.2.png" - } - Frame { - msec: 2896 - hash: "9b3c6414e4ef5a452a5c92bb0b893fc3" - } - Frame { - msec: 2912 - hash: "7cc7ddec3ac2d8cac33c0b0f80a7544d" - } - Frame { - msec: 2928 - hash: "7dd4e7d606e953c872c57fad786d64aa" - } - Frame { - msec: 2944 - hash: "117cc903a39d99ca22f6556095e6f883" - } - Frame { - msec: 2960 - hash: "c6c9304fd65fee1909473bdb21ac7806" - } - Frame { - msec: 2976 - hash: "8e704fe81c040f49c4d80e7dcc46084d" - } - Frame { - msec: 2992 - hash: "d202d5c0a058e1e088fdd280e59f17bb" - } - Frame { - msec: 3008 - hash: "90c072dea32c056f8bd6d010df681929" - } - Frame { - msec: 3024 - hash: "80b4e99f1b47e64084e295a2a3e1121e" - } - Frame { - msec: 3040 - hash: "41d6307075ec9ae9e92d227921f71289" - } - Frame { - msec: 3056 - hash: "f33de23cf4a5c4881310c6866261d387" - } - Frame { - msec: 3072 - hash: "441faa0a1fc95d66b27479dfc1e40188" - } - Frame { - msec: 3088 - hash: "2314b5f6ba3864abd5e87bc87bd621b0" - } - Frame { - msec: 3104 - hash: "e71e3b0ad953258ceef3101e38283fdb" - } - Frame { - msec: 3120 - hash: "890c3b0e727f136bf1ccc486531c9677" - } - Frame { - msec: 3136 - hash: "2a0d23e6dcc6475c323dbf8eb36e8094" - } - Frame { - msec: 3152 - hash: "692682e82347936f87a66484b428e959" - } - Frame { - msec: 3168 - hash: "cf4005c08789762ad21be1a1d78755c9" - } - Frame { - msec: 3184 - hash: "566184563091626bb20ae679e3ce3b91" - } - Frame { - msec: 3200 - hash: "f88a24ad3bbc2699924bb9a7ff6490b3" - } - Frame { - msec: 3216 - hash: "23f3f63d07b2bdc2b82ff4e8606a634d" - } - Frame { - msec: 3232 - hash: "fe121c71ce469ec6f0bf957eb2f0447b" - } - Frame { - msec: 3248 - hash: "ba217690a33c701afe11842aa8105cbb" - } - Frame { - msec: 3264 - hash: "e5c7c1323108f13ba26f5198cc62c137" - } - Frame { - msec: 3280 - hash: "664f76d3d0008b56be2790c470befc91" - } - Frame { - msec: 3296 - hash: "b3f54070ba64b983ccd2a15941ef4c35" - } - Frame { - msec: 3312 - hash: "8a0ba2ae36ad3811778f3a3bc55743f5" - } - Frame { - msec: 3328 - hash: "bfdc71733ca45a2ba2e8abf751554a62" - } - Frame { - msec: 3344 - hash: "686e4d7bb5ae148d37fc2a1f6004a33a" - } - Frame { - msec: 3360 - hash: "29c553d9fe42fdbbd019d0ead61dffa0" - } - Frame { - msec: 3376 - hash: "bfa2b72c6554a2ed80a3b86f2cbed986" - } - Frame { - msec: 3392 - hash: "074ff90417a947f0a04926d5675d073b" - } - Frame { - msec: 3408 - hash: "6f56f9e0aa40149156ca71d6f8d4476a" - } - Frame { - msec: 3424 - hash: "950ce749bbf572021de2dd1688cb87e6" - } - Frame { - msec: 3440 - hash: "2d0903bd71862dc6f28bd702d955ae99" - } - Frame { - msec: 3456 - hash: "2733adae56728f1b744a4086ecb98052" - } - Frame { - msec: 3472 - hash: "779859d739e799bba15beeb97d18e682" - } - Frame { - msec: 3488 - hash: "9074386cfabe136b8839637e5cd58f57" - } - Frame { - msec: 3504 - hash: "fa5bcbf20c6ad0a218f23d98961229a1" - } - Frame { - msec: 3520 - hash: "5406c94da1717eaa5eb0010564216059" - } - Frame { - msec: 3536 - hash: "27d0a3c3a33c04df843bebd72ef79824" - } - Frame { - msec: 3552 - hash: "270df9c99c2679071b854b3d82337f79" - } - Frame { - msec: 3568 - hash: "5b3945505443a67e7a91f66fe42b4fe3" - } - Frame { - msec: 3584 - hash: "9a2f8565c354cb366725368ed323ccf4" - } - Frame { - msec: 3600 - hash: "6702cb7ccd61c008b511932d7bd5d107" - } - Frame { - msec: 3616 - hash: "f6b86c3a1cc88357f588b6dae11aae30" - } - Frame { - msec: 3632 - hash: "b10c23937f420db72af8abaf126f71c2" - } - Frame { - msec: 3648 - hash: "7d6b0810ffc6e488c8168e19bccb7358" - } - Frame { - msec: 3664 - hash: "c01ef69ec46391909619434e9d9dd0ce" - } - Frame { - msec: 3680 - hash: "a046464fccb0c5ba1f63f8b569821a44" - } - Frame { - msec: 3696 - hash: "8763c526924d882438f9aa9bfb4fe87d" - } - Frame { - msec: 3712 - hash: "dede7a62d6e5c10e8f30caa075bd8dfd" - } - Frame { - msec: 3728 - hash: "3b408e5c986f5bb01d8c3949876b792f" - } - Frame { - msec: 3744 - hash: "0a458f3b17cdd3ea85522779c9346af9" - } - Frame { - msec: 3760 - hash: "fef521f0301cce90af88d37e6d441ec8" - } - Frame { - msec: 3776 - hash: "3d083e0822242b3b37c6839ca91a1f68" - } - Frame { - msec: 3792 - hash: "f8fe013a717e6e61830137bdc78a8b40" - } - Frame { - msec: 3808 - hash: "0ae80ad65dd194043500fa50b5a547a6" - } - Frame { - msec: 3824 - hash: "a53c67fa32ef971eaea202fa5d8a6ad6" - } - Frame { - msec: 3840 - image: "easefollow.3.png" - } - Frame { - msec: 3856 - hash: "41f86bbf0658b127f01e8d46d7ec941b" - } - Frame { - msec: 3872 - hash: "d20f21df127565f9eb87c5d759a638d9" - } - Frame { - msec: 3888 - hash: "85ff94f03cea3e111807e90d062c1367" - } - Frame { - msec: 3904 - hash: "aa637850fe5f05a71ac4c7d31dbb36ee" - } - Frame { - msec: 3920 - hash: "c86a67096c5e62bb73b785cdf6a5b6b1" - } - Frame { - msec: 3936 - hash: "9d53537f2c50a0016bf7bb522b2ec3d8" - } - Frame { - msec: 3952 - hash: "b48630c27c27785ddce568a85d4dc58f" - } - Frame { - msec: 3968 - hash: "01c1bdb6e261cc509f26712b13eeb554" - } - Frame { - msec: 3984 - hash: "af8a44284695fd999acd5944434f0372" - } - Frame { - msec: 4000 - hash: "b156d9d6d5163f007ac4a309d8927ae9" - } - Frame { - msec: 4016 - hash: "2df3715416c3c005f04b66fe1258c0d8" - } - Frame { - msec: 4032 - hash: "96b4a7c6b8542b50fc345b54d38ec82a" - } - Frame { - msec: 4048 - hash: "7e62e757fafa06833444c3a7e1d96ce4" - } - Frame { - msec: 4064 - hash: "5222a8f9366c7d974d0687d05d229069" - } - Frame { - msec: 4080 - hash: "ec96169f4633c3bddfd582feeb8e9ad4" - } - Frame { - msec: 4096 - hash: "cb10db893d1e1cb2a370507dc5679985" - } - Frame { - msec: 4112 - hash: "d7e346c2ac77796bde639bd829b72e85" - } - Frame { - msec: 4128 - hash: "ba5bea8857e4fb444bedd3873563e7db" - } - Frame { - msec: 4144 - hash: "05556fba5d1714f70fd6c2bfb43d213b" - } - Frame { - msec: 4160 - hash: "aeeabf35f9759f045a670a9b9f90dc68" - } - Frame { - msec: 4176 - hash: "131bd453f4c7726e5fdd546252700e2e" - } - Frame { - msec: 4192 - hash: "7c5c3b5bb7a4082e6b9b43640e29f4e2" - } - Frame { - msec: 4208 - hash: "07515e21b7a7895f333e4a8bbd2202eb" - } - Frame { - msec: 4224 - hash: "6cf136f223ac6edd39ba6ed9b4445884" - } - Frame { - msec: 4240 - hash: "84264f5745add8a922101735ed8def84" - } - Frame { - msec: 4256 - hash: "660863d1e4b361f2e5445b417be0d2ad" - } - Frame { - msec: 4272 - hash: "7ceb86f4b16546370d72164d0ca3147c" - } - Frame { - msec: 4288 - hash: "a13e97da9722545ad87ac3c5eb92c497" - } - Frame { - msec: 4304 - hash: "5896b5307cbd609d2062d3607786d40c" - } - Frame { - msec: 4320 - hash: "c8c511115394116e4544c67f615ea5d5" - } - Frame { - msec: 4336 - hash: "59ca5fdf12a735e5c292901b54acccb2" - } - Frame { - msec: 4352 - hash: "155cce2738d34e0eac86f5eb63d638f0" - } - Frame { - msec: 4368 - hash: "83a840c3ae7dbd9a05c17fdd8be07d7a" - } - Frame { - msec: 4384 - hash: "800a15de28b14d88f0ad58fc3f4a2520" - } - Frame { - msec: 4400 - hash: "c8381439a3cd3f9e7f80061023723a6e" - } - Frame { - msec: 4416 - hash: "e3d63000db4b9458b202dece49d1bdba" - } - Frame { - msec: 4432 - hash: "c943e56781695798f3c221f8ab09681a" - } - Frame { - msec: 4448 - hash: "1137ee66d7fbf5a84c33f5ffff15b3dd" - } - Frame { - msec: 4464 - hash: "5a98013cc4462aad18cad8d941f77aa0" - } - Frame { - msec: 4480 - hash: "d0b3748fb49a13c0ad9a68b0e2914921" - } - Frame { - msec: 4496 - hash: "12113f71f9117670acbd7877edded7e0" - } - Frame { - msec: 4512 - hash: "22983424da08cdae7a9c6a8905b37736" - } - Frame { - msec: 4528 - hash: "b2db5618a025cefb2650124c81880c49" - } - Frame { - msec: 4544 - hash: "84fb5e7edc5b42163a83e0cd362b3a46" - } - Frame { - msec: 4560 - hash: "39d6f1ed0f60a0c366c22e1442c455ac" - } - Frame { - msec: 4576 - hash: "702367f6e4aaa2a862e57f9e02a08758" - } - Frame { - msec: 4592 - hash: "ecc75293bc156c560d55cb7d278a4e58" - } - Frame { - msec: 4608 - hash: "e68af8e97ce65376fd7904e599440c92" - } - Frame { - msec: 4624 - hash: "75fe9f766d6cf636cd72d8879a461439" - } - Frame { - msec: 4640 - hash: "162aef147ef4bbb0cd92bd70e4f37f62" - } - Frame { - msec: 4656 - hash: "d879aae8949976c7bad4d97f1e5b5549" - } - Frame { - msec: 4672 - hash: "8a983d7228190721f988de2d72cb3aa2" - } - Frame { - msec: 4688 - hash: "a4f3c63fde664d128cd35b129a4f9a23" - } - Frame { - msec: 4704 - hash: "115fb5f3c9b7f1c28ab379596faba91c" - } - Frame { - msec: 4720 - hash: "ea9600c4d6c77a3b32e59401aa84fe96" - } - Frame { - msec: 4736 - hash: "bd6531fdd9cfd46af2df73bacb31f4c5" - } - Frame { - msec: 4752 - hash: "33bdcf1df50eab5e7963c649fbd32226" - } - Frame { - msec: 4768 - hash: "236e88fb72369a55f9eba4b50712ae85" - } - Frame { - msec: 4784 - hash: "5eb3c14a6296fb3a1c58603b2fc937c8" - } - Frame { - msec: 4800 - image: "easefollow.4.png" - } - Frame { - msec: 4816 - hash: "31d11a1ce6422524241c77603fe53e61" - } - Frame { - msec: 4832 - hash: "44e8b9947026c10b922c84883dd8e889" - } - Frame { - msec: 4848 - hash: "d049e4f7c4bc1849398859a4d630c1b3" - } - Frame { - msec: 4864 - hash: "e83b4757898e4eeef74be8213619fbfa" - } - Frame { - msec: 4880 - hash: "d08f40615f2d5abc6236e856a67575dd" - } - Frame { - msec: 4896 - hash: "d9cb26bf1b8bbafb2aed8f74bd454077" - } - Frame { - msec: 4912 - hash: "aa321b94a6cc53b2ebac80e834c0a908" - } - Frame { - msec: 4928 - hash: "48da37164be156b67a4b3b14e50f2375" - } - Frame { - msec: 4944 - hash: "f522ce7728a4a9e7fad86c72f29bd8f9" - } - Frame { - msec: 4960 - hash: "9bc1d16b4bda596702a3d8a3fad8a5c5" - } - Frame { - msec: 4976 - hash: "5275dccf18745dec6c59b846de17d9ef" - } - Frame { - msec: 4992 - hash: "4eb6babc177b96f69b148d52f56d82d7" - } - Frame { - msec: 5008 - hash: "ccdfb454070ac04c4fe4f3513c52f8c8" - } - Frame { - msec: 5024 - hash: "07f6adad6e8ff4f0eff92c758636a951" - } - Frame { - msec: 5040 - hash: "241e0ad9218d49be477509e008e45548" - } - Frame { - msec: 5056 - hash: "151a482e821779da8a61063f1cc73f8c" - } - Frame { - msec: 5072 - hash: "1499d207c5a3a9bc7bbb84d9c5e35578" - } - Frame { - msec: 5088 - hash: "c253753f653157a5058ef071f16b8bbb" - } - Frame { - msec: 5104 - hash: "ec9fea5a870724a106b952edef7fb466" - } - Frame { - msec: 5120 - hash: "99b673f8ed049d31a2aecabcc46d841d" - } - Frame { - msec: 5136 - hash: "61e77fea693ea55aafbdc94c40c3ab33" - } - Frame { - msec: 5152 - hash: "53e44a3732ee6858d5bd596b4c5d5305" - } - Frame { - msec: 5168 - hash: "5b25d3894a56dc4f4a0aa8f88cb69e23" - } - Frame { - msec: 5184 - hash: "5683ad02f1b9126f4e4ff6b03044fdc6" - } - Frame { - msec: 5200 - hash: "0a3ec255575ec1b70e0b10cf59c7c5fd" - } - Frame { - msec: 5216 - hash: "0f5f46fe3fdf42d4651891f13c8afc7e" - } - Frame { - msec: 5232 - hash: "b6955407245c73e356a460d99dad77be" - } - Frame { - msec: 5248 - hash: "6018b53414921943b37c33fa04a29697" - } - Frame { - msec: 5264 - hash: "ff184d349ce0b648f8c1fce91ae997f6" - } - Frame { - msec: 5280 - hash: "9c112a3a785d970593887eeab72fa7fe" - } - Frame { - msec: 5296 - hash: "00384fb20d4c6cd6236d519d2d734cc3" - } - Frame { - msec: 5312 - hash: "601ea99400e5f50ee9a5a4b74b6f3017" - } - Frame { - msec: 5328 - hash: "9afed04bf7eca24d9b6d31ac84ae59c2" - } - Frame { - msec: 5344 - hash: "1983319c8043bfe403513af7ccb5b924" - } - Frame { - msec: 5360 - hash: "b0244e4e1b61202ede78405415c22bca" - } - Frame { - msec: 5376 - hash: "ec5516b1aaeace8784b04649c51ab40b" - } - Frame { - msec: 5392 - hash: "8ff7d2001594abb588f769bab15406d7" - } - Frame { - msec: 5408 - hash: "64d5fd96a1726aa5276f9b508566676f" - } - Frame { - msec: 5424 - hash: "ab49497a6c825038354f076bdbbbc235" - } - Frame { - msec: 5440 - hash: "6b821e43be932800b20af58a7b5a1ff7" - } - Frame { - msec: 5456 - hash: "683a2902300f930e2a81a82dc37c583b" - } - Frame { - msec: 5472 - hash: "86d7946d7fbb66369ccbf26430939225" - } - Frame { - msec: 5488 - hash: "fb38f5fb6555fc14e95a47c595a6ea0c" - } - Frame { - msec: 5504 - hash: "3878f685d9fa3299e9ffe78c22595387" - } - Frame { - msec: 5520 - hash: "b48840a68ff007901b02332c7177f315" - } - Frame { - msec: 5536 - hash: "9d847abc99220b04aceef12e5c09aac0" - } - Frame { - msec: 5552 - hash: "9893ac89fda64d96ec4140c3c87e17a5" - } - Frame { - msec: 5568 - hash: "cd94e1c36e6be9877cd9c12df42bd968" - } - Frame { - msec: 5584 - hash: "c1ce5e53b74af022dc103ad74ff5f1af" - } - Frame { - msec: 5600 - hash: "b3630e08eac02a9578a00b01baabaaba" - } - Frame { - msec: 5616 - hash: "0eb9241aa1f9526c1e24ba76d630805c" - } - Frame { - msec: 5632 - hash: "1b532ae7f9253469467522d4ca66c47b" - } - Frame { - msec: 5648 - hash: "7e6e49079ed6330da2e337a5e4ffd730" - } - Frame { - msec: 5664 - hash: "0391d668f4b906b244a5f5c1713573c2" - } - Frame { - msec: 5680 - hash: "8070fa3280d0d64bf976d4a276359c4c" - } - Frame { - msec: 5696 - hash: "f7d0d36a2d40c798f56ac7ecc1effca6" - } - Frame { - msec: 5712 - hash: "9f8e35ee5080e811c670c480a9c2bd9f" - } - Frame { - msec: 5728 - hash: "c7fea75a43a59a11aa504df32afcdaf8" - } - Frame { - msec: 5744 - hash: "7e549a93ffc6ddcc3d8111f10c05b29e" - } - Frame { - msec: 5760 - image: "easefollow.5.png" - } - Frame { - msec: 5776 - hash: "92d298262f610a2dafa095e3d67c80af" - } - Frame { - msec: 5792 - hash: "db8826b0b2feece0999863b8827a6234" - } - Frame { - msec: 5808 - hash: "12c7050e8094bb39212aed0163666d1a" - } - Frame { - msec: 5824 - hash: "69531beace5c749bf90160a4b25f736a" - } - Frame { - msec: 5840 - hash: "ce873e4dbc8853183b54d59991b2e030" - } - Frame { - msec: 5856 - hash: "fa1078973634578d69527402b11fb7e0" - } - Frame { - msec: 5872 - hash: "1e3b3db590567c0afd1913101192cda9" - } - Frame { - msec: 5888 - hash: "7b9e097018278b784973a546da3d401a" - } - Frame { - msec: 5904 - hash: "a7b0667093888480de6697280aeea9ba" - } - Frame { - msec: 5920 - hash: "e381f2422ead86575abf643b0b0c9797" - } - Frame { - msec: 5936 - hash: "44b08f5a0de2a6955e02f67753f409c8" - } - Frame { - msec: 5952 - hash: "db04665e58448ecc7f95baa3e4ea79a5" - } - Frame { - msec: 5968 - hash: "0e4aae728d8d543538a9446c41e18e91" - } - Frame { - msec: 5984 - hash: "e3cd1bbb1d9963e5c74d36e526a871b0" - } - Frame { - msec: 6000 - hash: "bcd893a0e200ddda4e1468c159018865" - } - Frame { - msec: 6016 - hash: "9c5293356aa6312f909e655e9bcf961b" - } - Frame { - msec: 6032 - hash: "0bab7b9166f6af554d4fa0badeec739e" - } - Frame { - msec: 6048 - hash: "e74996581f0aaeced118c5cbfd977d90" - } - Frame { - msec: 6064 - hash: "5d128eb20a2a23da8c2d9a35293e5769" - } - Frame { - msec: 6080 - hash: "ebbbc343698287faf7ffa7526a726b54" - } - Frame { - msec: 6096 - hash: "d812172192cc19590f9a2d7dbf970439" - } - Frame { - msec: 6112 - hash: "60263addb1b4b5ac43f8199b8ed77e40" - } - Frame { - msec: 6128 - hash: "702a1ff2876eaaa59359811bb6437c5b" - } - Frame { - msec: 6144 - hash: "8f81dc43decce5094ee7a089f0009730" - } - Frame { - msec: 6160 - hash: "efda5dd9edd83a0da089d0b28806c6b6" - } - Frame { - msec: 6176 - hash: "7274a33a7a5272d7abdaf41f4b2bf664" - } - Frame { - msec: 6192 - hash: "0cc80077476e721a3da85c17cc56a65e" - } - Frame { - msec: 6208 - hash: "e65a534f0e7e70520a9c2cfa09ee8159" - } - Frame { - msec: 6224 - hash: "b05b514c63bd8998785382e6a9cbd849" - } - Frame { - msec: 6240 - hash: "10a04d641e0cc65c120d8bcf2f3e54c8" - } - Frame { - msec: 6256 - hash: "68418e2206a496dd15a05b50fec6f87e" - } - Frame { - msec: 6272 - hash: "6549e0989e1c86e3a7eb0dcc8dd31380" - } - Frame { - msec: 6288 - hash: "bd0193c2cbc8958f674f4ec52a693b72" - } - Frame { - msec: 6304 - hash: "746440b45a3688dbd32b34c57454e956" - } - Frame { - msec: 6320 - hash: "6b54ee8af30be2178e8b3afab5dcb4c7" - } - Frame { - msec: 6336 - hash: "ba2fbad3fe2fe25ec0c0c542659168dc" - } - Frame { - msec: 6352 - hash: "84bd72703bd8200f8f090783d06ae451" - } - Frame { - msec: 6368 - hash: "17c9fb063280c2ee4cb4a13273bbb199" - } - Frame { - msec: 6384 - hash: "df28fd55719f5c2d164596d02c2faff2" - } - Frame { - msec: 6400 - hash: "c2e280e78e892200d40022d17ce695b7" - } - Frame { - msec: 6416 - hash: "c657caa0c5158e178ec5df80bbad6bcb" - } - Frame { - msec: 6432 - hash: "d91f4f6ec6503fe8280f9b02dd11e64a" - } - Frame { - msec: 6448 - hash: "0fb9400cdca9dbd4035fbf8af9952360" - } - Frame { - msec: 6464 - hash: "cac0e1b4aa094306b95f90ede4705391" - } - Frame { - msec: 6480 - hash: "e60a4bb14300a937a767effee931c60f" - } - Frame { - msec: 6496 - hash: "8b461397e3f210ee7e9305dcab2af2db" - } - Frame { - msec: 6512 - hash: "6ce9ec0942dd06c9f73929a7e176852c" - } - Frame { - msec: 6528 - hash: "da36e254635eea854a6552ba008117f9" - } - Frame { - msec: 6544 - hash: "0bec6402b5eb09d05ce8e9ff5253ea8d" - } - Frame { - msec: 6560 - hash: "72f6610527d395ca590eda166ef6bc4e" - } - Frame { - msec: 6576 - hash: "622ae3fd47adb2432e2a40d3c5539393" - } - Frame { - msec: 6592 - hash: "0b18c49e2bbf9370216e06b555faf183" - } - Frame { - msec: 6608 - hash: "0c090bb975fb883301b52479fd6f5fdf" - } - Frame { - msec: 6624 - hash: "c4205d7ecb7327426d9591e77247acab" - } - Frame { - msec: 6640 - hash: "f0e0075243e4b8aa97056248fe6033ed" - } - Frame { - msec: 6656 - hash: "47f99b40a8764ee9d9e429061fb7acb2" - } - Frame { - msec: 6672 - hash: "49e8c1e974b0716570d85109b53817a5" - } - Frame { - msec: 6688 - hash: "72f981bad831b6ed858009527902f734" - } - Frame { - msec: 6704 - hash: "e959a0493b06369a429f90f66cb65977" - } - Frame { - msec: 6720 - image: "easefollow.6.png" - } - Frame { - msec: 6736 - hash: "93470d983282f24425558f47ad705154" - } - Frame { - msec: 6752 - hash: "cdccbe1a7c7abd4a6a6ee754ed0c9759" - } - Frame { - msec: 6768 - hash: "0e1b7b5332a9fcdb492db5314a2a0267" - } - Frame { - msec: 6784 - hash: "1e1ffe3439aab51d0b325474e7d8dc28" - } - Frame { - msec: 6800 - hash: "e8e7e9b5871caf77f15678616d6c9c8a" - } - Frame { - msec: 6816 - hash: "9771fff3b7752154d093c038bea73d28" - } - Frame { - msec: 6832 - hash: "1af851ea214cbddb0e3a743084a5cf6b" - } - Frame { - msec: 6848 - hash: "1566182a7e29bbb738705a90c4909617" - } - Frame { - msec: 6864 - hash: "feed650e1d948fe622234d212fb745f2" - } - Frame { - msec: 6880 - hash: "3cd3d063275b91f9680717421c118ba4" - } - Frame { - msec: 6896 - hash: "c1f088801334762cd499e7cc70e1e59a" - } - Frame { - msec: 6912 - hash: "e8f8d153e7a027a5092a9209411d97f7" - } - Frame { - msec: 6928 - hash: "f11747c3533b4b2fc77a64ca0cace8b0" - } - Frame { - msec: 6944 - hash: "21618c67a2a8bbce86fc872060ad40e8" - } - Frame { - msec: 6960 - hash: "02da96335db74b87ceefe91b1dfe72e6" - } - Frame { - msec: 6976 - hash: "2b2e4143143ead8dea5865fd782f1775" - } - Frame { - msec: 6992 - hash: "13e710900b05e26cdb030b1e2b2be715" - } - Frame { - msec: 7008 - hash: "29e8995d17aac4d02034debcbb9fcb98" - } - Frame { - msec: 7024 - hash: "1099db1b3e4c69e84c6ab1b7c311bf1e" - } - Frame { - msec: 7040 - hash: "cc7cb720043334f1eeb385dce4389dc2" - } - Frame { - msec: 7056 - hash: "34c7a62c1bc7261e2fd31c40068b37a7" - } - Frame { - msec: 7072 - hash: "7fafbe05cbcaa21893e3aa0f1fcfb5a0" - } - Key { - type: 6 - key: 16777249 - modifiers: 67108864 - text: "" - autorep: false - count: 1 - } - Frame { - msec: 7088 - hash: "5b26c8cf047706633795a8ed3e703a89" - } - Frame { - msec: 7104 - hash: "e0774bf9e74d0cde81c5cb216a9258fc" - } - Frame { - msec: 7120 - hash: "0870262f643245e13f4fba79fd575897" - } - Frame { - msec: 7136 - hash: "8faf0d050bb435ade8af5012c1a6b0dc" - } - Frame { - msec: 7152 - hash: "382c037895cc39a6870db57b5016c01f" - } - Frame { - msec: 7168 - hash: "f1f5a2cbc103ab1bee9f537fa8266e03" - } -} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml b/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml deleted file mode 100644 index ee94857..0000000 --- a/tests/auto/declarative/qmlvisual/qdeclarativeeasefollow/easefollow.qml +++ /dev/null @@ -1,45 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 800; height: 240; color: "gray" - - Rectangle { - id: rect - width: 50; height: 20; y: 30; color: "black" - SequentialAnimation on x { - loops: Animation.Infinite - NumberAnimation { from: 50; to: 700; duration: 2000 } - NumberAnimation { from: 700; to: 50; duration: 2000 } - } - } - - Rectangle { - width: 50; height: 20; y: 60; color: "red" - x: rect.x - Behavior on x { SmoothedAnimation { velocity: 400 } } - } - - Rectangle { - width: 50; height: 20; y: 90; color: "yellow" - x: rect.x - Behavior on x { SmoothedAnimation { velocity: 300; reversingMode: SmoothedAnimation.Immediate } } - } - - Rectangle { - width: 50; height: 20; y: 120; color: "green" - x: rect.x - Behavior on x { SmoothedAnimation { reversingMode: SmoothedAnimation.Sync } } - } - - Rectangle { - width: 50; height: 20; y: 150; color: "purple" - x: rect.x - Behavior on x { SmoothedAnimation { maximumEasingTime: 200 } } - } - - Rectangle { - width: 50; height: 20; y: 180; color: "blue" - x: rect.x - Behavior on x { SmoothedAnimation { duration: 300 } } - } -} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.0.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.0.png new file mode 100644 index 0000000..21b6afb Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.0.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.1.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.1.png new file mode 100644 index 0000000..bb8a02b Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.1.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.2.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.2.png new file mode 100644 index 0000000..da60237 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.2.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.3.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.3.png new file mode 100644 index 0000000..3e943e8 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.3.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.4.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.4.png new file mode 100644 index 0000000..4fbaf26 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.4.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.5.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.5.png new file mode 100644 index 0000000..c10d196 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.5.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.6.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.6.png new file mode 100644 index 0000000..a672c06 Binary files /dev/null and b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.6.png differ diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.qml b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.qml new file mode 100644 index 0000000..029a2fc --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/easefollow.qml @@ -0,0 +1,1807 @@ +import Qt.VisualTest 4.6 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + hash: "1f60efdb8704b92c9361daa468a25391" + } + Frame { + msec: 32 + hash: "3bb6a87617e0e5d4922e573eec975886" + } + Frame { + msec: 48 + hash: "268941737e6324d580890b151de621fb" + } + Frame { + msec: 64 + hash: "99c674eccc082d7f0982257a748d93e5" + } + Frame { + msec: 80 + hash: "2970467e8262c8a3f0b11be71245d048" + } + Frame { + msec: 96 + hash: "63cbd06d6bb035d27c18dba49238d8b2" + } + Frame { + msec: 112 + hash: "49f77bb3d323f882c0ec56e1f1040b3a" + } + Frame { + msec: 128 + hash: "40263c5f9b5d2236536163785f832b4d" + } + Frame { + msec: 144 + hash: "dc63b1c21a2027c4beb9c297a3677fbd" + } + Frame { + msec: 160 + hash: "4fab52ea29a819fec032f19dbcbef012" + } + Frame { + msec: 176 + hash: "60b48407a8f8ae2cce7d3e7c8b21991c" + } + Frame { + msec: 192 + hash: "6e542c681092a5ebeef0534fa2bd2d6c" + } + Frame { + msec: 208 + hash: "c7c6471969bbf81efdb86d1695548fc6" + } + Frame { + msec: 224 + hash: "b7f4ad9a49feb400894209c02b94478a" + } + Frame { + msec: 240 + hash: "3eb58b2f5233aead976183c13f241113" + } + Frame { + msec: 256 + hash: "54f2036c50c6d8079fc0cadc01385980" + } + Frame { + msec: 272 + hash: "f297659d75f6e724d72bd548821f4c9f" + } + Frame { + msec: 288 + hash: "112798f080336fc9c603a7e9097dd8aa" + } + Frame { + msec: 304 + hash: "c432e6ec2b53ca43cb7a7325d0cc379b" + } + Frame { + msec: 320 + hash: "4a6d3db3efd665ad7f372bf3f2508ed7" + } + Frame { + msec: 336 + hash: "0befa5dc4d2cc196fed0eb1a3aa75b8f" + } + Frame { + msec: 352 + hash: "a34d010b50d59c362b54e44d69c2df91" + } + Frame { + msec: 368 + hash: "cbdacced50186c87066ce1d46548b27e" + } + Frame { + msec: 384 + hash: "a4060010ae4d3c0973bda48d68f7bd0a" + } + Frame { + msec: 400 + hash: "47353437da587f732f986004c09884d0" + } + Frame { + msec: 416 + hash: "080c348145167bbec671a04da6f7564f" + } + Frame { + msec: 432 + hash: "69dead737c717a076ae3865680341fb4" + } + Frame { + msec: 448 + hash: "1efdc31c5c8fa72fc848877deb6caaa4" + } + Frame { + msec: 464 + hash: "28d7da1e933d0585d03acf4a529e7b42" + } + Frame { + msec: 480 + hash: "bf85534124bf025b7ede0d6c80b8e443" + } + Frame { + msec: 496 + hash: "cdbeb2d51541b1b1eff060efe993db91" + } + Frame { + msec: 512 + hash: "52ad56ae16c8ab523adda8edc512dd87" + } + Frame { + msec: 528 + hash: "61b1937f4c8dd2cb0ddd7031c5bfb3ab" + } + Frame { + msec: 544 + hash: "1b109baba71b16827f90da654af093a3" + } + Frame { + msec: 560 + hash: "d56621362802c8626868f36ba1e7db22" + } + Frame { + msec: 576 + hash: "ee5555ec3ad8760f43bbf5958a925936" + } + Frame { + msec: 592 + hash: "1ed2831144a453af1978605c0e42d17c" + } + Frame { + msec: 608 + hash: "c74d5cdb3395a702269dfa88c8c9d975" + } + Frame { + msec: 624 + hash: "ea98ddd9588cc23fd82a342ec2925ba8" + } + Frame { + msec: 640 + hash: "e76b94d6d57f1a510f7649eaab892562" + } + Frame { + msec: 656 + hash: "022f40b6fe9dbaf8019855234acb3461" + } + Frame { + msec: 672 + hash: "467da4f48aa6aeb113f0797facf157e8" + } + Frame { + msec: 688 + hash: "8df407aadd4d896eb6537e1555a0242f" + } + Frame { + msec: 704 + hash: "122e4671881e31f54e617729f4fbb3b0" + } + Frame { + msec: 720 + hash: "562718f101c3cd7525b890076413df5e" + } + Frame { + msec: 736 + hash: "07feae99ecf4b70eb094fd3e10deca56" + } + Frame { + msec: 752 + hash: "0980d133b1006cc07796023880415163" + } + Frame { + msec: 768 + hash: "7112b6ac97678b3b942c64c5108f0329" + } + Frame { + msec: 784 + hash: "bb9f893a9aaee60ab6c30918552828a4" + } + Frame { + msec: 800 + hash: "65d1f29437aaaea33676757276f1e434" + } + Frame { + msec: 816 + hash: "52adcf2509f3236ac8ef571708e77206" + } + Frame { + msec: 832 + hash: "22df5e7eda8a813531d0e0366cbfbf64" + } + Frame { + msec: 848 + hash: "fe9b7b7812dd2410b8ed2eb19aa78f4d" + } + Frame { + msec: 864 + hash: "141e22de4469f316b5ef5471f3c7bba0" + } + Frame { + msec: 880 + hash: "1125c0a105fc4a2cae36b798058ce23f" + } + Frame { + msec: 896 + hash: "8c17c5da2ae867fb0016a485ba9e4166" + } + Frame { + msec: 912 + hash: "d8da9fc7ec4dcefb894c5a6a71e9d001" + } + Frame { + msec: 928 + hash: "00ff642bea89fd89de394d78f8c5db33" + } + Frame { + msec: 944 + hash: "8549063d517a3ce1ffd44c56b3b6cf5e" + } + Frame { + msec: 960 + image: "easefollow.0.png" + } + Frame { + msec: 976 + hash: "95a642caa72bb31cc1e04ecc12d07cd0" + } + Frame { + msec: 992 + hash: "e65c823476bf920d0386f62ca831e6a0" + } + Frame { + msec: 1008 + hash: "91e8913dc693c91a674a10b5b088dd8f" + } + Frame { + msec: 1024 + hash: "1a469ffa0d530f72c78dc14783891c78" + } + Frame { + msec: 1040 + hash: "6e46a83d07f8bc034b421103ef0e4f8c" + } + Frame { + msec: 1056 + hash: "8ddacab411a8b73b6c9e69576fa1b003" + } + Frame { + msec: 1072 + hash: "41f419a85fe44efe27c9a526d83a1e9a" + } + Frame { + msec: 1088 + hash: "73d4ece31b258f9caf4556ce20a5be1f" + } + Frame { + msec: 1104 + hash: "ef3ebe0acb50386cf79b9f08fbba2fbc" + } + Frame { + msec: 1120 + hash: "c11a84d2fa80f28adb1466409812e987" + } + Frame { + msec: 1136 + hash: "2e9db854b02d28b38063ff2a8e821ed1" + } + Frame { + msec: 1152 + hash: "48e073c0e6b19aea8314629a2179af87" + } + Frame { + msec: 1168 + hash: "77e518b7428d93b67a8fb0d33d85ed97" + } + Frame { + msec: 1184 + hash: "1d18323af9c62e015513451883f8b39f" + } + Frame { + msec: 1200 + hash: "df49889ba157cdc1ca240d08d2760ad7" + } + Frame { + msec: 1216 + hash: "7b8cd2bcf0a4c38ab870f27894a43d2f" + } + Frame { + msec: 1232 + hash: "84f10e0c9fd57dd1799df7fc34c5ef01" + } + Frame { + msec: 1248 + hash: "ead4e609bc4a0755032b1648485b9625" + } + Frame { + msec: 1264 + hash: "9a9829c3bd4a3a4155383c37e21e8db8" + } + Frame { + msec: 1280 + hash: "5008917f60256abad867f32c1caf954d" + } + Frame { + msec: 1296 + hash: "c21455d66ed0754177af5ce44b7c7600" + } + Frame { + msec: 1312 + hash: "e8332f2586d80a2700b610e8fe5c72d9" + } + Frame { + msec: 1328 + hash: "0d0c8af138f98bae8a370ebec4a4796c" + } + Frame { + msec: 1344 + hash: "04065e8feeb900d18deeb941572f7f10" + } + Frame { + msec: 1360 + hash: "992a225b1f25bf5b21dd7f8a55dc4b70" + } + Frame { + msec: 1376 + hash: "8ef739d91ee2a4337cbfc3dc94ce9845" + } + Frame { + msec: 1392 + hash: "46744977a26b37ab65e65e1891ceafe7" + } + Frame { + msec: 1408 + hash: "1b4c0d79eeb8d6b2e30172f3664407b9" + } + Frame { + msec: 1424 + hash: "d572831ed34d14d1125570b8b8767bdb" + } + Frame { + msec: 1440 + hash: "8b785c756d11e0fc18959d0897a45673" + } + Frame { + msec: 1456 + hash: "164a71ffcea63ceb6c1ebeb8d0d07af1" + } + Frame { + msec: 1472 + hash: "e128dc12d5117eed9f7c0a16e8348ba2" + } + Frame { + msec: 1488 + hash: "4c7db5b12d83bf22b1c88ac06ca7c385" + } + Frame { + msec: 1504 + hash: "c7283df8dbd78121e17a5893e3ea4f3c" + } + Frame { + msec: 1520 + hash: "fea768e5bb43f6d86d88ced9f73915de" + } + Frame { + msec: 1536 + hash: "b99b54f8e75452c539bb4e7b6a36e944" + } + Frame { + msec: 1552 + hash: "b7274938d16f03b376ad9739e2e893f1" + } + Frame { + msec: 1568 + hash: "e61601942193add8c1c8ebf5c5319932" + } + Frame { + msec: 1584 + hash: "8fdc2181e0120391505706716ba7e5d7" + } + Frame { + msec: 1600 + hash: "66f737ed28453da5175d6b5e807c374d" + } + Frame { + msec: 1616 + hash: "2e00a7895d61edbe794f0a8000871b30" + } + Frame { + msec: 1632 + hash: "1a279fc6b7c4105eccc4e3bc99481bef" + } + Frame { + msec: 1648 + hash: "bc1dea4d23ca9bc29b72a8c2bde4787b" + } + Frame { + msec: 1664 + hash: "8ef40e0be5fb82b32b365b3d4b85421d" + } + Frame { + msec: 1680 + hash: "ee37c68bf38d5eed4e3e9a31306f6801" + } + Frame { + msec: 1696 + hash: "303d760c87a7a833606c8e9f46cb5fc0" + } + Frame { + msec: 1712 + hash: "cc2563b47c58efd39bec6b4e0f2995bb" + } + Frame { + msec: 1728 + hash: "33f7daf09497510475283d6dc7c51228" + } + Frame { + msec: 1744 + hash: "5b5e2de9934c80bd49e0eb7afd85151d" + } + Frame { + msec: 1760 + hash: "5e6bf706336789ca6b60a82998b70113" + } + Frame { + msec: 1776 + hash: "b4d4a860f49bfb88dd2079862b40b7ec" + } + Frame { + msec: 1792 + hash: "07b571fa55327487e34a592c778beb67" + } + Frame { + msec: 1808 + hash: "cb5b349a536cf75a83734181b3eab92b" + } + Frame { + msec: 1824 + hash: "ce903bb58c5c86f2955e68412893aedf" + } + Frame { + msec: 1840 + hash: "ffa89e879558c83ed538812a93e2fe29" + } + Frame { + msec: 1856 + hash: "562aa66bf537853be82a654542c8b80e" + } + Frame { + msec: 1872 + hash: "dc45dac0cc20220bcc81210fb5506ee2" + } + Frame { + msec: 1888 + hash: "3b429eb827df0800a1ad8b906ea32ef9" + } + Frame { + msec: 1904 + hash: "d6ebaf12515d9e24cdbf6d75080c0b28" + } + Frame { + msec: 1920 + image: "easefollow.1.png" + } + Frame { + msec: 1936 + hash: "9f6d26224055c809dc2f3490cd0ff880" + } + Frame { + msec: 1952 + hash: "5630cc8f0b401f7d81bdceaaae5cce68" + } + Frame { + msec: 1968 + hash: "dafda60467e5e2b99c41543dd191ac2d" + } + Frame { + msec: 1984 + hash: "e053cb07a734278cd111d612883c165e" + } + Frame { + msec: 2000 + hash: "63870f3e99c11707004dab9439d61389" + } + Frame { + msec: 2016 + hash: "14c311a6fab45f828c3a19535ea9edc8" + } + Frame { + msec: 2032 + hash: "13e614446cbfcbfd2a7ecc5f0e8688df" + } + Frame { + msec: 2048 + hash: "173c97f59da05b9347180a4824e60c06" + } + Frame { + msec: 2064 + hash: "932e2a9bbcb7dc5befca8f63d8fa3c95" + } + Frame { + msec: 2080 + hash: "4b8f232ffe0cbc7f900de5737c9f95be" + } + Frame { + msec: 2096 + hash: "9686d294d4e931a5eed0e6b5bda63377" + } + Frame { + msec: 2112 + hash: "969c569d92e3ec51dfbdd20d64432224" + } + Frame { + msec: 2128 + hash: "0cef3550cca9fb5611b836098c517dd1" + } + Frame { + msec: 2144 + hash: "6728080a09aa5d48462a3abb8e285e8a" + } + Frame { + msec: 2160 + hash: "4b904dc671b7fc72db0b6e52543e96bd" + } + Frame { + msec: 2176 + hash: "38232f89dffc9b16db6ea60b02f8d1be" + } + Frame { + msec: 2192 + hash: "6b41f2a0f950eddad217a03e137f9a9b" + } + Frame { + msec: 2208 + hash: "be576ea74c2c404da46fcf1d22de6df9" + } + Frame { + msec: 2224 + hash: "3f44bad4b51ceff2944337064a5efa91" + } + Frame { + msec: 2240 + hash: "e1ab98ac1366e9fd8af62a6a26878c73" + } + Frame { + msec: 2256 + hash: "bd131e1725a54b3dbbb86a29ca8a56a9" + } + Frame { + msec: 2272 + hash: "4d3e8af70f228643803f780c4e36f1a6" + } + Frame { + msec: 2288 + hash: "853a5ab4271af7a7638454cfa883aa33" + } + Frame { + msec: 2304 + hash: "ede9260157000f346900153ce2409278" + } + Frame { + msec: 2320 + hash: "b2b16d8ce1ba89f0d9558ac387e25c3d" + } + Frame { + msec: 2336 + hash: "387d338910453637c5cf80fa35528e56" + } + Frame { + msec: 2352 + hash: "26deabf9cdd994455f2a8802eb0e04dc" + } + Frame { + msec: 2368 + hash: "13939659a315dae1b81e3ea166102edf" + } + Frame { + msec: 2384 + hash: "be92b55bb7562372401b25a9167abb2b" + } + Frame { + msec: 2400 + hash: "ee7bf60d7ee97b7de5e909b9af88df80" + } + Frame { + msec: 2416 + hash: "434313a3bcd1d7582b0d89b9a145ef09" + } + Frame { + msec: 2432 + hash: "0857ca59a283897e3df62b9633488f83" + } + Frame { + msec: 2448 + hash: "76718fc7e3d21b54930bc8307a57733a" + } + Frame { + msec: 2464 + hash: "93a91588b38129053a462b920fd686e3" + } + Frame { + msec: 2480 + hash: "2a2486c52fde915696fd8cbd3682e8db" + } + Frame { + msec: 2496 + hash: "b1f4ab6cc5fb4a3a1b4885f2d1b29277" + } + Frame { + msec: 2512 + hash: "4258afce8a85a2e9ead149e34b43d8fc" + } + Frame { + msec: 2528 + hash: "6672c71b98e13d51ebb523aed9036a72" + } + Frame { + msec: 2544 + hash: "eaa39af7eb78948f433e3b44a9454317" + } + Frame { + msec: 2560 + hash: "0a766bc97bea67d4b848c703eaa6777a" + } + Frame { + msec: 2576 + hash: "0b461ec1885ede1dd96b71cf38bfd3d6" + } + Frame { + msec: 2592 + hash: "15efc929370a3864529080e30db1026a" + } + Frame { + msec: 2608 + hash: "e1529e30ff1e4ea1b092a88e85f2f1f6" + } + Frame { + msec: 2624 + hash: "f29bd9dbf7317e94b885da63f0cb7374" + } + Frame { + msec: 2640 + hash: "e5294e087e2ce0d7d936c0129b6c37ae" + } + Frame { + msec: 2656 + hash: "9c63129e774b391cc398cf5da5c9339c" + } + Frame { + msec: 2672 + hash: "4371d85854419d4b00671176bb7c5a2b" + } + Frame { + msec: 2688 + hash: "dd10b3f50e2fdc56c75f00321634b1cc" + } + Frame { + msec: 2704 + hash: "aac6256b21152a5f1f8c576b667d275e" + } + Frame { + msec: 2720 + hash: "c937c44037b2228590d334df4d56a86f" + } + Frame { + msec: 2736 + hash: "f6c714db51cbd1bdb737afe612c33f9c" + } + Frame { + msec: 2752 + hash: "0bba45af79f3201bc7cf042d5c648f73" + } + Frame { + msec: 2768 + hash: "941b08ddbafea3bd46262c060b1e290b" + } + Frame { + msec: 2784 + hash: "d898918dc2023de239b4ab38f7420960" + } + Frame { + msec: 2800 + hash: "d1a16dc2282329113093d06862e7a871" + } + Frame { + msec: 2816 + hash: "bba5359475f643fbeee240e71e843d4c" + } + Frame { + msec: 2832 + hash: "03cf861f4b6bc767e723e47e95c2448b" + } + Frame { + msec: 2848 + hash: "a64bf158c6199b88bc2db3b741d342f0" + } + Frame { + msec: 2864 + hash: "cf0fe7cb42ba842f1c28c1211adb768d" + } + Frame { + msec: 2880 + image: "easefollow.2.png" + } + Frame { + msec: 2896 + hash: "9b3c6414e4ef5a452a5c92bb0b893fc3" + } + Frame { + msec: 2912 + hash: "7cc7ddec3ac2d8cac33c0b0f80a7544d" + } + Frame { + msec: 2928 + hash: "7dd4e7d606e953c872c57fad786d64aa" + } + Frame { + msec: 2944 + hash: "117cc903a39d99ca22f6556095e6f883" + } + Frame { + msec: 2960 + hash: "c6c9304fd65fee1909473bdb21ac7806" + } + Frame { + msec: 2976 + hash: "8e704fe81c040f49c4d80e7dcc46084d" + } + Frame { + msec: 2992 + hash: "d202d5c0a058e1e088fdd280e59f17bb" + } + Frame { + msec: 3008 + hash: "90c072dea32c056f8bd6d010df681929" + } + Frame { + msec: 3024 + hash: "80b4e99f1b47e64084e295a2a3e1121e" + } + Frame { + msec: 3040 + hash: "41d6307075ec9ae9e92d227921f71289" + } + Frame { + msec: 3056 + hash: "f33de23cf4a5c4881310c6866261d387" + } + Frame { + msec: 3072 + hash: "441faa0a1fc95d66b27479dfc1e40188" + } + Frame { + msec: 3088 + hash: "2314b5f6ba3864abd5e87bc87bd621b0" + } + Frame { + msec: 3104 + hash: "e71e3b0ad953258ceef3101e38283fdb" + } + Frame { + msec: 3120 + hash: "890c3b0e727f136bf1ccc486531c9677" + } + Frame { + msec: 3136 + hash: "2a0d23e6dcc6475c323dbf8eb36e8094" + } + Frame { + msec: 3152 + hash: "692682e82347936f87a66484b428e959" + } + Frame { + msec: 3168 + hash: "cf4005c08789762ad21be1a1d78755c9" + } + Frame { + msec: 3184 + hash: "566184563091626bb20ae679e3ce3b91" + } + Frame { + msec: 3200 + hash: "f88a24ad3bbc2699924bb9a7ff6490b3" + } + Frame { + msec: 3216 + hash: "23f3f63d07b2bdc2b82ff4e8606a634d" + } + Frame { + msec: 3232 + hash: "fe121c71ce469ec6f0bf957eb2f0447b" + } + Frame { + msec: 3248 + hash: "ba217690a33c701afe11842aa8105cbb" + } + Frame { + msec: 3264 + hash: "e5c7c1323108f13ba26f5198cc62c137" + } + Frame { + msec: 3280 + hash: "664f76d3d0008b56be2790c470befc91" + } + Frame { + msec: 3296 + hash: "b3f54070ba64b983ccd2a15941ef4c35" + } + Frame { + msec: 3312 + hash: "8a0ba2ae36ad3811778f3a3bc55743f5" + } + Frame { + msec: 3328 + hash: "bfdc71733ca45a2ba2e8abf751554a62" + } + Frame { + msec: 3344 + hash: "686e4d7bb5ae148d37fc2a1f6004a33a" + } + Frame { + msec: 3360 + hash: "29c553d9fe42fdbbd019d0ead61dffa0" + } + Frame { + msec: 3376 + hash: "bfa2b72c6554a2ed80a3b86f2cbed986" + } + Frame { + msec: 3392 + hash: "074ff90417a947f0a04926d5675d073b" + } + Frame { + msec: 3408 + hash: "6f56f9e0aa40149156ca71d6f8d4476a" + } + Frame { + msec: 3424 + hash: "950ce749bbf572021de2dd1688cb87e6" + } + Frame { + msec: 3440 + hash: "2d0903bd71862dc6f28bd702d955ae99" + } + Frame { + msec: 3456 + hash: "2733adae56728f1b744a4086ecb98052" + } + Frame { + msec: 3472 + hash: "779859d739e799bba15beeb97d18e682" + } + Frame { + msec: 3488 + hash: "9074386cfabe136b8839637e5cd58f57" + } + Frame { + msec: 3504 + hash: "fa5bcbf20c6ad0a218f23d98961229a1" + } + Frame { + msec: 3520 + hash: "5406c94da1717eaa5eb0010564216059" + } + Frame { + msec: 3536 + hash: "27d0a3c3a33c04df843bebd72ef79824" + } + Frame { + msec: 3552 + hash: "270df9c99c2679071b854b3d82337f79" + } + Frame { + msec: 3568 + hash: "5b3945505443a67e7a91f66fe42b4fe3" + } + Frame { + msec: 3584 + hash: "9a2f8565c354cb366725368ed323ccf4" + } + Frame { + msec: 3600 + hash: "6702cb7ccd61c008b511932d7bd5d107" + } + Frame { + msec: 3616 + hash: "f6b86c3a1cc88357f588b6dae11aae30" + } + Frame { + msec: 3632 + hash: "b10c23937f420db72af8abaf126f71c2" + } + Frame { + msec: 3648 + hash: "7d6b0810ffc6e488c8168e19bccb7358" + } + Frame { + msec: 3664 + hash: "c01ef69ec46391909619434e9d9dd0ce" + } + Frame { + msec: 3680 + hash: "a046464fccb0c5ba1f63f8b569821a44" + } + Frame { + msec: 3696 + hash: "8763c526924d882438f9aa9bfb4fe87d" + } + Frame { + msec: 3712 + hash: "dede7a62d6e5c10e8f30caa075bd8dfd" + } + Frame { + msec: 3728 + hash: "3b408e5c986f5bb01d8c3949876b792f" + } + Frame { + msec: 3744 + hash: "0a458f3b17cdd3ea85522779c9346af9" + } + Frame { + msec: 3760 + hash: "fef521f0301cce90af88d37e6d441ec8" + } + Frame { + msec: 3776 + hash: "3d083e0822242b3b37c6839ca91a1f68" + } + Frame { + msec: 3792 + hash: "f8fe013a717e6e61830137bdc78a8b40" + } + Frame { + msec: 3808 + hash: "0ae80ad65dd194043500fa50b5a547a6" + } + Frame { + msec: 3824 + hash: "a53c67fa32ef971eaea202fa5d8a6ad6" + } + Frame { + msec: 3840 + image: "easefollow.3.png" + } + Frame { + msec: 3856 + hash: "41f86bbf0658b127f01e8d46d7ec941b" + } + Frame { + msec: 3872 + hash: "d20f21df127565f9eb87c5d759a638d9" + } + Frame { + msec: 3888 + hash: "85ff94f03cea3e111807e90d062c1367" + } + Frame { + msec: 3904 + hash: "aa637850fe5f05a71ac4c7d31dbb36ee" + } + Frame { + msec: 3920 + hash: "c86a67096c5e62bb73b785cdf6a5b6b1" + } + Frame { + msec: 3936 + hash: "9d53537f2c50a0016bf7bb522b2ec3d8" + } + Frame { + msec: 3952 + hash: "b48630c27c27785ddce568a85d4dc58f" + } + Frame { + msec: 3968 + hash: "01c1bdb6e261cc509f26712b13eeb554" + } + Frame { + msec: 3984 + hash: "af8a44284695fd999acd5944434f0372" + } + Frame { + msec: 4000 + hash: "b156d9d6d5163f007ac4a309d8927ae9" + } + Frame { + msec: 4016 + hash: "2df3715416c3c005f04b66fe1258c0d8" + } + Frame { + msec: 4032 + hash: "96b4a7c6b8542b50fc345b54d38ec82a" + } + Frame { + msec: 4048 + hash: "7e62e757fafa06833444c3a7e1d96ce4" + } + Frame { + msec: 4064 + hash: "5222a8f9366c7d974d0687d05d229069" + } + Frame { + msec: 4080 + hash: "ec96169f4633c3bddfd582feeb8e9ad4" + } + Frame { + msec: 4096 + hash: "cb10db893d1e1cb2a370507dc5679985" + } + Frame { + msec: 4112 + hash: "d7e346c2ac77796bde639bd829b72e85" + } + Frame { + msec: 4128 + hash: "ba5bea8857e4fb444bedd3873563e7db" + } + Frame { + msec: 4144 + hash: "05556fba5d1714f70fd6c2bfb43d213b" + } + Frame { + msec: 4160 + hash: "aeeabf35f9759f045a670a9b9f90dc68" + } + Frame { + msec: 4176 + hash: "131bd453f4c7726e5fdd546252700e2e" + } + Frame { + msec: 4192 + hash: "7c5c3b5bb7a4082e6b9b43640e29f4e2" + } + Frame { + msec: 4208 + hash: "07515e21b7a7895f333e4a8bbd2202eb" + } + Frame { + msec: 4224 + hash: "6cf136f223ac6edd39ba6ed9b4445884" + } + Frame { + msec: 4240 + hash: "84264f5745add8a922101735ed8def84" + } + Frame { + msec: 4256 + hash: "660863d1e4b361f2e5445b417be0d2ad" + } + Frame { + msec: 4272 + hash: "7ceb86f4b16546370d72164d0ca3147c" + } + Frame { + msec: 4288 + hash: "a13e97da9722545ad87ac3c5eb92c497" + } + Frame { + msec: 4304 + hash: "5896b5307cbd609d2062d3607786d40c" + } + Frame { + msec: 4320 + hash: "c8c511115394116e4544c67f615ea5d5" + } + Frame { + msec: 4336 + hash: "59ca5fdf12a735e5c292901b54acccb2" + } + Frame { + msec: 4352 + hash: "155cce2738d34e0eac86f5eb63d638f0" + } + Frame { + msec: 4368 + hash: "83a840c3ae7dbd9a05c17fdd8be07d7a" + } + Frame { + msec: 4384 + hash: "800a15de28b14d88f0ad58fc3f4a2520" + } + Frame { + msec: 4400 + hash: "c8381439a3cd3f9e7f80061023723a6e" + } + Frame { + msec: 4416 + hash: "e3d63000db4b9458b202dece49d1bdba" + } + Frame { + msec: 4432 + hash: "c943e56781695798f3c221f8ab09681a" + } + Frame { + msec: 4448 + hash: "1137ee66d7fbf5a84c33f5ffff15b3dd" + } + Frame { + msec: 4464 + hash: "5a98013cc4462aad18cad8d941f77aa0" + } + Frame { + msec: 4480 + hash: "d0b3748fb49a13c0ad9a68b0e2914921" + } + Frame { + msec: 4496 + hash: "12113f71f9117670acbd7877edded7e0" + } + Frame { + msec: 4512 + hash: "22983424da08cdae7a9c6a8905b37736" + } + Frame { + msec: 4528 + hash: "b2db5618a025cefb2650124c81880c49" + } + Frame { + msec: 4544 + hash: "84fb5e7edc5b42163a83e0cd362b3a46" + } + Frame { + msec: 4560 + hash: "39d6f1ed0f60a0c366c22e1442c455ac" + } + Frame { + msec: 4576 + hash: "702367f6e4aaa2a862e57f9e02a08758" + } + Frame { + msec: 4592 + hash: "ecc75293bc156c560d55cb7d278a4e58" + } + Frame { + msec: 4608 + hash: "e68af8e97ce65376fd7904e599440c92" + } + Frame { + msec: 4624 + hash: "75fe9f766d6cf636cd72d8879a461439" + } + Frame { + msec: 4640 + hash: "162aef147ef4bbb0cd92bd70e4f37f62" + } + Frame { + msec: 4656 + hash: "d879aae8949976c7bad4d97f1e5b5549" + } + Frame { + msec: 4672 + hash: "8a983d7228190721f988de2d72cb3aa2" + } + Frame { + msec: 4688 + hash: "a4f3c63fde664d128cd35b129a4f9a23" + } + Frame { + msec: 4704 + hash: "115fb5f3c9b7f1c28ab379596faba91c" + } + Frame { + msec: 4720 + hash: "ea9600c4d6c77a3b32e59401aa84fe96" + } + Frame { + msec: 4736 + hash: "bd6531fdd9cfd46af2df73bacb31f4c5" + } + Frame { + msec: 4752 + hash: "33bdcf1df50eab5e7963c649fbd32226" + } + Frame { + msec: 4768 + hash: "236e88fb72369a55f9eba4b50712ae85" + } + Frame { + msec: 4784 + hash: "5eb3c14a6296fb3a1c58603b2fc937c8" + } + Frame { + msec: 4800 + image: "easefollow.4.png" + } + Frame { + msec: 4816 + hash: "31d11a1ce6422524241c77603fe53e61" + } + Frame { + msec: 4832 + hash: "44e8b9947026c10b922c84883dd8e889" + } + Frame { + msec: 4848 + hash: "d049e4f7c4bc1849398859a4d630c1b3" + } + Frame { + msec: 4864 + hash: "e83b4757898e4eeef74be8213619fbfa" + } + Frame { + msec: 4880 + hash: "d08f40615f2d5abc6236e856a67575dd" + } + Frame { + msec: 4896 + hash: "d9cb26bf1b8bbafb2aed8f74bd454077" + } + Frame { + msec: 4912 + hash: "aa321b94a6cc53b2ebac80e834c0a908" + } + Frame { + msec: 4928 + hash: "48da37164be156b67a4b3b14e50f2375" + } + Frame { + msec: 4944 + hash: "f522ce7728a4a9e7fad86c72f29bd8f9" + } + Frame { + msec: 4960 + hash: "9bc1d16b4bda596702a3d8a3fad8a5c5" + } + Frame { + msec: 4976 + hash: "5275dccf18745dec6c59b846de17d9ef" + } + Frame { + msec: 4992 + hash: "4eb6babc177b96f69b148d52f56d82d7" + } + Frame { + msec: 5008 + hash: "ccdfb454070ac04c4fe4f3513c52f8c8" + } + Frame { + msec: 5024 + hash: "07f6adad6e8ff4f0eff92c758636a951" + } + Frame { + msec: 5040 + hash: "241e0ad9218d49be477509e008e45548" + } + Frame { + msec: 5056 + hash: "151a482e821779da8a61063f1cc73f8c" + } + Frame { + msec: 5072 + hash: "1499d207c5a3a9bc7bbb84d9c5e35578" + } + Frame { + msec: 5088 + hash: "c253753f653157a5058ef071f16b8bbb" + } + Frame { + msec: 5104 + hash: "ec9fea5a870724a106b952edef7fb466" + } + Frame { + msec: 5120 + hash: "99b673f8ed049d31a2aecabcc46d841d" + } + Frame { + msec: 5136 + hash: "61e77fea693ea55aafbdc94c40c3ab33" + } + Frame { + msec: 5152 + hash: "53e44a3732ee6858d5bd596b4c5d5305" + } + Frame { + msec: 5168 + hash: "5b25d3894a56dc4f4a0aa8f88cb69e23" + } + Frame { + msec: 5184 + hash: "5683ad02f1b9126f4e4ff6b03044fdc6" + } + Frame { + msec: 5200 + hash: "0a3ec255575ec1b70e0b10cf59c7c5fd" + } + Frame { + msec: 5216 + hash: "0f5f46fe3fdf42d4651891f13c8afc7e" + } + Frame { + msec: 5232 + hash: "b6955407245c73e356a460d99dad77be" + } + Frame { + msec: 5248 + hash: "6018b53414921943b37c33fa04a29697" + } + Frame { + msec: 5264 + hash: "ff184d349ce0b648f8c1fce91ae997f6" + } + Frame { + msec: 5280 + hash: "9c112a3a785d970593887eeab72fa7fe" + } + Frame { + msec: 5296 + hash: "00384fb20d4c6cd6236d519d2d734cc3" + } + Frame { + msec: 5312 + hash: "601ea99400e5f50ee9a5a4b74b6f3017" + } + Frame { + msec: 5328 + hash: "9afed04bf7eca24d9b6d31ac84ae59c2" + } + Frame { + msec: 5344 + hash: "1983319c8043bfe403513af7ccb5b924" + } + Frame { + msec: 5360 + hash: "b0244e4e1b61202ede78405415c22bca" + } + Frame { + msec: 5376 + hash: "ec5516b1aaeace8784b04649c51ab40b" + } + Frame { + msec: 5392 + hash: "8ff7d2001594abb588f769bab15406d7" + } + Frame { + msec: 5408 + hash: "64d5fd96a1726aa5276f9b508566676f" + } + Frame { + msec: 5424 + hash: "ab49497a6c825038354f076bdbbbc235" + } + Frame { + msec: 5440 + hash: "6b821e43be932800b20af58a7b5a1ff7" + } + Frame { + msec: 5456 + hash: "683a2902300f930e2a81a82dc37c583b" + } + Frame { + msec: 5472 + hash: "86d7946d7fbb66369ccbf26430939225" + } + Frame { + msec: 5488 + hash: "fb38f5fb6555fc14e95a47c595a6ea0c" + } + Frame { + msec: 5504 + hash: "3878f685d9fa3299e9ffe78c22595387" + } + Frame { + msec: 5520 + hash: "b48840a68ff007901b02332c7177f315" + } + Frame { + msec: 5536 + hash: "9d847abc99220b04aceef12e5c09aac0" + } + Frame { + msec: 5552 + hash: "9893ac89fda64d96ec4140c3c87e17a5" + } + Frame { + msec: 5568 + hash: "cd94e1c36e6be9877cd9c12df42bd968" + } + Frame { + msec: 5584 + hash: "c1ce5e53b74af022dc103ad74ff5f1af" + } + Frame { + msec: 5600 + hash: "b3630e08eac02a9578a00b01baabaaba" + } + Frame { + msec: 5616 + hash: "0eb9241aa1f9526c1e24ba76d630805c" + } + Frame { + msec: 5632 + hash: "1b532ae7f9253469467522d4ca66c47b" + } + Frame { + msec: 5648 + hash: "7e6e49079ed6330da2e337a5e4ffd730" + } + Frame { + msec: 5664 + hash: "0391d668f4b906b244a5f5c1713573c2" + } + Frame { + msec: 5680 + hash: "8070fa3280d0d64bf976d4a276359c4c" + } + Frame { + msec: 5696 + hash: "f7d0d36a2d40c798f56ac7ecc1effca6" + } + Frame { + msec: 5712 + hash: "9f8e35ee5080e811c670c480a9c2bd9f" + } + Frame { + msec: 5728 + hash: "c7fea75a43a59a11aa504df32afcdaf8" + } + Frame { + msec: 5744 + hash: "7e549a93ffc6ddcc3d8111f10c05b29e" + } + Frame { + msec: 5760 + image: "easefollow.5.png" + } + Frame { + msec: 5776 + hash: "92d298262f610a2dafa095e3d67c80af" + } + Frame { + msec: 5792 + hash: "db8826b0b2feece0999863b8827a6234" + } + Frame { + msec: 5808 + hash: "12c7050e8094bb39212aed0163666d1a" + } + Frame { + msec: 5824 + hash: "69531beace5c749bf90160a4b25f736a" + } + Frame { + msec: 5840 + hash: "ce873e4dbc8853183b54d59991b2e030" + } + Frame { + msec: 5856 + hash: "fa1078973634578d69527402b11fb7e0" + } + Frame { + msec: 5872 + hash: "1e3b3db590567c0afd1913101192cda9" + } + Frame { + msec: 5888 + hash: "7b9e097018278b784973a546da3d401a" + } + Frame { + msec: 5904 + hash: "a7b0667093888480de6697280aeea9ba" + } + Frame { + msec: 5920 + hash: "e381f2422ead86575abf643b0b0c9797" + } + Frame { + msec: 5936 + hash: "44b08f5a0de2a6955e02f67753f409c8" + } + Frame { + msec: 5952 + hash: "db04665e58448ecc7f95baa3e4ea79a5" + } + Frame { + msec: 5968 + hash: "0e4aae728d8d543538a9446c41e18e91" + } + Frame { + msec: 5984 + hash: "e3cd1bbb1d9963e5c74d36e526a871b0" + } + Frame { + msec: 6000 + hash: "bcd893a0e200ddda4e1468c159018865" + } + Frame { + msec: 6016 + hash: "9c5293356aa6312f909e655e9bcf961b" + } + Frame { + msec: 6032 + hash: "0bab7b9166f6af554d4fa0badeec739e" + } + Frame { + msec: 6048 + hash: "e74996581f0aaeced118c5cbfd977d90" + } + Frame { + msec: 6064 + hash: "5d128eb20a2a23da8c2d9a35293e5769" + } + Frame { + msec: 6080 + hash: "ebbbc343698287faf7ffa7526a726b54" + } + Frame { + msec: 6096 + hash: "d812172192cc19590f9a2d7dbf970439" + } + Frame { + msec: 6112 + hash: "60263addb1b4b5ac43f8199b8ed77e40" + } + Frame { + msec: 6128 + hash: "702a1ff2876eaaa59359811bb6437c5b" + } + Frame { + msec: 6144 + hash: "8f81dc43decce5094ee7a089f0009730" + } + Frame { + msec: 6160 + hash: "efda5dd9edd83a0da089d0b28806c6b6" + } + Frame { + msec: 6176 + hash: "7274a33a7a5272d7abdaf41f4b2bf664" + } + Frame { + msec: 6192 + hash: "0cc80077476e721a3da85c17cc56a65e" + } + Frame { + msec: 6208 + hash: "e65a534f0e7e70520a9c2cfa09ee8159" + } + Frame { + msec: 6224 + hash: "b05b514c63bd8998785382e6a9cbd849" + } + Frame { + msec: 6240 + hash: "10a04d641e0cc65c120d8bcf2f3e54c8" + } + Frame { + msec: 6256 + hash: "68418e2206a496dd15a05b50fec6f87e" + } + Frame { + msec: 6272 + hash: "6549e0989e1c86e3a7eb0dcc8dd31380" + } + Frame { + msec: 6288 + hash: "bd0193c2cbc8958f674f4ec52a693b72" + } + Frame { + msec: 6304 + hash: "746440b45a3688dbd32b34c57454e956" + } + Frame { + msec: 6320 + hash: "6b54ee8af30be2178e8b3afab5dcb4c7" + } + Frame { + msec: 6336 + hash: "ba2fbad3fe2fe25ec0c0c542659168dc" + } + Frame { + msec: 6352 + hash: "84bd72703bd8200f8f090783d06ae451" + } + Frame { + msec: 6368 + hash: "17c9fb063280c2ee4cb4a13273bbb199" + } + Frame { + msec: 6384 + hash: "df28fd55719f5c2d164596d02c2faff2" + } + Frame { + msec: 6400 + hash: "c2e280e78e892200d40022d17ce695b7" + } + Frame { + msec: 6416 + hash: "c657caa0c5158e178ec5df80bbad6bcb" + } + Frame { + msec: 6432 + hash: "d91f4f6ec6503fe8280f9b02dd11e64a" + } + Frame { + msec: 6448 + hash: "0fb9400cdca9dbd4035fbf8af9952360" + } + Frame { + msec: 6464 + hash: "cac0e1b4aa094306b95f90ede4705391" + } + Frame { + msec: 6480 + hash: "e60a4bb14300a937a767effee931c60f" + } + Frame { + msec: 6496 + hash: "8b461397e3f210ee7e9305dcab2af2db" + } + Frame { + msec: 6512 + hash: "6ce9ec0942dd06c9f73929a7e176852c" + } + Frame { + msec: 6528 + hash: "da36e254635eea854a6552ba008117f9" + } + Frame { + msec: 6544 + hash: "0bec6402b5eb09d05ce8e9ff5253ea8d" + } + Frame { + msec: 6560 + hash: "72f6610527d395ca590eda166ef6bc4e" + } + Frame { + msec: 6576 + hash: "622ae3fd47adb2432e2a40d3c5539393" + } + Frame { + msec: 6592 + hash: "0b18c49e2bbf9370216e06b555faf183" + } + Frame { + msec: 6608 + hash: "0c090bb975fb883301b52479fd6f5fdf" + } + Frame { + msec: 6624 + hash: "c4205d7ecb7327426d9591e77247acab" + } + Frame { + msec: 6640 + hash: "f0e0075243e4b8aa97056248fe6033ed" + } + Frame { + msec: 6656 + hash: "47f99b40a8764ee9d9e429061fb7acb2" + } + Frame { + msec: 6672 + hash: "49e8c1e974b0716570d85109b53817a5" + } + Frame { + msec: 6688 + hash: "72f981bad831b6ed858009527902f734" + } + Frame { + msec: 6704 + hash: "e959a0493b06369a429f90f66cb65977" + } + Frame { + msec: 6720 + image: "easefollow.6.png" + } + Frame { + msec: 6736 + hash: "93470d983282f24425558f47ad705154" + } + Frame { + msec: 6752 + hash: "cdccbe1a7c7abd4a6a6ee754ed0c9759" + } + Frame { + msec: 6768 + hash: "0e1b7b5332a9fcdb492db5314a2a0267" + } + Frame { + msec: 6784 + hash: "1e1ffe3439aab51d0b325474e7d8dc28" + } + Frame { + msec: 6800 + hash: "e8e7e9b5871caf77f15678616d6c9c8a" + } + Frame { + msec: 6816 + hash: "9771fff3b7752154d093c038bea73d28" + } + Frame { + msec: 6832 + hash: "1af851ea214cbddb0e3a743084a5cf6b" + } + Frame { + msec: 6848 + hash: "1566182a7e29bbb738705a90c4909617" + } + Frame { + msec: 6864 + hash: "feed650e1d948fe622234d212fb745f2" + } + Frame { + msec: 6880 + hash: "3cd3d063275b91f9680717421c118ba4" + } + Frame { + msec: 6896 + hash: "c1f088801334762cd499e7cc70e1e59a" + } + Frame { + msec: 6912 + hash: "e8f8d153e7a027a5092a9209411d97f7" + } + Frame { + msec: 6928 + hash: "f11747c3533b4b2fc77a64ca0cace8b0" + } + Frame { + msec: 6944 + hash: "21618c67a2a8bbce86fc872060ad40e8" + } + Frame { + msec: 6960 + hash: "02da96335db74b87ceefe91b1dfe72e6" + } + Frame { + msec: 6976 + hash: "2b2e4143143ead8dea5865fd782f1775" + } + Frame { + msec: 6992 + hash: "13e710900b05e26cdb030b1e2b2be715" + } + Frame { + msec: 7008 + hash: "29e8995d17aac4d02034debcbb9fcb98" + } + Frame { + msec: 7024 + hash: "1099db1b3e4c69e84c6ab1b7c311bf1e" + } + Frame { + msec: 7040 + hash: "cc7cb720043334f1eeb385dce4389dc2" + } + Frame { + msec: 7056 + hash: "34c7a62c1bc7261e2fd31c40068b37a7" + } + Frame { + msec: 7072 + hash: "7fafbe05cbcaa21893e3aa0f1fcfb5a0" + } + Key { + type: 6 + key: 16777249 + modifiers: 67108864 + text: "" + autorep: false + count: 1 + } + Frame { + msec: 7088 + hash: "5b26c8cf047706633795a8ed3e703a89" + } + Frame { + msec: 7104 + hash: "e0774bf9e74d0cde81c5cb216a9258fc" + } + Frame { + msec: 7120 + hash: "0870262f643245e13f4fba79fd575897" + } + Frame { + msec: 7136 + hash: "8faf0d050bb435ade8af5012c1a6b0dc" + } + Frame { + msec: 7152 + hash: "382c037895cc39a6870db57b5016c01f" + } + Frame { + msec: 7168 + hash: "f1f5a2cbc103ab1bee9f537fa8266e03" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedanimation.qml b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedanimation.qml new file mode 100644 index 0000000..ee94857 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedanimation.qml @@ -0,0 +1,45 @@ +import Qt 4.6 + +Rectangle { + width: 800; height: 240; color: "gray" + + Rectangle { + id: rect + width: 50; height: 20; y: 30; color: "black" + SequentialAnimation on x { + loops: Animation.Infinite + NumberAnimation { from: 50; to: 700; duration: 2000 } + NumberAnimation { from: 700; to: 50; duration: 2000 } + } + } + + Rectangle { + width: 50; height: 20; y: 60; color: "red" + x: rect.x + Behavior on x { SmoothedAnimation { velocity: 400 } } + } + + Rectangle { + width: 50; height: 20; y: 90; color: "yellow" + x: rect.x + Behavior on x { SmoothedAnimation { velocity: 300; reversingMode: SmoothedAnimation.Immediate } } + } + + Rectangle { + width: 50; height: 20; y: 120; color: "green" + x: rect.x + Behavior on x { SmoothedAnimation { reversingMode: SmoothedAnimation.Sync } } + } + + Rectangle { + width: 50; height: 20; y: 150; color: "purple" + x: rect.x + Behavior on x { SmoothedAnimation { maximumEasingTime: 200 } } + } + + Rectangle { + width: 50; height: 20; y: 180; color: "blue" + x: rect.x + Behavior on x { SmoothedAnimation { duration: 300 } } + } +} -- cgit v0.12 From 444c52937410a0581a8bb93c9bee2245a84fe24c Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Mon, 29 Mar 2010 15:44:09 +1000 Subject: Fixes PathView compile warnings --- src/declarative/graphicsitems/qdeclarativepathview.cpp | 2 +- src/declarative/graphicsitems/qdeclarativepathview_p_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index c2cfbb1..71f85ae 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1193,7 +1193,7 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count) emit countChanged(); } -void QDeclarativePathView::itemsMoved(int from, int to, int count) +void QDeclarativePathView::itemsMoved(int /*from*/, int /*to*/, int /*count*/) { Q_D(QDeclarativePathView); if (!d->isValid() || !isComponentComplete()) diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index 26ec4e5..6470893 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -79,9 +79,9 @@ public: , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) , autoHighlight(true), highlightUp(false), dragMargin(0), deceleration(100) , moveOffset(this, &QDeclarativePathViewPrivate::setOffset) - , moveHighlight(this, &QDeclarativePathViewPrivate::setHighlightPosition) , firstIndex(-1), pathItems(-1), requestedIndex(-1) , moveReason(Other), attType(0), highlightComponent(0), highlightItem(0) + , moveHighlight(this, &QDeclarativePathViewPrivate::setHighlightPosition) , highlightPosition(0) , highlightRangeStart(0), highlightRangeEnd(0) , highlightRangeMode(QDeclarativePathView::StrictlyEnforceRange) -- cgit v0.12 From 859304f5a8d9169a3f2f30e013d460b0e93c118f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Mar 2010 15:45:18 +1000 Subject: Make visual tests run on windows --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 8f1a406..2794ab8 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -106,7 +106,6 @@ void tst_qmlvisual::visual_data() files << QT_TEST_SOURCE_DIR "/animation/reanchor/reanchor.qml"; } - foreach (const QString &file, files) { QString testdata = toTestScript(file); if (testdata.isEmpty()) @@ -141,6 +140,8 @@ QString tst_qmlvisual::toTestScript(const QString &file, Mode mode) int index = file.lastIndexOf(QDir::separator()); if (index == -1) + index = file.lastIndexOf('/'); + if (index == -1) return QString(); const char* platformsuffix=0; // platforms with different fonts -- cgit v0.12 From ff983ee8257b79143911ca58ebedc49b1660a0c4 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Mar 2010 16:03:29 +1000 Subject: Make qmlpixmapcache thread shutdown cleaner Change to Thiago's method: QThread::quit() is *not* thread-safe, so we mustn't call it from outside the QThread that the QThread holds. Unlike other QObjects, this method and some others must not be called from the thread they have affinity to. So add a hack to call it in the auxiliary thread. Do that by connecting a dummy QObject's destroyed() signal to the quit() slot in a DirectConnection, then move the object to the thread. When we call deleteLater(), this will cause the thread's event loop to delete the object, which in turn calls quit() in the actual thread. Reviewed-by: Thiago Macieira --- src/declarative/util/qdeclarativepixmapcache.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index a9c30f8..1da929e 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -114,7 +114,7 @@ private: QList cancelled; QDeclarativeEngine *engine; QDeclarativeImageRequestHandler *handler; - QWaitCondition started; + QObject *eventLoopQuitHack; QMutex mutex; static QHash readers; @@ -370,6 +370,9 @@ void QDeclarativeImageRequestHandler::networkRequestDone() QDeclarativeImageReader::QDeclarativeImageReader(QDeclarativeEngine *eng) : QThread(eng), engine(eng), handler(0) { + eventLoopQuitHack = new QObject; + eventLoopQuitHack->moveToThread(this); + connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection); start(QThread::IdlePriority); } @@ -379,15 +382,8 @@ QDeclarativeImageReader::~QDeclarativeImageReader() readers.remove(engine); readerMutex.unlock(); - if (isRunning()) { - quit(); - while (!wait(100)) { - // It is possible to for the quit to happen before exec() - // Need to wait until the event loop starts so that we - // can stop it. Particularly likely with an idle thread. - quit(); - } - } + eventLoopQuitHack->deleteLater(); + wait(); } QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *engine) @@ -396,7 +392,6 @@ QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *e QDeclarativeImageReader *reader = readers.value(engine); if (!reader) { reader = new QDeclarativeImageReader(engine); - reader->started.wait(&readerMutex); readers.insert(engine, reader); } readerMutex.unlock(); @@ -433,7 +428,6 @@ void QDeclarativeImageReader::run() { readerMutex.lock(); handler = new QDeclarativeImageRequestHandler(this, engine); - started.wakeAll(); readerMutex.unlock(); exec(); -- cgit v0.12 From 2661be1bacdd83d1b3e6207c519c2699edfdc1d0 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 30 Mar 2010 15:25:01 +1000 Subject: WorkerScript was receiving events after deletion and trying to process these events. --- src/declarative/qml/qdeclarativeworkerscript.cpp | 6 +++++- .../qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp | 11 ++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index a7ed358..628681f 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -437,8 +437,12 @@ QDeclarativeWorkerScriptEngine::QDeclarativeWorkerScriptEngine(QDeclarativeEngin QDeclarativeWorkerScriptEngine::~QDeclarativeWorkerScriptEngine() { + d->m_lock.lock(); qDeleteAll(d->workers); - delete d; d = 0; + d->workers.clear(); + d->m_lock.unlock(); + + d->deleteLater(); } QDeclarativeWorkerScriptEnginePrivate::WorkerScript::WorkerScript() diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index fcb453c..12000d0 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -193,7 +193,7 @@ void tst_QDeclarativeListModel::dynamic_data() QTest::newRow("clear1") << "{append({'foo':456});clear();count}" << 0 << ""; QTest::newRow("clear2") << "{append({'foo':123});append({'foo':456});clear();count}" << 0 << ""; - QTest::newRow("clear2") << "{append({'foo':123});clear();get(0).foo}" << 0 << "QML ListModel (unknown location) get: index 0 out of range"; + QTest::newRow("clear3") << "{append({'foo':123});clear();get(0).foo}" << 0 << "QML ListModel (unknown location) get: index 0 out of range"; QTest::newRow("remove1") << "{append({'foo':123});remove(0);count}" << 0 << ""; QTest::newRow("remove2a") << "{append({'foo':123});append({'foo':456});remove(0);count}" << 1 << ""; @@ -290,8 +290,6 @@ void tst_QDeclarativeListModel::dynamic_worker_data() void tst_QDeclarativeListModel::dynamic_worker() { - QSKIP("", SkipAll); - QFETCH(QString, script); QFETCH(int, result); QFETCH(QString, warning); @@ -324,6 +322,7 @@ void tst_QDeclarativeListModel::dynamic_worker() // changes are reflected in the list model in the main thread if (QByteArray(QTest::currentDataTag()).startsWith("nested")) QTest::ignoreMessage(QtWarningMsg, "QML ListModel (unknown location) Cannot add nested list values when modifying or after modification from a worker script"); + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, operations.mid(0, operations.length()-1)))); waitForWorker(item); @@ -342,7 +341,6 @@ void tst_QDeclarativeListModel::dynamic_worker() void tst_QDeclarativeListModel::convertNestedToFlat_fail() { - QSKIP("", SkipAll); // If a model has nested data, it cannot be used at all from a worker script QFETCH(QString, script); @@ -368,7 +366,7 @@ void tst_QDeclarativeListModel::convertNestedToFlat_fail() delete item; QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); - qApp->processEvents(); + qApp->processEvents(); } void tst_QDeclarativeListModel::convertNestedToFlat_fail_data() @@ -387,7 +385,6 @@ void tst_QDeclarativeListModel::convertNestedToFlat_fail_data() void tst_QDeclarativeListModel::convertNestedToFlat_ok() { - QSKIP("", SkipAll); // If a model only has plain data, it can be modified from a worker script. However, // once the model is used from a worker script, it no longer accepts nested data @@ -429,7 +426,7 @@ void tst_QDeclarativeListModel::convertNestedToFlat_ok() delete item; QTest::ignoreMessage(QtWarningMsg, "QThread: Destroyed while thread is still running"); - qApp->processEvents(); + qApp->processEvents(); } void tst_QDeclarativeListModel::convertNestedToFlat_ok_data() -- cgit v0.12 From 1190f901cbcc62ab50c66bf0a7c41bfba923da7f Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 30 Mar 2010 16:31:26 +1000 Subject: Update QmlChanges for SmoothedAnimation --- src/declarative/QmlChanges.txt | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 847f1f5..c86bdc6 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -32,6 +32,39 @@ syntax has been introduced: Item { Behavior on x {}; NumberAnimation on y {} } Only the syntax has changed, the behavior is identical. + +EaseFollow changed to SmoothedAnimation +--------------------------------------- +EaseFollow was renamed to SmoothedAnimation and now it inherits from +NumberAnimaton and as a consequence SmoothedAnimation can be used inside +Behaviors, as PropertySourceValues or in state transitions, like any other animation. + +The old EaseFollow properties changed to comply with the other declarative +animations ('source' changed to 'to'), so now 'to' changes are not +automatically 'followed' anymore. + +If you want to follow an hypothetical rect1, you should do now: + +     Rectangle { +         color: "green" +         width: 60; height: 60; +         x: rect1.x - 5; y: rect1.y - 5; +         Behavior on x { SmoothedAnimation { velocity: 200 } } +         Behavior on y { SmoothedAnimation { velocity: 200 } } +     } + +instead of the old automatic source changed tracking: + +     Rectangle { +         color: "green" +         width: 60; height: 60; +         EaseFollow on x { source: rect1.x - 5; velocity: 200 } +         EaseFollow on y { source: rect1.y - 5; velocity: 200 } +    } + +This is a syntax and behavior change. + + Script element removed ---------------------- Inline Script{} blocks have been deprecated, and will soon be removed entirely. -- cgit v0.12 From b9b305f6c7bc960101bfd883ca6e3df889483481 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Tue, 30 Mar 2010 16:37:28 +1000 Subject: Correctly construct boolean JSValue's Task-number: QTBUG-9205 --- src/script/bridge/qscriptdeclarativeclass.cpp | 12 +++++++++--- .../qdeclarativeecmascript/data/strictlyEquals.qml | 17 +++++++++++++++++ .../tst_qdeclarativeecmascript.cpp | 21 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index acfb2a4..0f450ca 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -70,9 +70,12 @@ QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, uint value) new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); } -QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, bool value) +QScriptDeclarativeClass::Value::Value(QScriptContext *, bool value) { - new (this) JSC::JSValue(QScriptEnginePrivate::frameForContext(ctxt), value); + if (value) + new (this) JSC::JSValue(JSC::JSValue::JSTrue); + else + new (this) JSC::JSValue(JSC::JSValue::JSFalse); } QScriptDeclarativeClass::Value::Value(QScriptContext *ctxt, double value) @@ -107,7 +110,10 @@ QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, uint value) QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, bool value) { - new (this) JSC::JSValue(QScriptEnginePrivate::get(eng)->currentFrame, value); + if (value) + new (this) JSC::JSValue(JSC::JSValue::JSTrue); + else + new (this) JSC::JSValue(JSC::JSValue::JSFalse); } QScriptDeclarativeClass::Value::Value(QScriptEngine *eng, double value) diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml b/tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml new file mode 100644 index 0000000..b9e455d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml @@ -0,0 +1,17 @@ +import Qt 4.6 + +QtObject { + property bool test1: (a === true) + property bool test2: !(a === false) + property bool test3: (b === 11.2) + property bool test4: !(b === 9) + property bool test5: (c === 9) + property bool test6: !(c === 13) + property bool test7: (d === "Hello world") + property bool test8: !(d === "Hi") + + property bool a: true + property real b: 11.2 + property int c: 9 + property string d: "Hello world" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 2791722c..b218d30 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -128,6 +128,7 @@ private slots: void scriptDisconnect(); void ownership(); void qlistqobjectMethods(); + void strictlyEquals(); void bug1(); void dynamicCreationCrash(); @@ -2005,6 +2006,26 @@ void tst_qdeclarativeecmascript::qlistqobjectMethods() delete object; } +// QTBUG-9205 +void tst_qdeclarativeecmascript::strictlyEquals() +{ + QDeclarativeComponent component(&engine, TEST_FILE("strictlyEquals.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + QCOMPARE(object->property("test3").toBool(), true); + QCOMPARE(object->property("test4").toBool(), true); + QCOMPARE(object->property("test5").toBool(), true); + QCOMPARE(object->property("test6").toBool(), true); + QCOMPARE(object->property("test7").toBool(), true); + QCOMPARE(object->property("test8").toBool(), true); + + delete object; +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" -- cgit v0.12