Add QQuickMatrix4x4, a way to specify a matrix transform in QML.
authorErik Larsson <erik@ortogonal.com>
Wed, 11 Dec 2013 06:22:49 +0000 (07:22 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 7 Jan 2014 13:44:50 +0000 (14:44 +0100)
Add QQuickMatrix4x4 which makes it possible to specify a 4x4
matrix tranformation directly in QML instead of decomposing the
transformation into rotation, scale etc. It does NOT replace anything,
just adds a new way of specifying a tranformation of an Item.

Change-Id: I1b123778d1d458dfe4314cdb4f0fc99fd8a4c86a
Reviewed-by: Alan Alpert <aalpert@blackberry.com>
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
src/quick/items/qquickitemsmodule.cpp
src/quick/items/qquicktranslate.cpp
src/quick/items/qquicktranslate_p.h
tests/auto/quick/qquickitem2/tst_qquickitem.cpp

index 8b2b5d4..9674622 100644 (file)
@@ -184,6 +184,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
     qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
     qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
     qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
+    qmlRegisterType<QQuickMatrix4x4>(uri,2,4,"Matrix4x4");
     qmlRegisterType<QQuickText>(uri,major,minor,"Text");
     qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit");
     qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
index f1b716c..5c61fb3 100644 (file)
@@ -458,4 +458,79 @@ void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
     matrix->translate(-d->origin);
 }
 
+class QQuickMatrix4x4Private : public QQuickTransformPrivate
+{
+public:
+    QQuickMatrix4x4Private()
+        : matrix() {}
+    QMatrix4x4 matrix;
+};
+
+/*!
+    \qmltype Matrix4x4
+    \instantiates QQuickMatrix4x4
+    \inqmlmodule QtQuick
+    \ingroup qtquick-visual-transforms
+    \brief Provides a way to apply a 4x4 tranformation matrix to an \l Item
+
+    The Matrix4x4 type provides a way to apply a transformation to an
+    \l Item through a 4x4 matrix.
+
+    It allows for a combination of rotation, scale, translatation and shearing
+    by using just one tranformation provided in a 4x4-matrix.
+
+    The following example rotates a Rectangle 45 degress (PI/4):
+
+    \qml
+    Rectangle {
+        width: 100
+        height: 100
+        color: "red"
+
+        transform: Matrix4x4 {
+            property real a: Math.PI / 4
+            matrix: Qt.matrix4x4(Math.cos(a), -Math.sin(a), 0, 0,
+                                 Math.sin(a),  Math.cos(a), 0, 0,
+                                 0,           0,            1, 0,
+                                 0,           0,            0, 1)
+        }
+    }
+    \endqml
+*/
+QQuickMatrix4x4::QQuickMatrix4x4(QObject *parent)
+    : QQuickTransform(*new QQuickMatrix4x4Private, parent)
+{
+}
+
+QQuickMatrix4x4::~QQuickMatrix4x4()
+{
+}
+
+/*!
+    \qmlproperty QMatrix4x4 QtQuick::Matrix4x4::matrix
+
+    4x4-matrix which will be used in the tranformation of an \l Item
+*/
+QMatrix4x4 QQuickMatrix4x4::matrix() const
+{
+    Q_D(const QQuickMatrix4x4);
+    return d->matrix;
+}
+
+void QQuickMatrix4x4::setMatrix(const QMatrix4x4 &matrix)
+{
+    Q_D(QQuickMatrix4x4);
+    if (d->matrix == matrix)
+         return;
+    d->matrix = matrix;
+    update();
+    emit matrixChanged();
+}
+
+void QQuickMatrix4x4::applyTo(QMatrix4x4 *matrix) const
+{
+    Q_D(const QQuickMatrix4x4);
+    *matrix *= d->matrix;
+}
+
 QT_END_NAMESPACE
index d7843fe..dd93275 100644 (file)
@@ -148,6 +148,29 @@ private:
     Q_DECLARE_PRIVATE(QQuickRotation)
 };
 
+class QQuickMatrix4x4Private;
+class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged)
+public:
+    QQuickMatrix4x4(QObject *parent = 0);
+    ~QQuickMatrix4x4();
+
+    QMatrix4x4 matrix() const;
+    void setMatrix(const QMatrix4x4& matrix);
+
+    void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+    void matrixChanged();
+
+private:
+    Q_DECLARE_PRIVATE(QQuickMatrix4x4)
+};
+
+
 QT_END_NAMESPACE
 
 QML_DECLARE_TYPE(QQuickTranslate)
index 8a4ed5a..64795f9 100644 (file)
@@ -1972,6 +1972,8 @@ void tst_QQuickItem::transforms_data()
     QTest::addColumn<QTransform>("transform");
     QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }")
         << QTransform(1,0,0,0,1,0,10,20,1);
+    QTest::newRow("matrix4x4") << QByteArray("Matrix4x4 { matrix: Qt.matrix4x4(1,0,0,10, 0,1,0,15, 0,0,1,0, 0,0,0,1) }")
+        << QTransform(1,0,0,0,1,0,10,15,1);
     QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }")
         << QTransform(0,1,0,-1,0,0,0,0,1);
     QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2  }")
@@ -1985,7 +1987,7 @@ void tst_QQuickItem::transforms()
     QFETCH(QByteArray, qml);
     QFETCH(QTransform, transform);
     QQmlComponent component(&engine);
-    component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
+    component.setData("import QtQuick 2.4\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
     QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
     QVERIFY(item);
     QCOMPARE(item->itemTransform(0,0), transform);