From 4b9a44274563b8cc0a9d98f86893df3f31f01307 Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Wed, 11 Dec 2013 07:22:49 +0100 Subject: Add QQuickMatrix4x4, a way to specify a matrix transform in QML. 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 Reviewed-by: Robin Burchell Reviewed-by: Gunnar Sletta --- src/quick/items/qquickitemsmodule.cpp | 1 + src/quick/items/qquicktranslate.cpp | 75 +++++++++++++++++++++++++ src/quick/items/qquicktranslate_p.h | 23 ++++++++ tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 4 +- 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 8b2b5d4fc8..96746223ce 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -184,6 +184,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType(uri,major,minor,"Translate"); qmlRegisterType(uri,major,minor,"Rotation"); qmlRegisterType(uri,major,minor,"Scale"); + qmlRegisterType(uri,2,4,"Matrix4x4"); qmlRegisterType(uri,major,minor,"Text"); qmlRegisterType(uri,major,minor,"TextEdit"); qmlRegisterType(uri,2,1,"TextEdit"); diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp index f1b716cf5b..5c61fb33f8 100644 --- a/src/quick/items/qquicktranslate.cpp +++ b/src/quick/items/qquicktranslate.cpp @@ -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 diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h index d7843fe103..dd93275a28 100644 --- a/src/quick/items/qquicktranslate_p.h +++ b/src/quick/items/qquicktranslate_p.h @@ -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) diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 8a4ed5ae4c..64795f9ebe 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -1972,6 +1972,8 @@ void tst_QQuickItem::transforms_data() QTest::addColumn("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(component.create()); QVERIFY(item); QCOMPARE(item->itemTransform(0,0), transform); -- cgit v1.2.3