diff options
author | Thomas Hartmann <thomas.hartmann@qt.io> | 2018-04-23 18:02:15 +0200 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@qt.io> | 2018-04-27 14:07:23 +0000 |
commit | b2cd5db1e5bfcd168bce025b126d4c5a2fc9e0ae (patch) | |
tree | 5c7c4af9e7c536d1172271b6b2f7849668778c27 | |
parent | e60155d6af1a9e1c86bfb7679dbd92ce616ad8fd (diff) |
Add TimelineAnimation
* New api to define animation clips
* Special animation type for timeline
* Adding ping pong for TimelineAnimation
* Adjusting manual tests
* Adding new manual tests
Change-Id: Ic670b389062ef4ac92e000bc99574e5fa04a7006
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
-rw-r--r-- | src/imports/timeline/plugins.qmltypes | 101 | ||||
-rw-r--r-- | src/imports/timeline/qquicktimeline.cpp | 58 | ||||
-rw-r--r-- | src/imports/timeline/qquicktimeline_p.h | 5 | ||||
-rw-r--r-- | src/imports/timeline/qquicktimelineanimation.cpp | 112 | ||||
-rw-r--r-- | src/imports/timeline/qquicktimelineanimation_p.h | 55 | ||||
-rw-r--r-- | src/imports/timeline/qtquicktimelineplugin.cpp | 4 | ||||
-rw-r--r-- | src/imports/timeline/timeline.pri | 6 | ||||
-rw-r--r-- | tests/manual/timelineTestApp/main.qml | 18 | ||||
-rw-r--r-- | tests/manual/timelineTestApp/qml.qrc | 2 | ||||
-rw-r--r-- | tests/manual/timelineTestApp/test01.qml | 24 | ||||
-rw-r--r-- | tests/manual/timelineTestApp/test02.qml | 18 | ||||
-rw-r--r-- | tests/manual/timelineTestApp/test04.qml | 222 | ||||
-rw-r--r-- | tests/manual/timelineTestApp/test05.qml | 266 |
13 files changed, 858 insertions, 33 deletions
diff --git a/src/imports/timeline/plugins.qmltypes b/src/imports/timeline/plugins.qmltypes index a795dd0..b77b587 100644 --- a/src/imports/timeline/plugins.qmltypes +++ b/src/imports/timeline/plugins.qmltypes @@ -9,6 +9,44 @@ import QtQuick.tooling 1.2 Module { dependencies: [] Component { + name: "QQuickAbstractAnimation" + prototype: "QObject" + Enum { + name: "Loops" + values: { + "Infinite": -2 + } + } + Property { name: "running"; type: "bool" } + Property { name: "paused"; type: "bool" } + Property { name: "alwaysRunToEnd"; type: "bool" } + Property { name: "loops"; type: "int" } + Signal { name: "started" } + Signal { name: "stopped" } + Signal { + name: "runningChanged" + Parameter { type: "bool" } + } + Signal { + name: "pausedChanged" + Parameter { type: "bool" } + } + Signal { + name: "alwaysRunToEndChanged" + Parameter { type: "bool" } + } + Signal { + name: "loopCountChanged" + Parameter { type: "int" } + } + Method { name: "restart" } + Method { name: "start" } + Method { name: "pause" } + Method { name: "resume" } + Method { name: "stop" } + Method { name: "complete" } + } + Component { name: "QQuickKeyframe" prototype: "QObject" exports: ["QtQuick.Timeline/Keyframe 1.0"] @@ -19,6 +57,55 @@ Module { Signal { name: "easingCurveChanged" } } Component { + name: "QQuickKeyframeGroup" + defaultProperty: "keyframes" + prototype: "QObject" + exports: ["QtQuick.Timeline/KeyframeGroup 1.0"] + exportMetaObjectRevisions: [0] + Property { name: "target"; type: "QObject"; isPointer: true } + Property { name: "property"; type: "string" } + Property { name: "keyframes"; type: "QQuickKeyframe"; isList: true; isReadonly: true } + } + Component { + name: "QQuickNumberAnimation" + prototype: "QQuickPropertyAnimation" + Property { name: "from"; type: "double" } + Property { name: "to"; type: "double" } + } + Component { + name: "QQuickPropertyAnimation" + prototype: "QQuickAbstractAnimation" + Property { name: "duration"; type: "int" } + Property { name: "from"; type: "QVariant" } + Property { name: "to"; type: "QVariant" } + Property { name: "easing"; type: "QEasingCurve" } + Property { name: "target"; type: "QObject"; isPointer: true } + Property { name: "property"; type: "string" } + Property { name: "properties"; type: "string" } + Property { name: "targets"; type: "QObject"; isList: true; isReadonly: true } + Property { name: "exclude"; type: "QObject"; isList: true; isReadonly: true } + Signal { + name: "durationChanged" + Parameter { type: "int" } + } + Signal { + name: "fromChanged" + Parameter { type: "QVariant" } + } + Signal { + name: "toChanged" + Parameter { type: "QVariant" } + } + Signal { + name: "easingChanged" + Parameter { type: "QEasingCurve" } + } + Signal { + name: "propertiesChanged" + Parameter { type: "string" } + } + } + Component { name: "QQuickTimeline" defaultProperty: "keyframes" prototype: "QObject" @@ -28,16 +115,16 @@ Module { Property { name: "endFrame"; type: "double" } Property { name: "currentFrame"; type: "double" } Property { name: "keyframes"; type: "QQuickKeyframeGroup"; isList: true; isReadonly: true } + Property { name: "animations"; type: "QQuickTimelineAnimation"; isList: true; isReadonly: true } Property { name: "enabled"; type: "bool" } } Component { - name: "QQuickKeyframeGroup" - defaultProperty: "keyframes" - prototype: "QObject" - exports: ["QtQuick.Timeline/KeyframeGroup 1.0"] + name: "QQuickTimelineAnimation" + prototype: "QQuickNumberAnimation" + exports: ["QtQuick.Timeline/TimelineAnimation 1.0"] exportMetaObjectRevisions: [0] - Property { name: "target"; type: "QObject"; isPointer: true } - Property { name: "property"; type: "string" } - Property { name: "keyframes"; type: "QQuickKeyframe"; isList: true; isReadonly: true } + Property { name: "pingPong"; type: "bool" } + Signal { name: "finished" } + Signal { name: "pingPongChanged" } } } diff --git a/src/imports/timeline/qquicktimeline.cpp b/src/imports/timeline/qquicktimeline.cpp index 52f9a32..d5e5b26 100644 --- a/src/imports/timeline/qquicktimeline.cpp +++ b/src/imports/timeline/qquicktimeline.cpp @@ -53,7 +53,14 @@ protected: static QQuickKeyframeGroup* keyframe_at(QQmlListProperty<QQuickKeyframeGroup> *list, int pos); static void clear_keyframes(QQmlListProperty<QQuickKeyframeGroup> *list); + static void append_animation(QQmlListProperty<QQuickTimelineAnimation> *list, QQuickTimelineAnimation *a); + static int animation_count(QQmlListProperty<QQuickTimelineAnimation> *list); + static QQuickTimelineAnimation* animation_at(QQmlListProperty<QQuickTimelineAnimation> *list, int pos); + static void clear_animations(QQmlListProperty<QQuickTimelineAnimation> *list); + + QList<QQuickKeyframeGroup *> keyframes; + QList<QQuickTimelineAnimation *> animations; }; void QQuickTimelinePrivate::init() @@ -97,6 +104,34 @@ void QQuickTimelinePrivate::clear_keyframes(QQmlListProperty<QQuickKeyframeGroup } } +void QQuickTimelinePrivate::append_animation(QQmlListProperty<QQuickTimelineAnimation> *list, QQuickTimelineAnimation *a) +{ + QQuickTimeline *q = static_cast<QQuickTimeline *>(list->object); + a->setTargetObject(q); + q->d_func()->animations.append(a); +} + +int QQuickTimelinePrivate::animation_count(QQmlListProperty<QQuickTimelineAnimation> *list) +{ + QQuickTimeline *q = static_cast<QQuickTimeline *>(list->object); + return q->d_func()->animations.count(); +} + +QQuickTimelineAnimation* QQuickTimelinePrivate::animation_at(QQmlListProperty<QQuickTimelineAnimation> *list, int pos) +{ + QQuickTimeline *q = static_cast<QQuickTimeline *>(list->object); + return q->d_func()->animations.at(pos); +} + +void QQuickTimelinePrivate::clear_animations(QQmlListProperty<QQuickTimelineAnimation> *list) +{ + QQuickTimeline *q = static_cast<QQuickTimeline *>(list->object); + while (q->d_func()->animations.count()) { + QQuickTimelineAnimation *firstAnimation = q->d_func()->animations.at(0); + q->d_func()->animations.removeAll(firstAnimation); + } +} + QQuickTimeline::QQuickTimeline(QObject *parent) : QObject(*(new QQuickTimelinePrivate), parent) { @@ -107,9 +142,19 @@ QQmlListProperty<QQuickKeyframeGroup> QQuickTimeline::keyframes() Q_D(QQuickTimeline); return QQmlListProperty<QQuickKeyframeGroup>(this, &d->keyframes, QQuickTimelinePrivate::append_keyframe, - QQuickTimelinePrivate::keyframe_count, - QQuickTimelinePrivate::keyframe_at, - QQuickTimelinePrivate::clear_keyframes); + QQuickTimelinePrivate::keyframe_count, + QQuickTimelinePrivate::keyframe_at, + QQuickTimelinePrivate::clear_keyframes); +} + +QQmlListProperty<QQuickTimelineAnimation> QQuickTimeline::animations() +{ + Q_D(QQuickTimeline); + + return QQmlListProperty<QQuickTimelineAnimation>(this, &d->animations, QQuickTimelinePrivate::append_animation, + QQuickTimelinePrivate::animation_count, + QQuickTimelinePrivate::animation_at, + QQuickTimelinePrivate::clear_animations); } bool QQuickTimeline::enabled() const @@ -201,6 +246,13 @@ void QQuickTimeline::reset() d->disable(); } +QList<QQuickTimelineAnimation *> QQuickTimeline::getAnimations() const +{ + Q_D(const QQuickTimeline); + + return d->animations; +} + void QQuickTimeline::classBegin() { Q_D(QQuickTimeline); diff --git a/src/imports/timeline/qquicktimeline_p.h b/src/imports/timeline/qquicktimeline_p.h index b4c2567..e09daff 100644 --- a/src/imports/timeline/qquicktimeline_p.h +++ b/src/imports/timeline/qquicktimeline_p.h @@ -31,6 +31,7 @@ // #include "qquickkeyframe_p.h" +#include "qquicktimelineanimation_p.h" #include <QtQml/qqml.h> @@ -49,6 +50,7 @@ class QQuickTimeline : public QObject, public QQmlParserStatus Q_PROPERTY(qreal endFrame READ endFrame WRITE setEndFrame NOTIFY endFrameChanged) Q_PROPERTY(qreal currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged) Q_PROPERTY(QQmlListProperty<QQuickKeyframeGroup> keyframes READ keyframes) + Q_PROPERTY(QQmlListProperty<QQuickTimelineAnimation> animations READ animations) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) Q_CLASSINFO("DefaultProperty", "keyframes") @@ -57,6 +59,7 @@ public: explicit QQuickTimeline(QObject *parent = nullptr); QQmlListProperty<QQuickKeyframeGroup> keyframes(); + QQmlListProperty<QQuickTimelineAnimation> animations(); bool enabled() const; void setEnabled(bool enabled); @@ -73,6 +76,8 @@ public: void init(); void reset(); + QList<QQuickTimelineAnimation*> getAnimations() const; + protected: void classBegin() override; void componentComplete() override; diff --git a/src/imports/timeline/qquicktimelineanimation.cpp b/src/imports/timeline/qquicktimelineanimation.cpp new file mode 100644 index 0000000..e3a816e --- /dev/null +++ b/src/imports/timeline/qquicktimelineanimation.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd +** All rights reserved. +** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** +** This file is part of the Qt Enterprise Qt Quick Timeline Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. +** +** If you have questions regarding the use of this file, please use +** contact form at http://www.qt.io/contact-us +** +****************************************************************************/ + +#include "qquicktimelineanimation_p.h" + +#include "qquicktimeline_p.h" + +#include <private/qobject_p.h> +#include <private/qquickanimation_p_p.h> + +#include <QTimer> + +QT_BEGIN_NAMESPACE + +QQuickTimelineAnimation::QQuickTimelineAnimation(QObject *parent) : QQuickNumberAnimation(parent) +{ + setProperty(QLatin1String("currentFrame")); + connect(this, &QQuickAbstractAnimation::started, this, &QQuickTimelineAnimation::handleStarted); + connect(this, &QQuickAbstractAnimation::stopped, this, &QQuickTimelineAnimation::handleStopped); +} + +void QQuickTimelineAnimation::setPingPong(bool b) +{ + if (b == m_pinpong) + return; + + m_pinpong = b; + emit pingPongChanged(); +} + +bool QQuickTimelineAnimation::pingPong() const +{ + return m_pinpong; +} + +void QQuickTimelineAnimation::handleStarted() +{ + QQuickTimeline* timeline = qobject_cast<QQuickTimeline*>(parent()); + + if (!timeline) + return; + + for (QQuickTimelineAnimation *other : timeline->getAnimations()) { + if (other != this) + other->stop(); + } + + auto *privateObject = static_cast<QQuickPropertyAnimationPrivate*>(QObjectPrivate::get(this)); + + if (m_pinpong && m_originalStart) { + m_originalLoop = privateObject->loopCount; + m_currentLoop = 0; + privateObject->loopCount = 1; + privateObject->animationInstance->setLoopCount(1); + m_originalStart = false; + m_reversed = false; + } +} + +static void swapStartEnd(QQuickPropertyAnimationPrivate *privateObject) +{ + std::swap(privateObject->to, privateObject->from); +} + +void QQuickTimelineAnimation::handleStopped() +{ + if (!m_pinpong) { + emit finished(); + return; + } + + auto *privateObject = static_cast<QQuickPropertyAnimationPrivate*>(QObjectPrivate::get(this)); + + if (m_reversed) { + m_currentLoop++; + } + + if (!(privateObject->animationInstance->currentTime() < privateObject->duration) + && (m_currentLoop < m_originalLoop + || m_originalLoop == -1)) { + swapStartEnd(privateObject); + + m_reversed = !m_reversed; + QQuickTimelineAnimation::start(); + + } else { + if (m_reversed) { + swapStartEnd(privateObject); + } + m_originalStart = true; + m_reversed = false; + privateObject->loopCount = m_originalLoop; + emit finished(); + } +} + +QT_END_NAMESPACE diff --git a/src/imports/timeline/qquicktimelineanimation_p.h b/src/imports/timeline/qquicktimelineanimation_p.h new file mode 100644 index 0000000..ee85b65 --- /dev/null +++ b/src/imports/timeline/qquicktimelineanimation_p.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd +** All rights reserved. +** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** +** This file is part of the Qt Enterprise Qt Quick Timeline Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. +** +** If you have questions regarding the use of this file, please use +** contact form at http://www.qt.io/contact-us +** +****************************************************************************/ + +#ifndef QQUICKTIMELINEANIMATION_H +#define QQUICKTIMELINEANIMATION_H + +#include <QtQuick/private/qquickanimation_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTimelineAnimation : public QQuickNumberAnimation +{ + Q_OBJECT + + Q_PROPERTY(bool pingPong READ pingPong WRITE setPingPong NOTIFY pingPongChanged) + +public: + QQuickTimelineAnimation(QObject *parent = nullptr); + + void setPingPong(bool b); + bool pingPong() const; + +Q_SIGNALS: + void pingPongChanged(); + void finished(); + +private: + void handleStarted(); + void handleStopped(); + + bool m_pinpong = false; + bool m_reversed = false; + bool m_originalStart = true; + int m_currentLoop = 0; + int m_originalLoop = 0; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTIMELINEANIMATION_H diff --git a/src/imports/timeline/qtquicktimelineplugin.cpp b/src/imports/timeline/qtquicktimelineplugin.cpp index b1cb0dc..35f47bd 100644 --- a/src/imports/timeline/qtquicktimelineplugin.cpp +++ b/src/imports/timeline/qtquicktimelineplugin.cpp @@ -18,8 +18,9 @@ #include <QtQml/qqmlextensionplugin.h> -#include "qquicktimeline_p.h" #include "qquickkeyframe_p.h" +#include "qquicktimeline_p.h" +#include "qquicktimelineanimation_p.h" static inline void initResources() { @@ -50,6 +51,7 @@ QtQuickTimelinePlugin::QtQuickTimelinePlugin(QObject *parent) : QQmlExtensionPlu void QtQuickTimelinePlugin::registerTypes(const char *uri) { qmlRegisterType<QQuickTimeline>(uri, 1, 0, "Timeline"); + qmlRegisterType<QQuickTimelineAnimation>(uri, 1, 0, "TimelineAnimation"); qmlRegisterType<QQuickKeyframe>(uri, 1, 0, "Keyframe"); qmlRegisterType<QQuickKeyframeGroup>(uri, 1, 0, "KeyframeGroup"); } diff --git a/src/imports/timeline/timeline.pri b/src/imports/timeline/timeline.pri index 5aa0999..2d1d363 100644 --- a/src/imports/timeline/timeline.pri +++ b/src/imports/timeline/timeline.pri @@ -1,7 +1,9 @@ HEADERS += \ $$PWD/qquickkeyframe_p.h \ - $$PWD/qquicktimeline_p.h + $$PWD/qquicktimeline_p.h \ + $$PWD/qquicktimelineanimation_p.h SOURCES += \ $$PWD/qquickkeyframe.cpp \ - $$PWD/qquicktimeline.cpp + $$PWD/qquicktimeline.cpp \ + $$PWD/qquicktimelineanimation.cpp diff --git a/tests/manual/timelineTestApp/main.qml b/tests/manual/timelineTestApp/main.qml index 8b43d52..64416dd 100644 --- a/tests/manual/timelineTestApp/main.qml +++ b/tests/manual/timelineTestApp/main.qml @@ -61,5 +61,23 @@ Window { onClicked: loader.source = "test03.qml" } } + + Text { + text: "Test 04" + font.pixelSize: 12 + MouseArea { + anchors.fill: parent + onClicked: loader.source = "test04.qml" + } + } + + Text { + text: "Test 05" + font.pixelSize: 12 + MouseArea { + anchors.fill: parent + onClicked: loader.source = "test05.qml" + } + } } } diff --git a/tests/manual/timelineTestApp/qml.qrc b/tests/manual/timelineTestApp/qml.qrc index 4da9ddc..0fffb97 100644 --- a/tests/manual/timelineTestApp/qml.qrc +++ b/tests/manual/timelineTestApp/qml.qrc @@ -4,5 +4,7 @@ <file>test01.qml</file> <file>test02.qml</file> <file>test03.qml</file> + <file>test04.qml</file> + <file>test05.qml</file> </qresource> </RCC> diff --git a/tests/manual/timelineTestApp/test01.qml b/tests/manual/timelineTestApp/test01.qml index d0810aa..d395bbd 100644 --- a/tests/manual/timelineTestApp/test01.qml +++ b/tests/manual/timelineTestApp/test01.qml @@ -37,21 +37,10 @@ Item { color: "blue" MouseArea { anchors.fill: parent - onClicked: animation.start() + onClicked: animation.restart() } } - NumberAnimation { - id: animation - target: timeline - property: "currentFrame" - easing.type: Easing.InOutQuad - duration: 2000 - from: 0 - to: 100 - running: true - } - Item { width: 480 height: 480 @@ -65,6 +54,17 @@ Item { enabled: true + animations: [ + TimelineAnimation { + id: animation + duration: 2000 + from: 0 + to: 100 + running: false + } + + ] + KeyframeGroup { target: rectangle property: "x" diff --git a/tests/manual/timelineTestApp/test02.qml b/tests/manual/timelineTestApp/test02.qml index 861fe45..7d27a21 100644 --- a/tests/manual/timelineTestApp/test02.qml +++ b/tests/manual/timelineTestApp/test02.qml @@ -20,14 +20,6 @@ import QtQuick 2.0 import QtQuick.Timeline 1.0 Item { - PropertyAnimation { - running: true - duration: 1000 - target: timeline - property: "currentFrame" - from: 0 - to: 1000 - } Rectangle { id: leftGauge @@ -82,6 +74,16 @@ Item { startFrame: 0 endFrame: 1000 + animations: [ + + TimelineAnimation { + running: true + duration: 1000 + from: 0 + to: 1000 + } + ] + KeyframeGroup { target: leftGauge property: "x" diff --git a/tests/manual/timelineTestApp/test04.qml b/tests/manual/timelineTestApp/test04.qml new file mode 100644 index 0000000..be09f49 --- /dev/null +++ b/tests/manual/timelineTestApp/test04.qml @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd +** All rights reserved. +** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** +** This file is part of the Qt Enterprise Qt Quick Timeline Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. +** +** If you have questions regarding the use of this file, please use +** contact form at http://www.qt.io/contact-us +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Timeline 1.0 + +Item { + id: item1 + state: "pingpong" + + Timeline { + id: timeline + enabled: true + startFrame: 0 + endFrame: 1000 + animations: [ + TimelineAnimation { + id: pingPongAnimation + to: 200 + loops: 2 + from: 0 + duration: 2000 + running: false + pingPong: true + onFinished: item1.state = "firsthalf" + }, + + TimelineAnimation { + id: animation01 + to: 200 + loops: 1 + from: 0 + duration: 1000 + running: false + onFinished: item1.state = "secondhalf (ping pong)" + }, + TimelineAnimation { + id: animation02 + to: 400 + loops: 1 + from: 200 + duration: 1000 + running: false + pingPong: true + onFinished: item1.state = "last" + }, + TimelineAnimation { + id: animation03 + to: 0 + loops: 1 + from: 200 + duration: 500 + running: false + onFinished: item1.state = "pingpong" + } + ] + + KeyframeGroup { + target: rectangle + property: "width" + Keyframe { + frame: 1 + value: 50 + } + } + + KeyframeGroup { + target: rectangle + property: "height" + Keyframe { + frame: 1 + value: 50 + } + } + + KeyframeGroup { + target: rectangle + property: "x" + Keyframe { + frame: 100 + value: 100 + } + + Keyframe { + frame: 200 + value: 200 + } + + Keyframe { + frame: 300 + value: 100 + } + + Keyframe { + frame: 400 + value: 0 + } + } + + KeyframeGroup { + target: rectangle + property: "y" + Keyframe { + frame: 100 + value: 400 + } + + Keyframe { + frame: 200 + value: 430 + } + + Keyframe { + frame: 300 + value: 335 + } + + Keyframe { + frame: 400 + value: 430 + } + } + + KeyframeGroup { + target: rectangle + property: "color" + + Keyframe { + frame: 400 + value: "#f61b1b" + } + } + } + + Rectangle { + id: rectangle + x: 0 + y: 430 + width: 50 + height: 50 + color: "#f61b1b" + MouseArea { + anchors.topMargin: 109 + anchors.fill: parent + onClicked: { + print("clicked") + numberAnimation.start() + } + } + } + + Rectangle { + id: rectangle1 + x: 0 + y: 0 + width: 85 + height: 85 + color: "#22f4dd" + MouseArea { + anchors.fill: parent + onClicked: { + print("clicked") + numberAnimation.stop() + } + } + } + + Text { + id: text1 + x: 376 + y: 18 + text: item1.state + font.pixelSize: 12 + } + states: [ + State { + name: "pingpong" + + PropertyChanges { + target: pingPongAnimation + running: true + } + }, + State { + name: "firsthalf" + PropertyChanges { + target: animation01 + running: true + } + }, + State { + name: "secondhalf (ping pong)" + PropertyChanges { + target: animation02 + running: true + } + }, + State { + name: "last" + PropertyChanges { + target: animation03 + running: true + } + } + ] + +} diff --git a/tests/manual/timelineTestApp/test05.qml b/tests/manual/timelineTestApp/test05.qml new file mode 100644 index 0000000..5464556 --- /dev/null +++ b/tests/manual/timelineTestApp/test05.qml @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd +** All rights reserved. +** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** +** This file is part of the Qt Enterprise Qt Quick Timeline Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. +** +** If you have questions regarding the use of this file, please use +** contact form at http://www.qt.io/contact-us +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Timeline 1.0 + +Item { + width: 640 + height: 480 + + id: root + + state: "page02" + + Rectangle { + id: rectangle + x: 0 + y: 0 + width: 64 + height: 64 + color: "#747474" + + MouseArea { + anchors.fill: parent + id: leftArea + } + } + + Rectangle { + id: rectangle1 + x: 576 + y: 0 + width: 64 + height: 64 + color: "#747474" + + MouseArea { + anchors.fill: parent + id: rightArea + } + } + + Item { + id: item1 + x: -640 + y: 123 + width: 1920 + height: 480 + + Rectangle { + id: screen01 + x: 0 + y: 0 + width: 640 + height: 359 + color: "#ffffff" + + Text { + x: 0 + y: 0 + text: qsTr("Page 01") + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 38 + } + } + + + Rectangle { + id: screen02 + x: 640 + y: 0 + width: 640 + height: 359 + color: "#ffffff" + + Text { + x: 0 + y: 0 + text: qsTr("Page 02") + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 38 + anchors.horizontalCenter: parent.horizontalCenter + } + } + + + + Rectangle { + id: screen03 + x: 1280 + y: 0 + width: 640 + height: 359 + color: "#ffffff" + + Text { + x: 0 + y: 0 + text: qsTr("Page 03") + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 38 + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + Timeline { + id: timeline + endFrame: 1000 + startFrame: 0 + enabled: true + + animations: [ + TimelineAnimation { + id: animationToPage01 + from: 500 + to: 0 + running: false + onFinished: root.state = "page01" + }, + TimelineAnimation { + id: animationToPage02Left + from: 0 + to: 500 + running: false + onFinished: root.state = "page02" + }, + TimelineAnimation { + id: animationToPage02Right + from: 1000 + to: 500 + running: false + onFinished: root.state = "page02" + }, + TimelineAnimation { + id: animationToPage03 + from: 500 + to: 1000 + running: false + onFinished: root.state = "page03" + } + + ] + + KeyframeGroup { + target: item1 + property: "x" + + Keyframe { + frame: 0 + value: 0 + } + + Keyframe { + frame: 500 + value: -640 + } + + Keyframe { + frame: 1000 + value: -1280 + } + } + } + + Connections { + target: rightArea + enabled: root.state == "page01" + onClicked: root.state = "toPage02FromLeft" + } + + Connections { + target: rightArea + enabled: root.state == "page02" + onClicked: root.state = "toPage03" + } + + Connections { + target: leftArea + enabled: root.state == "page02" + onClicked: root.state = "toPage01" + } + + Connections { + target: leftArea + enabled: root.state == "page03" + onClicked: root.state = "toPage02FromRight" + } + + states: [ + State { + name: "page01" + + PropertyChanges { + target: timeline + currentFrame: 0 + } + }, + State { + name: "page02" + + PropertyChanges { + target: timeline + currentFrame: 500 + } + }, + State { + name: "page03" + + PropertyChanges { + target: timeline + currentFrame: 1000 + } + }, + State { + name: "toPage01" + PropertyChanges { + target: animationToPage01 + running: true + } + }, + State { + name: "toPage02FromLeft" + PropertyChanges { + target: animationToPage02Left + running: true + } + }, + State { + name: "toPage03" + PropertyChanges { + target: animationToPage03 + running: true + } + }, + State { + name: "toPage02FromRight" + PropertyChanges { + target: animationToPage02Right + running: true + } + } + ] + +} + +/*##^## Designer { + D{i:62;anchors_width:100;anchors_height:100}D{i:47;currentFrame__AT__NodeInstance:1} +} + ##^##*/ |