aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2012-06-26 18:02:35 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-11 01:46:52 +0200
commitf5cb65b35e076facbce45e896902a34da7036135 (patch)
tree7575065fde2d0c14c379a992bf8b3593e21f4881 /src/qml/qml
parent5376906de58e1c25c77b7a61800365b6e542542f (diff)
Fix broken value-type support by allowing property definition
In QtQuick 1.x the "variant" property type was supported, which could be used to allow value type properties to be defined in QML. In QtQuick 2.0, we have deprecated the "variant" property, but its replacement ("var") is not suited for defining lightweight C++ type values (such as QColor, QFont, QRectF, QVector3D etc). This commit allows those QML basic types to be used in QML once more, by supporting them in the property definition syntax. Note that since some value types are provided by QtQuick and others are provided by QtQml, if a client imports only QtQml they can define but not use properties of certain types (eg, font). Task-number: QTBUG-21034 Task-number: QTBUG-18217 Change-Id: Ia951a8522f223408d27293bb96c276281a710277 Reviewed-by: Matthew Vogt <matthew.vogt@nokia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlcompiler.cpp8
-rw-r--r--src/qml/qml/qqmlengine.cpp14
-rw-r--r--src/qml/qml/qqmlglobal.cpp37
-rw-r--r--src/qml/qml/qqmlglobal_p.h13
-rw-r--r--src/qml/qml/qqmlscript.cpp8
-rw-r--r--src/qml/qml/qqmlscript_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp18
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h14
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp66
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp102
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h4
-rw-r--r--src/qml/qml/v8/qv8engine.cpp6
-rw-r--r--src/qml/qml/v8/qv8valuetypewrapper.cpp9
-rw-r--r--src/qml/qml/v8/qv8valuetypewrapper_p.h1
14 files changed, 269 insertions, 35 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 6f2792570f..539b6c402a 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -2806,10 +2806,18 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
{ Object::DynamicProperty::String, QMetaType::QString },
{ Object::DynamicProperty::Url, QMetaType::QUrl },
{ Object::DynamicProperty::Color, QMetaType::QColor },
+ { Object::DynamicProperty::Font, QMetaType::QFont },
{ Object::DynamicProperty::Time, QMetaType::QTime },
{ Object::DynamicProperty::Date, QMetaType::QDate },
{ Object::DynamicProperty::DateTime, QMetaType::QDateTime },
{ Object::DynamicProperty::Rect, QMetaType::QRectF },
+ { Object::DynamicProperty::Point, QMetaType::QPointF },
+ { Object::DynamicProperty::Size, QMetaType::QSizeF },
+ { Object::DynamicProperty::Vector2D, QMetaType::QVector2D },
+ { Object::DynamicProperty::Vector3D, QMetaType::QVector3D },
+ { Object::DynamicProperty::Vector4D, QMetaType::QVector4D },
+ { Object::DynamicProperty::Matrix4x4, QMetaType::QMatrix4x4 },
+ { Object::DynamicProperty::Quaternion, QMetaType::QQuaternion }
};
static const int builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 229a071789..e3db9d478a 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -271,16 +271,26 @@ the \l Qt::LeftButton and \l Qt::RightButton enumeration values as \c Qt.LeftBut
\section1 Types
+
The Qt object also contains helper functions for creating objects of specific
data types. This is primarily useful when setting the properties of an item
when the property has one of the following types:
-
\list
-\li \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()}
\li \c rect - use \l{Qt::rect()}{Qt.rect()}
\li \c point - use \l{Qt::point()}{Qt.point()}
\li \c size - use \l{Qt::size()}{Qt.size()}
+\endlist
+
+If the QtQuick module has been imported, the following helper functions for
+creating objects of specific data types are also available for clients to use:
+\list
+\li \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()}
+\li \c font - use \l{Qt::font()}{Qt.font()}
+\li \c vector2d - use \l{Qt::vector2d()}{Qt.vector2d()}
\li \c vector3d - use \l{Qt::vector3d()}{Qt.vector3d()}
+\li \c vector4d - use \l{Qt::vector4d()}{Qt.vector4d()}
+\li \c quaternion - use \l{Qt::quaternion()}{Qt.quaternion()}
+\li \c matrix4x4 - use \l{Qt::matrix4x4()}{Qt.matrix4x4()}
\endlist
There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 6f4942963f..0ebc802dec 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -175,42 +175,58 @@ QVariant QQmlValueTypeProvider::createVariantFromString(int type, const QString
return QVariant();
}
-bool QQmlValueTypeProvider::equalValueType(int type, const void *lhs, const void *rhs)
+QVariant QQmlValueTypeProvider::createVariantFromJsObject(int type, QQmlV8Handle obj, QV8Engine *e, bool *ok)
+{
+ QVariant v;
+
+ QQmlValueTypeProvider *p = this;
+ do {
+ if (p->variantFromJsObject(type, obj, e, &v)) {
+ if (ok) *ok = true;
+ return v;
+ }
+ } while ((p = p->next));
+
+ if (ok) *ok = false;
+ return QVariant();
+}
+
+bool QQmlValueTypeProvider::equalValueType(int type, const void *lhs, const void *rhs, size_t rhsSize)
{
Q_ASSERT(lhs);
Q_ASSERT(rhs);
QQmlValueTypeProvider *p = this;
do {
- if (p->equal(type, lhs, rhs))
+ if (p->equal(type, lhs, rhs, rhsSize))
return true;
} while ((p = p->next));
return false;
}
-bool QQmlValueTypeProvider::storeValueType(int type, const void *src, void *dst, size_t n)
+bool QQmlValueTypeProvider::storeValueType(int type, const void *src, void *dst, size_t dstSize)
{
Q_ASSERT(src);
Q_ASSERT(dst);
QQmlValueTypeProvider *p = this;
do {
- if (p->store(type, src, dst, n))
+ if (p->store(type, src, dst, dstSize))
return true;
} while ((p = p->next));
return false;
}
-bool QQmlValueTypeProvider::readValueType(int srcType, const void *src, int dstType, void *dst)
+bool QQmlValueTypeProvider::readValueType(int srcType, const void *src, size_t srcSize, int dstType, void *dst)
{
Q_ASSERT(src);
Q_ASSERT(dst);
QQmlValueTypeProvider *p = this;
do {
- if (p->read(srcType, src, dstType, dst))
+ if (p->read(srcType, src, srcSize, dstType, dst))
return true;
} while ((p = p->next));
@@ -240,9 +256,10 @@ bool QQmlValueTypeProvider::createFromString(int, const QString &, void *, size_
bool QQmlValueTypeProvider::createStringFrom(int, const void *, QString *) { return false; }
bool QQmlValueTypeProvider::variantFromString(const QString &, QVariant *) { return false; }
bool QQmlValueTypeProvider::variantFromString(int, const QString &, QVariant *) { return false; }
-bool QQmlValueTypeProvider::equal(int, const void *, const void *) { return false; }
+bool QQmlValueTypeProvider::variantFromJsObject(int, QQmlV8Handle, QV8Engine *, QVariant *) { return false; }
+bool QQmlValueTypeProvider::equal(int, const void *, const void *, size_t) { return false; }
bool QQmlValueTypeProvider::store(int, const void *, void *, size_t) { return false; }
-bool QQmlValueTypeProvider::read(int, const void *, int, void *) { return false; }
+bool QQmlValueTypeProvider::read(int, const void *, size_t, int, void *) { return false; }
bool QQmlValueTypeProvider::write(int, const void *, void *, size_t) { return false; }
static QQmlValueTypeProvider *valueTypeProvider = 0;
@@ -266,10 +283,6 @@ Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *newPr
Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider(void)
{
- if (valueTypeProvider == 0) {
- qWarning() << "Warning: QQml_valueTypeProvider: no value type provider has been set!";
- }
-
static QQmlValueTypeProvider **providerPtr = getValueTypeProvider();
return *providerPtr;
}
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index b3e8eb6421..b10457bd29 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -46,6 +46,7 @@
#include <QtCore/QObject>
#include <private/qqmlpropertycache_p.h>
#include <private/qmetaobject_p.h>
+#include <private/qv8engine_p.h>
QT_BEGIN_HEADER
@@ -208,7 +209,7 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
class QQmlValueType;
-
+class QV8Engine;
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
{
public:
@@ -226,10 +227,11 @@ public:
QVariant createVariantFromString(const QString &);
QVariant createVariantFromString(int, const QString &, bool *);
+ QVariant createVariantFromJsObject(int, QQmlV8Handle, QV8Engine *, bool*);
- bool equalValueType(int, const void *, const void *);
+ bool equalValueType(int, const void *, const void *, size_t);
bool storeValueType(int, const void *, void *, size_t);
- bool readValueType(int, const void *, int, void *);
+ bool readValueType(int, const void *, size_t, int, void *);
bool writeValueType(int, const void *, void *, size_t);
private:
@@ -245,10 +247,11 @@ private:
virtual bool variantFromString(const QString &, QVariant *);
virtual bool variantFromString(int, const QString &, QVariant *);
+ virtual bool variantFromJsObject(int, QQmlV8Handle, QV8Engine *, QVariant *);
- virtual bool equal(int, const void *, const void *);
+ virtual bool equal(int, const void *, const void *, size_t);
virtual bool store(int, const void *, void *, size_t);
- virtual bool read(int, const void *, int, void *);
+ virtual bool read(int, const void *, size_t, int, void *);
virtual bool write(int, const void *, void *, size_t);
friend Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *);
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
index f4a928c784..469b5d5291 100644
--- a/src/qml/qml/qqmlscript.cpp
+++ b/src/qml/qml/qqmlscript.cpp
@@ -912,6 +912,14 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
// { "date", strlen("date"), Object::DynamicProperty::Date },
{ "date", strlen("date"), Object::DynamicProperty::DateTime },
{ "rect", strlen("rect"), Object::DynamicProperty::Rect },
+ { "point", strlen("point"), Object::DynamicProperty::Point },
+ { "size", strlen("size"), Object::DynamicProperty::Size },
+ { "font", strlen("font"), Object::DynamicProperty::Font },
+ { "vector2d", strlen("vector2d"), Object::DynamicProperty::Vector2D },
+ { "vector3d", strlen("vector3d"), Object::DynamicProperty::Vector3D },
+ { "vector4d", strlen("vector4d"), Object::DynamicProperty::Vector4D },
+ { "quaternion", strlen("quaternion"), Object::DynamicProperty::Quaternion },
+ { "matrix4x4", strlen("matrix4x4"), Object::DynamicProperty::Matrix4x4 },
{ "variant", strlen("variant"), Object::DynamicProperty::Variant },
{ "var", strlen("var"), Object::DynamicProperty::Var }
};
diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h
index 486c573754..718faa33ca 100644
--- a/src/qml/qml/qqmlscript_p.h
+++ b/src/qml/qml/qqmlscript_p.h
@@ -381,7 +381,9 @@ public:
DynamicProperty();
enum Type { Var, Variant, Int, Bool, Real, String, Url, Color,
- Time, Date, DateTime, Rect, Alias, Custom, CustomList };
+ Font, Time, Date, DateTime, Rect, Point, Size,
+ Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion,
+ Alias, Custom, CustomList };
quint32 isDefaultProperty:1;
quint32 isReadOnly:1;
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index c0759a31b4..165024adfe 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -112,14 +112,14 @@ QQmlValueType *QQmlValueTypeFactory::valueType(int t)
return rv;
}
-QQmlValueType::QQmlValueType(QObject *parent)
-: QObject(parent)
+QQmlValueType::QQmlValueType(int userType, QObject *parent)
+: QObject(parent), m_userType(userType)
{
}
QQmlPointFValueType::QQmlPointFValueType(QObject *parent)
- : QQmlValueTypeBase<QPointF>(parent)
+ : QQmlValueTypeBase<QPointF>(QMetaType::QPointF, parent)
{
}
@@ -150,7 +150,7 @@ void QQmlPointFValueType::setY(qreal y)
QQmlPointValueType::QQmlPointValueType(QObject *parent)
- : QQmlValueTypeBase<QPoint>(parent)
+ : QQmlValueTypeBase<QPoint>(QMetaType::QPoint, parent)
{
}
@@ -181,7 +181,7 @@ void QQmlPointValueType::setY(int y)
QQmlSizeFValueType::QQmlSizeFValueType(QObject *parent)
- : QQmlValueTypeBase<QSizeF>(parent)
+ : QQmlValueTypeBase<QSizeF>(QMetaType::QSizeF, parent)
{
}
@@ -212,7 +212,7 @@ void QQmlSizeFValueType::setHeight(qreal h)
QQmlSizeValueType::QQmlSizeValueType(QObject *parent)
- : QQmlValueTypeBase<QSize>(parent)
+ : QQmlValueTypeBase<QSize>(QMetaType::QSize, parent)
{
}
@@ -243,7 +243,7 @@ void QQmlSizeValueType::setHeight(int h)
QQmlRectFValueType::QQmlRectFValueType(QObject *parent)
- : QQmlValueTypeBase<QRectF>(parent)
+ : QQmlValueTypeBase<QRectF>(QMetaType::QRectF, parent)
{
}
@@ -294,7 +294,7 @@ void QQmlRectFValueType::setHeight(qreal h)
QQmlRectValueType::QQmlRectValueType(QObject *parent)
- : QQmlValueTypeBase<QRect>(parent)
+ : QQmlValueTypeBase<QRect>(QMetaType::QRect, parent)
{
}
@@ -345,7 +345,7 @@ void QQmlRectValueType::setHeight(int h)
QQmlEasingValueType::QQmlEasingValueType(QObject *parent)
- : QQmlValueTypeBase<QEasingCurve>(parent)
+ : QQmlValueTypeBase<QEasingCurve>(QMetaType::QEasingCurve, parent)
{
}
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index f704da2c8e..02be333037 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -69,7 +69,7 @@ class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject
{
Q_OBJECT
public:
- QQmlValueType(QObject *parent = 0);
+ QQmlValueType(int userType, QObject *parent = 0);
virtual void read(QObject *, int) = 0;
virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags flags) = 0;
virtual QVariant value() = 0;
@@ -80,6 +80,11 @@ public:
virtual void onLoad() {}
+ inline int userType() const
+ {
+ return m_userType;
+ }
+
protected:
inline void readProperty(QObject *obj, int idx, void *p)
{
@@ -94,6 +99,9 @@ protected:
void *a[] = { p, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
+
+private:
+ int m_userType;
};
template <typename T>
@@ -102,8 +110,8 @@ class QQmlValueTypeBase : public QQmlValueType
public:
typedef T ValueType;
- QQmlValueTypeBase(QObject *parent)
- : QQmlValueType(parent)
+ QQmlValueTypeBase(int userType, QObject *parent)
+ : QQmlValueType(userType, parent)
{
}
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 1c07dd676e..c982856453 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -101,6 +101,8 @@ public:
inline const QDate &asQDate();
inline const QDateTime &asQDateTime();
inline const QRectF &asQRectF();
+ inline const QPointF &asQPointF();
+ inline const QSizeF &asQSizeF();
inline const QJSValue &asQJSValue();
inline void setValue(QObject *v, QQmlVMEMetaObject *target, int index);
@@ -114,6 +116,8 @@ public:
inline void setValue(const QDate &);
inline void setValue(const QDateTime &);
inline void setValue(const QRectF &);
+ inline void setValue(const QPointF &);
+ inline void setValue(const QSizeF &);
inline void setValue(const QJSValue &);
inline void setDataType(int t);
@@ -176,6 +180,12 @@ void QQmlVMEVariant::cleanup()
} else if (type == QMetaType::QRectF) {
((QRectF *)dataPtr())->~QRectF();
type = QVariant::Invalid;
+ } else if (type == QMetaType::QPointF) {
+ ((QPointF *)dataPtr())->~QPointF();
+ type = QVariant::Invalid;
+ } else if (type == QMetaType::QSizeF) {
+ ((QSizeF *)dataPtr())->~QSizeF();
+ type = QVariant::Invalid;
} else if (type == qMetaTypeId<QVariant>()) {
((QVariant *)dataPtr())->~QVariant();
type = QVariant::Invalid;
@@ -297,6 +307,22 @@ const QRectF &QQmlVMEVariant::asQRectF()
return *(QRectF *)(dataPtr());
}
+const QSizeF &QQmlVMEVariant::asQSizeF()
+{
+ if (type != QMetaType::QSizeF)
+ setValue(QSizeF());
+
+ return *(QSizeF *)(dataPtr());
+}
+
+const QPointF &QQmlVMEVariant::asQPointF()
+{
+ if (type != QMetaType::QPointF)
+ setValue(QPointF());
+
+ return *(QPointF *)(dataPtr());
+}
+
const QJSValue &QQmlVMEVariant::asQJSValue()
{
if (type != qMetaTypeId<QJSValue>())
@@ -419,6 +445,28 @@ void QQmlVMEVariant::setValue(const QRectF &v)
}
}
+void QQmlVMEVariant::setValue(const QPointF &v)
+{
+ if (type != QMetaType::QPointF) {
+ cleanup();
+ type = QMetaType::QPointF;
+ new (dataPtr()) QPointF(v);
+ } else {
+ *(QPointF *)(dataPtr()) = v;
+ }
+}
+
+void QQmlVMEVariant::setValue(const QSizeF &v)
+{
+ if (type != QMetaType::QSizeF) {
+ cleanup();
+ type = QMetaType::QSizeF;
+ new (dataPtr()) QSizeF(v);
+ } else {
+ *(QSizeF *)(dataPtr()) = v;
+ }
+}
+
void QQmlVMEVariant::setValue(const QJSValue &v)
{
if (type != qMetaTypeId<QJSValue>()) {
@@ -685,6 +733,12 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
case QVariant::RectF:
*reinterpret_cast<QRectF *>(a[0]) = data[id].asQRectF();
break;
+ case QVariant::SizeF:
+ *reinterpret_cast<QSizeF *>(a[0]) = data[id].asQSizeF();
+ break;
+ case QVariant::PointF:
+ *reinterpret_cast<QPointF *>(a[0]) = data[id].asQPointF();
+ break;
case QMetaType::QObjectStar:
*reinterpret_cast<QObject **>(a[0]) = data[id].asQObject();
break;
@@ -692,7 +746,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
*reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
break;
default:
- QQml_valueTypeProvider()->readValueType(data[id].dataType(), data[id].dataPtr(), t, a[0]);
+ QQml_valueTypeProvider()->readValueType(data[id].dataType(), data[id].dataPtr(), data->dataSize(), t, a[0]);
break;
}
if (t == qMetaTypeId<QQmlListProperty<QObject> >()) {
@@ -739,6 +793,14 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
needActivate = *reinterpret_cast<QRectF *>(a[0]) != data[id].asQRectF();
data[id].setValue(*reinterpret_cast<QRectF *>(a[0]));
break;
+ case QVariant::SizeF:
+ needActivate = *reinterpret_cast<QSizeF *>(a[0]) != data[id].asQSizeF();
+ data[id].setValue(*reinterpret_cast<QSizeF *>(a[0]));
+ break;
+ case QVariant::PointF:
+ needActivate = *reinterpret_cast<QPointF *>(a[0]) != data[id].asQPointF();
+ data[id].setValue(*reinterpret_cast<QPointF *>(a[0]));
+ break;
case QMetaType::QObjectStar:
needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject();
data[id].setValue(*reinterpret_cast<QObject **>(a[0]), this, id);
@@ -748,7 +810,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
break;
default:
data[id].ensureValueType(t);
- needActivate = !QQml_valueTypeProvider()->equalValueType(t, a[0], data[id].dataPtr());
+ needActivate = !QQml_valueTypeProvider()->equalValueType(t, a[0], data[id].dataPtr(), data[id].dataSize());
QQml_valueTypeProvider()->writeValueType(t, a[0], data[id].dataPtr(), data[id].dataSize());
break;
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index deaf5f5c80..5abc7cf7bb 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -495,13 +495,30 @@ v8::Handle<v8::Value> size(const v8::Arguments &args)
}
/*!
+\qmlmethod Qt::vector2d(real x, real y)
+Returns a Vector2D with the specified \c x and \c y.
+*/
+v8::Handle<v8::Value> vector2d(const v8::Arguments &args)
+{
+ if (args.Length() != 2)
+ V8THROW_ERROR("Qt.vector2d(): Invalid arguments");
+
+ float xy[3];
+ xy[0] = args[0]->ToNumber()->Value();
+ xy[1] = args[1]->ToNumber()->Value();
+
+ const void *params[] = { xy };
+ return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
+}
+
+/*!
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
v8::Handle<v8::Value> vector3d(const v8::Arguments &args)
{
if (args.Length() != 3)
- V8THROW_ERROR("Qt.vector(): Invalid arguments");
+ V8THROW_ERROR("Qt.vector3d(): Invalid arguments");
float xyz[3];
xyz[0] = args[0]->ToNumber()->Value();
@@ -532,6 +549,89 @@ v8::Handle<v8::Value> vector4d(const v8::Arguments &args)
}
/*!
+\qmlmethod Qt::quaternion(real scalar, real x, real y, real z)
+Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z.
+*/
+v8::Handle<v8::Value> quaternion(const v8::Arguments &args)
+{
+ if (args.Length() != 4)
+ V8THROW_ERROR("Qt.quaternion(): Invalid arguments");
+
+ double sxyz[4];
+ sxyz[0] = args[0]->ToNumber()->Value();
+ sxyz[1] = args[1]->ToNumber()->Value();
+ sxyz[2] = args[2]->ToNumber()->Value();
+ sxyz[3] = args[3]->ToNumber()->Value();
+
+ const void *params[] = { sxyz };
+ return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
+}
+
+/*!
+\qmlmethod Qt::font(object fontSpecifier)
+Returns a Font with the properties specified in the \c fontSpecifier object
+or the nearest matching font. The \c fontSpecifier object should contain
+key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
+subproperty names, and the values are valid values for each subproperty.
+Invalid keys will be ignored.
+*/
+v8::Handle<v8::Value> font(const v8::Arguments &args)
+{
+ if (args.Length() != 1 || !args[0]->IsObject())
+ V8THROW_ERROR("Qt.font(): Invalid arguments");
+
+ v8::Handle<v8::Object> obj = args[0]->ToObject();
+ bool ok = false;
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV8Handle::fromHandle(obj), V8ENGINE(), &ok);
+ if (!ok)
+ V8THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
+ return V8ENGINE()->fromVariant(v);
+}
+
+/*!
+\qmlmethod Qt::matrix4x4(real m11, real m12, real m13, real m14, real m21, real m22, real m23, real m24, real m31, real m32, real m33, real m34, real m41, real m42, real m43, real m44)
+Returns a Matrix4x4 with the specified values.
+Alternatively, the function may be called with a single argument
+where that argument is a JavaScript array which contains the sixteen
+matrix values.
+*/
+v8::Handle<v8::Value> matrix4x4(const v8::Arguments &args)
+{
+ if (args.Length() == 1 && args[0]->IsObject()) {
+ v8::Handle<v8::Object> obj = args[0]->ToObject();
+ bool ok = false;
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV8Handle::fromHandle(obj), V8ENGINE(), &ok);
+ if (!ok)
+ V8THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
+ return V8ENGINE()->fromVariant(v);
+ }
+
+ if (args.Length() != 16)
+ V8THROW_ERROR("Qt.matrix4x4(): Invalid arguments");
+
+ float vals[16];
+ vals[0] = args[0]->ToNumber()->Value();
+ vals[1] = args[1]->ToNumber()->Value();
+ vals[2] = args[2]->ToNumber()->Value();
+ vals[3] = args[3]->ToNumber()->Value();
+ vals[4] = args[4]->ToNumber()->Value();
+ vals[5] = args[5]->ToNumber()->Value();
+ vals[6] = args[6]->ToNumber()->Value();
+ vals[7] = args[7]->ToNumber()->Value();
+ vals[8] = args[8]->ToNumber()->Value();
+ vals[9] = args[9]->ToNumber()->Value();
+ vals[10] = args[10]->ToNumber()->Value();
+ vals[11] = args[11]->ToNumber()->Value();
+ vals[12] = args[12]->ToNumber()->Value();
+ vals[13] = args[13]->ToNumber()->Value();
+ vals[14] = args[14]->ToNumber()->Value();
+ vals[15] = args[15]->ToNumber()->Value();
+
+ const void *params[] = { vals };
+ return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
+}
+
+/*!
\qmlmethod color Qt::lighter(color baseColor, real factor)
Returns a color lighter than \c baseColor by the \c factor provided.
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index bbfe88a292..0f43298338 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -75,11 +75,15 @@ v8::Handle<v8::Value> consoleException(const v8::Arguments &args);
v8::Handle<v8::Value> isQtObject(const v8::Arguments &args);
v8::Handle<v8::Value> rgba(const v8::Arguments &args);
v8::Handle<v8::Value> hsla(const v8::Arguments &args);
+v8::Handle<v8::Value> font(const v8::Arguments &args);
v8::Handle<v8::Value> rect(const v8::Arguments &args);
v8::Handle<v8::Value> point(const v8::Arguments &args);
v8::Handle<v8::Value> size(const v8::Arguments &args);
+v8::Handle<v8::Value> vector2d(const v8::Arguments &args);
v8::Handle<v8::Value> vector3d(const v8::Arguments &args);
v8::Handle<v8::Value> vector4d(const v8::Arguments &args);
+v8::Handle<v8::Value> quaternion(const v8::Arguments &args);
+v8::Handle<v8::Value> matrix4x4(const v8::Arguments &args);
v8::Handle<v8::Value> lighter(const v8::Arguments &args);
v8::Handle<v8::Value> darker(const v8::Arguments &args);
v8::Handle<v8::Value> tint(const v8::Arguments &args);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 732a04d437..be3c7def85 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -605,11 +605,17 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
qt->Set(v8::String::New("isQtObject"), V8FUNCTION(isQtObject, this));
qt->Set(v8::String::New("rgba"), V8FUNCTION(rgba, this));
qt->Set(v8::String::New("hsla"), V8FUNCTION(hsla, this));
+ qt->Set(v8::String::New("font"), V8FUNCTION(font, this));
+
qt->Set(v8::String::New("rect"), V8FUNCTION(rect, this));
qt->Set(v8::String::New("point"), V8FUNCTION(point, this));
qt->Set(v8::String::New("size"), V8FUNCTION(size, this));
+
+ qt->Set(v8::String::New("vector2d"), V8FUNCTION(vector2d, this));
qt->Set(v8::String::New("vector3d"), V8FUNCTION(vector3d, this));
qt->Set(v8::String::New("vector4d"), V8FUNCTION(vector4d, this));
+ qt->Set(v8::String::New("quaternion"), V8FUNCTION(quaternion, this));
+ qt->Set(v8::String::New("matrix4x4"), V8FUNCTION(matrix4x4, this));
qt->Set(v8::String::New("formatDate"), V8FUNCTION(formatDate, this));
qt->Set(v8::String::New("formatTime"), V8FUNCTION(formatTime, this));
diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp
index cf2c13fce9..cdee5a4771 100644
--- a/src/qml/qml/v8/qv8valuetypewrapper.cpp
+++ b/src/qml/qml/v8/qv8valuetypewrapper.cpp
@@ -44,6 +44,7 @@
#include <private/qqmlvaluetype_p.h>
#include <private/qqmlbinding_p.h>
+#include <private/qqmlglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -148,6 +149,14 @@ v8::Local<v8::Object> QV8ValueTypeWrapper::newValueType(const QVariant &value, Q
return rv;
}
+QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj, int typeHint, bool *succeeded)
+{
+ // NOTE: obj must not be an external resource object (ie, wrapper object)
+ // instead, it is a normal js object which one of the value-type providers
+ // may know how to convert to the given type.
+ return QQml_valueTypeProvider()->createVariantFromJsObject(typeHint, QQmlV8Handle::fromHandle(obj), m_engine, succeeded);
+}
+
QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj)
{
QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj);
diff --git a/src/qml/qml/v8/qv8valuetypewrapper_p.h b/src/qml/qml/v8/qv8valuetypewrapper_p.h
index b80d3cbbba..76b0087828 100644
--- a/src/qml/qml/v8/qv8valuetypewrapper_p.h
+++ b/src/qml/qml/v8/qv8valuetypewrapper_p.h
@@ -75,6 +75,7 @@ public:
v8::Local<v8::Object> newValueType(QObject *, int, QQmlValueType *);
v8::Local<v8::Object> newValueType(const QVariant &, QQmlValueType *);
+ QVariant toVariant(v8::Handle<v8::Object>, int typeHint, bool *succeeded);
QVariant toVariant(v8::Handle<v8::Object>);
QVariant toVariant(QV8ObjectResource *);