aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-11-21 17:51:31 +0000
committerQt by Nokia <qt-info@nokia.com>2011-11-21 19:01:16 +0100
commitfbbc3cab4ac57b99387c7955e712cfea7cd72856 (patch)
tree25089694b0ca98571eca11c94ce5608012e428bc
parentaf0af6fa1ad428931c729738a14bdf6fbb910887 (diff)
Adding custom easing curves to property animations
QDeclarativeEasingValueType gets the property customBezierCurve. This allows to define a custom easing curve as a cubic bezier curve. Change-Id: I33ae128ce29bba2834eedcbb90a9769a5391f997 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
-rw-r--r--examples/declarative/animation/easing/easing.qml15
-rw-r--r--src/declarative/items/qquickcanvas.h3
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp46
-rw-r--r--src/declarative/qml/qdeclarativevaluetype_p.h7
-rw-r--r--tools/qmleasing/TextField.qml76
-rw-r--r--tools/qmleasing/easing.qml219
-rw-r--r--tools/qmleasing/main.cpp116
-rw-r--r--tools/qmleasing/qmleasing.pro12
-rw-r--r--tools/qmleasing/resources.qrc6
-rw-r--r--tools/tools.pro2
10 files changed, 497 insertions, 5 deletions
diff --git a/examples/declarative/animation/easing/easing.qml b/examples/declarative/animation/easing/easing.qml
index 911e6ce7bf..233bb2d627 100644
--- a/examples/declarative/animation/easing/easing.qml
+++ b/examples/declarative/animation/easing/easing.qml
@@ -45,6 +45,9 @@ Rectangle {
id: window
width: 600; height: 460; color: "#232323"
+ property var easingCurve: [ 0.2, 0.2, 0.13, 0.65, 0.2, 0.8,
+ 0.624, 0.98, 0.93, 0.95, 1, 1 ]
+
ListModel {
id: easingTypes
ListElement { name: "Easing.Linear"; type: Easing.Linear; ballColor: "DarkRed" }
@@ -88,6 +91,7 @@ Rectangle {
ListElement { name: "Easing.InBounce"; type: Easing.InBounce; ballColor: "DimGray" }
ListElement { name: "Easing.InOutBounce"; type: Easing.InOutBounce; ballColor: "SlateGray" }
ListElement { name: "Easing.OutInBounce"; type: Easing.OutInBounce; ballColor: "DarkSlateGray" }
+ ListElement { name: "Easing.Bezier"; type: Easing.Bezier; ballColor: "Chartreuse"; }
}
Component {
@@ -128,8 +132,8 @@ Rectangle {
}
transitions: Transition {
- NumberAnimation { properties: "x"; easing.type: type; duration: 1000 }
- ColorAnimation { properties: "color"; easing.type: type; duration: 1000 }
+ NumberAnimation { properties: "x"; easing.type: type; easing.bezierCurve: getBezierCurve(name); duration: 1000 }
+ ColorAnimation { properties: "color"; easing.type: type; easing.bezierCurve: getBezierCurve(name); duration: 1000 }
}
}
}
@@ -156,4 +160,11 @@ Rectangle {
Repeater { model: easingTypes; delegate: delegate }
}
}
+
+ function getBezierCurve(name)
+ {
+ if (name === "Easing.Bezier")
+ return easingCurve;
+ return [];
+ }
}
diff --git a/src/declarative/items/qquickcanvas.h b/src/declarative/items/qquickcanvas.h
index a5a975785d..bf8693a354 100644
--- a/src/declarative/items/qquickcanvas.h
+++ b/src/declarative/items/qquickcanvas.h
@@ -52,9 +52,10 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QQuickItem;
class QSGEngine;
+class QQuickItem;
class QSGTexture;
+class QInputMethodEvent;
class QQuickCanvasPrivate;
class QOpenGLFramebufferObject;
class QDeclarativeIncubationController;
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index 9a941e63f9..ffd0041f7e 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -958,6 +958,52 @@ void QDeclarativeEasingValueType::setPeriod(qreal period)
easing.setPeriod(period);
}
+void QDeclarativeEasingValueType::setBezierCurve(const QVariantList &customCurveVariant)
+{
+ if (customCurveVariant.isEmpty())
+ return;
+
+ QVariantList variantList = customCurveVariant;
+ if ((variantList.count() % 6) == 0) {
+ bool allRealsOk = true;
+ QList<qreal> reals;
+ for (int i = 0; i < variantList.count(); i++) {
+ bool ok;
+ const qreal real = variantList.at(i).toReal(&ok);
+ reals.append(real);
+ if (!ok)
+ allRealsOk = false;
+ }
+ if (allRealsOk) {
+ QEasingCurve newEasingCurve(QEasingCurve::BezierSpline);
+ for (int i = 0; i < reals.count() / 6; i++) {
+ const qreal c1x = reals.at(i * 6);
+ const qreal c1y = reals.at(i * 6 + 1);
+ const qreal c2x = reals.at(i * 6 + 2);
+ const qreal c2y = reals.at(i * 6 + 3);
+ const qreal c3x = reals.at(i * 6 + 4);
+ const qreal c3y = reals.at(i * 6 + 5);
+
+ const QPointF c1(c1x, c1y);
+ const QPointF c2(c2x, c2y);
+ const QPointF c3(c3x, c3y);
+
+ newEasingCurve.addCubicBezierSegment(c1, c2, c3);
+ easing = newEasingCurve;
+ }
+ }
+ }
+}
+
+QVariantList QDeclarativeEasingValueType::bezierCurve() const
+{
+ QVariantList rv;
+ QList<QPointF> points = easing.cubicBezierSpline();
+ for (int ii = 0; ii < points.count(); ++ii)
+ rv << QVariant(points.at(ii).x()) << QVariant(points.at(ii).y());
+ return rv;
+}
+
QDeclarativeFontValueType::QDeclarativeFontValueType(QObject *parent)
: QDeclarativeValueType(parent), pixelSizeSet(false), pointSizeSet(false)
{
diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h
index 1feab4147b..9f00d97800 100644
--- a/src/declarative/qml/qdeclarativevaluetype_p.h
+++ b/src/declarative/qml/qdeclarativevaluetype_p.h
@@ -456,6 +456,7 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeEasingValueType : public QDeclara
Q_PROPERTY(qreal amplitude READ amplitude WRITE setAmplitude)
Q_PROPERTY(qreal overshoot READ overshoot WRITE setOvershoot)
Q_PROPERTY(qreal period READ period WRITE setPeriod)
+ Q_PROPERTY(QVariantList bezierCurve READ bezierCurve WRITE setBezierCurve)
public:
enum Type {
Linear = QEasingCurve::Linear,
@@ -480,7 +481,8 @@ public:
InBounce = QEasingCurve::InBounce, OutBounce = QEasingCurve::OutBounce,
InOutBounce = QEasingCurve::InOutBounce, OutInBounce = QEasingCurve::OutInBounce,
InCurve = QEasingCurve::InCurve, OutCurve = QEasingCurve::OutCurve,
- SineCurve = QEasingCurve::SineCurve, CosineCurve = QEasingCurve::CosineCurve
+ SineCurve = QEasingCurve::SineCurve, CosineCurve = QEasingCurve::CosineCurve,
+ Bezier = QEasingCurve::BezierSpline
};
QDeclarativeEasingValueType(QObject *parent = 0);
@@ -500,6 +502,9 @@ public:
void setAmplitude(qreal);
void setOvershoot(qreal);
void setPeriod(qreal);
+ void setBezierCurve(const QVariantList &);
+ QVariantList bezierCurve() const;
+
private:
QEasingCurve easing;
diff --git a/tools/qmleasing/TextField.qml b/tools/qmleasing/TextField.qml
new file mode 100644
index 0000000000..d99d4694b5
--- /dev/null
+++ b/tools/qmleasing/TextField.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+FocusScope {
+ width: input.x + input.width
+ height: border.height
+
+ property alias name: name.text
+ property alias text: input.text
+
+ Text {
+ id: name
+ height: parent.height
+ }
+
+ TextInput {
+ id: input
+ anchors.left: name.right
+ anchors.leftMargin: 4
+ focus: true
+ width: 50
+ horizontalAlignment: "AlignRight"
+ Rectangle {
+ id: border
+ x: -2; y: -2
+ width: parent.width + 4
+ height: parent.height + 4
+ color: "transparent"
+ border.color: input.activeFocus?"green":"lightgreen"
+
+ border.width: 3
+ radius: 5
+ }
+ }
+}
+
diff --git a/tools/qmleasing/easing.qml b/tools/qmleasing/easing.qml
new file mode 100644
index 0000000000..fe5f8312a4
--- /dev/null
+++ b/tools/qmleasing/easing.qml
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import EasingPlot 1.0
+
+Rectangle {
+ width: 775; height: 550
+
+ function precision(n)
+ {
+ var str = n.toPrecision(3);
+ while (str.length > 1 && (str[str.length - 1] == "0" || str[str.length - 1] == "."))
+ str = str.substr(0, str.length - 1);
+ return str;
+ }
+
+ function updateEasing() {
+ var ini = Math.min(100, Math.max(0, Number(in_inf.text)));
+ var outi = Math.min(100, Math.max(0, Number(out_inf.text)));
+
+ var ins = Number(in_slope.text);
+ var outs = Number(out_slope.text);
+
+ var p1 = [ (ini / 100), (ini / 100) * ins ];
+ var p2 = [ 1 - (outi / 100), 1 - (outi / 100) * outs ];
+
+ text.text = "[ " + precision(p1[0]) + ", " + precision(p1[1]) + ", " + precision(p2[0]) + ", " + precision(p2[1]) + ", 1, 1 ]";
+ }
+
+ Rectangle {
+ id: border
+ width: 500; height: 500
+ x: 25; y: 25
+ border.color: "lightsteelblue"
+ border.width: 3
+ radius: 5
+ color: "transparent"
+
+ EasingPlot {
+ id: plot
+
+ anchors.centerIn: parent
+ width: parent.width - 10
+ height: parent.height - 10
+
+ easing.type: "Bezier"
+ easing.bezierCurve: eval(text.text)
+ }
+
+ }
+
+ Text {
+ text: "<u>After Effects curve</u>"
+ anchors.horizontalCenter: text.horizontalCenter
+ anchors.bottom: column.top
+ anchors.bottomMargin: 14
+ }
+
+ Column {
+ id: column
+
+ y: 70
+ anchors.right: parent.right
+ anchors.rightMargin: 25
+ spacing: 5
+ TextField {
+ id: in_inf
+ focus: true
+ name: "Input influence:"
+ text: "33"
+ anchors.right: parent.right
+ KeyNavigation.tab: in_slope
+ KeyNavigation.backtab: text
+ onTextChanged: updateEasing();
+ }
+ TextField {
+ id: in_slope
+ name: "Input slope:"
+ text: "0"
+ anchors.right: parent.right
+ KeyNavigation.tab: out_inf
+ KeyNavigation.backtab: in_inf
+ onTextChanged: updateEasing();
+ }
+ TextField {
+ id: out_inf
+ name: "Output influence:"
+ text: "33"
+ anchors.right: parent.right
+ KeyNavigation.tab: out_slope
+ KeyNavigation.backtab: in_slope
+ onTextChanged: updateEasing();
+ }
+ TextField {
+ id: out_slope
+ name: "Output slope:"
+ text: "0"
+ anchors.right: parent.right
+ KeyNavigation.tab: text
+ KeyNavigation.backtab: out_info
+ onTextChanged: updateEasing();
+ }
+ }
+
+ Text {
+ text: "<u>QML Bezier curve</u>"
+ anchors.horizontalCenter: text.horizontalCenter
+ anchors.bottom: text.top
+ anchors.bottomMargin: 10
+ }
+
+ TextEdit {
+ id: text
+ x: 200
+ width: 200
+ height: 200
+
+ Rectangle {
+ x: -2; y: -2
+ width: parent.width + 4
+ height: parent.height + 4
+ color: "transparent"
+ border.color: text.activeFocus?"green":"lightgreen"
+
+ border.width: 3
+ radius: 5
+ }
+
+ wrapMode: "WordWrap"
+
+ anchors.top: column.bottom
+ anchors.topMargin: 50
+ anchors.right: column.right
+ KeyNavigation.tab: in_inf
+ KeyNavigation.backtab: out_slope
+ }
+
+
+ Item {
+ anchors.left: text.left
+ anchors.top: text.bottom
+ anchors.topMargin: 35
+ width: text.width
+ height: rect.height
+
+ Rectangle {
+ color: "gray"
+ width: 50; height: 50
+ id: rect
+
+ NumberAnimation on x {
+ id: animation
+ running: false
+ easing: plot.easing
+ duration: 1000
+ }
+
+ radius: 5
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (rect.x < 5) {
+ animation.to = text.width - rect.width;
+ } else {
+ animation.to = 0;
+ }
+ animation.start();
+ }
+ }
+
+ Text {
+ anchors.centerIn: parent
+ text: "Click to Try"
+ }
+ }
+
+ Component.onCompleted: updateEasing();
+}
diff --git a/tools/qmleasing/main.cpp b/tools/qmleasing/main.cpp
new file mode 100644
index 0000000000..a9f1da41d4
--- /dev/null
+++ b/tools/qmleasing/main.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QPainter>
+#include <QQuickView>
+#include <QApplication>
+#include <QEasingCurve>
+#include <QQuickPaintedItem>
+
+class EasingPlot : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged);
+
+public:
+ EasingPlot();
+
+ QEasingCurve easing() const;
+ void setEasing(const QEasingCurve &);
+
+signals:
+ void easingChanged();
+
+protected:
+ virtual void paint(QPainter *painter);
+
+private:
+ QEasingCurve m_easing;
+};
+
+EasingPlot::EasingPlot()
+{
+}
+
+QEasingCurve EasingPlot::easing() const
+{
+ return m_easing;
+}
+
+void EasingPlot::setEasing(const QEasingCurve &e)
+{
+ if (m_easing == e)
+ return;
+
+ m_easing = e;
+ emit easingChanged();
+
+ update();
+}
+
+void EasingPlot::paint(QPainter *painter)
+{
+ QPointF lastPoint(0, 0);
+
+ for (int ii = 1; ii <= 100; ++ii) {
+ qreal value = m_easing.valueForProgress(qreal(ii) / 100.);
+
+ QPointF currentPoint(width() * qreal(ii) / 100., value * (height() - 1));
+ painter->drawLine(lastPoint, currentPoint);
+
+ lastPoint = currentPoint;
+ }
+}
+
+int main(int argc, char ** argv)
+{
+ QApplication app(argc, argv);
+
+ qmlRegisterType<EasingPlot>("EasingPlot", 1, 0, "EasingPlot");
+
+ QQuickView view;
+ view.setSource(QUrl("qrc:/easing.qml"));
+ view.show();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tools/qmleasing/qmleasing.pro b/tools/qmleasing/qmleasing.pro
new file mode 100644
index 0000000000..4a64fe91e0
--- /dev/null
+++ b/tools/qmleasing/qmleasing.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += .
+
+QT += declarative widgets
+CONFIG -= app_bundle
+
+# Input
+SOURCES += main.cpp
+
+RESOURCES = $$PWD/resources.qrc
diff --git a/tools/qmleasing/resources.qrc b/tools/qmleasing/resources.qrc
new file mode 100644
index 0000000000..c7a67b838c
--- /dev/null
+++ b/tools/qmleasing/resources.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>easing.qml</file>
+ <file>TextField.qml</file>
+ </qresource>
+</RCC>
diff --git a/tools/tools.pro b/tools/tools.pro
index ae2ca0cd3b..46d381dee9 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -1,5 +1,5 @@
TEMPLATE = subdirs
-SUBDIRS += qmlviewer qmlscene qmlplugindump qmlmin
+SUBDIRS += qmlviewer qmlscene qmlplugindump qmlmin qmleasing
contains(QT_CONFIG, qmltest): SUBDIRS += qmltestrunner