aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp4
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp18
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp35
-rw-r--r--src/qml/qml/qqmlglobal.cpp10
-rw-r--r--src/qml/qml/qqmlglobal_p.h6
-rw-r--r--src/qml/qml/qqmlproperty.cpp20
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp198
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h158
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp35
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h6
-rw-r--r--src/qml/qml/v8/qv8engine.cpp8
-rw-r--r--src/quick/util/qquickglobal.cpp25
-rw-r--r--src/quick/util/qquickvaluetypes.cpp93
-rw-r--r--src/quick/util/qquickvaluetypes_p.h70
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp23
-rw-r--r--tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp21
16 files changed, 274 insertions, 456 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 339278fbe8..07ea2a6fff 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1941,8 +1941,8 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4
initMetaObjectResolver(resolver, cache);
return QV4::IR::QObjectType;
}
- } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(property->propType)) {
- if (QQmlPropertyCache *cache = qmlEngine->cache(valueType->metaObject())) {
+ } else if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType)) {
+ if (QQmlPropertyCache *cache = qmlEngine->cache(valueTypeMetaObject)) {
initMetaObjectResolver(resolver, cache);
resolver->flags |= ResolveTypeInformationOnly;
return QV4::IR::QObjectType;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index ada848f31d..7f399f0879 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -463,8 +463,8 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r
if (instantiatingProperty->isQObject()) {
baseTypeCache = enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType);
Q_ASSERT(baseTypeCache);
- } else if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(instantiatingProperty->propType)) {
- baseTypeCache = enginePrivate->cache(vt->metaObject());
+ } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType)) {
+ baseTypeCache = enginePrivate->cache(vtmo);
Q_ASSERT(baseTypeCache);
}
}
@@ -1630,8 +1630,8 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
notifySignal = targetProperty->notifyIndex;
if (!subProperty.isEmpty()) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
- if (!valueType) {
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(type);
+ if (!valueTypeMetaObject) {
recordError(p->aliasLocation, tr("Invalid alias location"));
return false;
}
@@ -1639,7 +1639,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
propType = type;
int valueTypeIndex =
- valueType->metaObject()->indexOfProperty(subProperty.toString().toUtf8().constData());
+ valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData());
if (valueTypeIndex == -1) {
recordError(p->aliasLocation, tr("Invalid alias location"));
return false;
@@ -1647,10 +1647,10 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
propIdx = QQmlPropertyData::encodeValueTypePropertyIndex(propIdx, valueTypeIndex);
- if (valueType->metaObject()->property(valueTypeIndex).isEnumType())
+ if (valueTypeMetaObject->property(valueTypeIndex).isEnumType())
type = QVariant::Int;
else
- type = valueType->metaObject()->property(valueTypeIndex).userType();
+ type = valueTypeMetaObject->property(valueTypeIndex).userType();
} else {
if (targetProperty->isEnum()) {
@@ -1887,7 +1887,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
if (binding->type >= QV4::CompiledData::Binding::Type_Object && !customParser) {
qSwap(_seenObjectWithId, seenSubObjectWithId);
- const bool subObjectValid = validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::valueType(pd->propType));
+ const bool subObjectValid = validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType));
qSwap(_seenObjectWithId, seenSubObjectWithId);
if (!subObjectValid)
return false;
@@ -1961,7 +1961,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
return false;
} else if (binding->isGroupProperty()) {
if (QQmlValueTypeFactory::isValueType(pd->propType)) {
- if (QQmlValueTypeFactory::valueType(pd->propType)) {
+ if (QQmlValueTypeFactory::metaObjectForMetaType(pd->propType)) {
if (!pd->isWritable()) {
recordError(binding->location, tr("Invalid property assignment: \"%1\" is a read-only property").arg(name));
return false;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index daaa0c16f1..c2b3b44bba 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -201,16 +201,16 @@ static QV4::ReturnedValue LoadProperty(QV8Engine *engine, QObject *object,
ReadFunction(object, property, &v, notifier);
if (QQmlValueTypeFactory::isValueType(v.userType())) {
- if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(v.userType()))
- return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueType); // VariantReference value-type.
+ if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(v.userType()))
+ return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueTypeMetaObject, v.userType()); // VariantReference value-type.
}
return engine->fromVariant(v);
} else if (QQmlValueTypeFactory::isValueType(property.propType)) {
Q_ASSERT(notifier == 0);
- if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(property.propType))
- return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueType);
+ if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property.propType))
+ return QV4::QmlValueTypeWrapper::create(engine, object, property.coreIndex, valueTypeMetaObject, property.propType);
} else {
Q_ASSERT(notifier == 0);
@@ -1134,17 +1134,6 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
int *argTypes, QV8Engine *engine, QV4::CallData *callArgs)
{
if (argCount > 0) {
-
- // Special handling is required for value types.
- // We need to save the current value in a temporary,
- // and reapply it after converting all arguments.
- // This avoids the "overwriting copy-value-type-value"
- // problem during Q_INVOKABLE function invocation.
- QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object);
- QVariant valueTypeValue;
- if (valueTypeObject)
- valueTypeValue = valueTypeObject->value();
-
// Convert all arguments.
QVarLengthArray<CallArgument, 9> args(argCount + 1);
args[0].initAsType(returnType);
@@ -1154,10 +1143,6 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
for (int ii = 0; ii < args.count(); ++ii)
argData[ii] = args[ii].dataPtr();
- // Reinstate saved value type object value if required.
- if (valueTypeObject)
- valueTypeObject->setValue(valueTypeValue);
-
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data());
return args[0].toValue(engine);
@@ -1443,16 +1428,6 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
int bestParameterScore = INT_MAX;
int bestMatchScore = INT_MAX;
- // Special handling is required for value types.
- // We need to save the current value in a temporary,
- // and reapply it after converting all arguments.
- // This avoids the "overwriting copy-value-type-value"
- // problem during Q_INVOKABLE function invocation.
- QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object);
- QVariant valueTypeValue;
- if (valueTypeObject)
- valueTypeValue = valueTypeObject->value();
-
QQmlPropertyData dummy;
const QQmlPropertyData *attempt = &data;
@@ -1496,8 +1471,6 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
} while((attempt = RelatedMethod(object, attempt, dummy)) != 0);
if (best.isValid()) {
- if (valueTypeObject)
- valueTypeObject->setValue(valueTypeValue);
return CallPrecise(object, best, engine, callArgs);
} else {
QString error = QLatin1String("Unable to determine callable overload. Candidates are:");
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 492836ae03..57c0993d00 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -50,14 +50,12 @@ QQmlValueTypeProvider::~QQmlValueTypeProvider()
QQml_removeValueTypeProvider(this);
}
-QQmlValueType *QQmlValueTypeProvider::createValueType(int type)
+const QMetaObject *QQmlValueTypeProvider::metaObjectForMetaType(int type)
{
- QQmlValueType *value = 0;
-
QQmlValueTypeProvider *p = this;
do {
- if (p->create(type, value))
- return value;
+ if (const QMetaObject *mo = p->getMetaObjectForMetaType(type))
+ return mo;
} while ((p = p->next));
return 0;
@@ -245,7 +243,7 @@ bool QQmlValueTypeProvider::writeValueType(int type, const void *src, void *dst,
return false;
}
-bool QQmlValueTypeProvider::create(int, QQmlValueType *&) { return false; }
+const QMetaObject *QQmlValueTypeProvider::getMetaObjectForMetaType(int) { return 0; }
bool QQmlValueTypeProvider::init(int, void *, size_t) { return false; }
bool QQmlValueTypeProvider::destroy(int, void *, size_t) { return false; }
bool QQmlValueTypeProvider::copy(int, const void *, void *, size_t) { return false; }
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 1d0bf59670..2832d0338d 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -215,7 +215,6 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
}
-class QQmlValueType;
class QV8Engine;
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
{
@@ -223,7 +222,7 @@ public:
QQmlValueTypeProvider();
virtual ~QQmlValueTypeProvider();
- QQmlValueType *createValueType(int);
+ const QMetaObject *metaObjectForMetaType(int);
bool initValueType(int, void *, size_t);
bool destroyValueType(int, void *, size_t);
@@ -243,8 +242,7 @@ public:
bool writeValueType(int, const void *, void *, size_t);
private:
- virtual bool create(int, QQmlValueType *&);
-
+ virtual const QMetaObject *getMetaObjectForMetaType(int);
virtual bool init(int, void *, size_t);
virtual bool destroy(int, void *, size_t);
virtual bool copy(int, const void *, void *, size_t);
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 635e4d4a54..0ee8f94a66 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -284,13 +284,13 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType)) {
// We're now at a value type property
- QObject *typeObject = QQmlValueTypeFactory::valueType(property->propType);
- if (!typeObject) return; // Not a value type
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType);
+ if (!valueTypeMetaObject) return; // Not a value type
- int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
+ int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData());
if (idx == -1) return; // Value type property does not exist
- QMetaProperty vtProp = typeObject->metaObject()->property(idx);
+ QMetaProperty vtProp = valueTypeMetaObject->property(idx);
Q_ASSERT(QQmlPropertyData::flagsForProperty(vtProp) <= QQmlPropertyData::ValueTypeFlagMask);
Q_ASSERT(vtProp.userType() <= 0x0000FFFF);
@@ -463,9 +463,9 @@ const char *QQmlProperty::propertyTypeName() const
if (!d)
return 0;
if (d->isValueType()) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(d->core.propType);
- Q_ASSERT(valueType);
- return valueType->metaObject()->property(d->core.valueTypeCoreIndex).typeName();
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType);
+ Q_ASSERT(valueTypeMetaObject);
+ return valueTypeMetaObject->property(d->core.valueTypeCoreIndex).typeName();
} else if (d->object && type() & Property && d->core.isValid()) {
return d->object->metaObject()->property(d->core.coreIndex).typeName();
} else {
@@ -642,10 +642,10 @@ QString QQmlProperty::name() const
} else if (d->isValueType()) {
QString rv = d->core.name(d->object) + QLatin1Char('.');
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(d->core.propType);
- Q_ASSERT(valueType);
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType);
+ Q_ASSERT(valueTypeMetaObject);
- const char *vtName = valueType->metaObject()->property(d->core.valueTypeCoreIndex).name();
+ const char *vtName = valueTypeMetaObject->property(d->core.valueTypeCoreIndex).name();
rv += QString::fromUtf8(vtName);
d->nameCache = rv;
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index f73b50ad46..20f3027e4c 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -36,6 +36,7 @@
#include <private/qqmlglobal_p.h>
#include <QtCore/qdebug.h>
+#include <private/qmetaobjectbuilder_p.h>
QT_BEGIN_NAMESPACE
@@ -48,7 +49,7 @@ struct QQmlValueTypeFactoryImpl
bool isValueType(int idx);
- QQmlValueType *createValueType(int);
+ const QMetaObject *metaObjectForMetaType(int);
QQmlValueType *valueType(int);
QQmlValueType *valueTypes[QVariant::UserType];
@@ -83,39 +84,30 @@ bool QQmlValueTypeFactoryImpl::isValueType(int idx)
return false;
}
-QQmlValueType *QQmlValueTypeFactoryImpl::createValueType(int t)
+const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
{
- QQmlValueType *rv = 0;
-
switch (t) {
case QVariant::Point:
- rv = new QQmlPointValueType;
- break;
+ return &QQmlPointValueType::staticMetaObject;
case QVariant::PointF:
- rv = new QQmlPointFValueType;
- break;
+ return &QQmlPointFValueType::staticMetaObject;
case QVariant::Size:
- rv = new QQmlSizeValueType;
- break;
+ return &QQmlSizeValueType::staticMetaObject;
case QVariant::SizeF:
- rv = new QQmlSizeFValueType;
- break;
+ return &QQmlSizeFValueType::staticMetaObject;
case QVariant::Rect:
- rv = new QQmlRectValueType;
- break;
+ return &QQmlRectValueType::staticMetaObject;
case QVariant::RectF:
- rv = new QQmlRectFValueType;
- break;
+ return &QQmlRectFValueType::staticMetaObject;
case QVariant::EasingCurve:
- rv = new QQmlEasingValueType;
- break;
+ return &QQmlEasingValueType::staticMetaObject;
default:
- rv = QQml_valueTypeProvider()->createValueType(t);
+ if (const QMetaObject *mo = QQml_valueTypeProvider()->metaObjectForMetaType(t))
+ return mo;
break;
}
- Q_ASSERT(!rv || rv->metaObject()->propertyCount() < 32);
- return rv;
+ return 0;
}
QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
@@ -126,7 +118,10 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
QHash<int, QQmlValueType *>::iterator it = userTypes.find(idx);
if (it == userTypes.end()) {
- it = userTypes.insert(idx, createValueType(idx));
+ QQmlValueType *vt = 0;
+ if (const QMetaObject *mo = metaObjectForMetaType(idx))
+ vt = new QQmlValueType(idx, mo);
+ it = userTypes.insert(idx, vt);
}
mutex.unlock();
@@ -139,7 +134,8 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
// TODO: Investigate the performance/memory characteristics of
// removing the preallocated array
- if ((rv = createValueType(idx))) {
+ if (const QMetaObject *mo = metaObjectForMetaType(idx)) {
+ rv = new QQmlValueType(idx, mo);
valueTypes[idx] = rv;
}
}
@@ -161,20 +157,116 @@ QQmlValueType *QQmlValueTypeFactory::valueType(int idx)
return factoryImpl()->valueType(idx);
}
+const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(int type)
+{
+ return factoryImpl()->metaObjectForMetaType(type);
+}
+
void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor)
{
qmlRegisterValueTypeEnums<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing");
}
+QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject)
+ : typeId(typeId)
+ , gadgetPtr(QMetaType::create(typeId))
+{
+ QObjectPrivate *op = QObjectPrivate::get(this);
+ Q_ASSERT(!op->metaObject);
+ op->metaObject = this;
+
+ QMetaObjectBuilder builder(gadgetMetaObject);
+ _metaObject = builder.toMetaObject();
+
+ *static_cast<QMetaObject*>(this) = *_metaObject;
+}
+
+QQmlValueType::~QQmlValueType()
+{
+ QObjectPrivate *op = QObjectPrivate::get(this);
+ Q_ASSERT(op->metaObject == this);
+ op->metaObject = 0;
+ ::free((void*)_metaObject);
+ QMetaType::destroy(typeId, gadgetPtr);
+}
+
+void QQmlValueType::read(QObject *obj, int idx)
+{
+ readProperty(obj, idx, gadgetPtr);
+}
+
+void QQmlValueType::readVariantValue(QObject *obj, int idx, QVariant *into)
+{
+ // important: must not change the userType of the variant
+ readProperty(obj, idx, into);
+}
+
+void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags)
+{
+ Q_ASSERT(gadgetPtr);
+ writeProperty(obj, idx, flags, gadgetPtr);
+}
+
+void QQmlValueType::writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from)
+{
+ writeProperty(obj, idx, flags, from);
+}
+
+QVariant QQmlValueType::value()
+{
+ Q_ASSERT(gadgetPtr);
+ return QVariant(typeId, gadgetPtr);
+}
+
+void QQmlValueType::setValue(const QVariant &value)
+{
+ Q_ASSERT(typeId == value.userType());
+ QMetaType::destruct(typeId, gadgetPtr);
+ QMetaType::construct(typeId, gadgetPtr, value.constData());
+}
+
+bool QQmlValueType::isEqual(const QVariant &other) const
+{
+ Q_ASSERT(gadgetPtr);
+ return QVariant(typeId, gadgetPtr) == other;
+}
+
+QString QQmlValueType::toString() const
+{
+ const QMetaObject *mo = metaObject();
+ const int toStringIndex = mo->indexOfMethod("toString()");
+ if (toStringIndex != -1) {
+ QString result;
+ void *args[] = { &result, 0 };
+ _metaObject->d.static_metacall(reinterpret_cast<QObject*>(gadgetPtr), QMetaObject::InvokeMetaMethod, toStringIndex, args);
+ return result;
+ }
+ QString result = QString::fromUtf8(QMetaType::typeName(typeId));
+ result += QLatin1Char('(');
+ const int propCount = mo->propertyCount();
+ for (int i = 0; i < propCount; ++i) {
+ QVariant value = mo->property(i).read(this);
+ result += value.toString();
+ if (i < propCount - 1)
+ result += QStringLiteral(", ");
+ }
+ result += QLatin1Char(')');
+ return result;
+}
+
+QAbstractDynamicMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
+{
+ return this;
+}
-QQmlValueType::QQmlValueType(int userType, QObject *parent)
-: QObject(parent), m_userType(userType)
+void QQmlValueType::objectDestroyed(QObject *)
{
}
-QQmlPointFValueType::QQmlPointFValueType(QObject *parent)
- : QQmlValueTypeBase<QPointF>(QMetaType::QPointF, parent)
+int QQmlValueType::metaCall(QObject *, QMetaObject::Call type, int _id, void **argv)
{
+ d.static_metacall(reinterpret_cast<QObject*>(gadgetPtr), type, _id, argv);
+ return _id;
}
QString QQmlPointFValueType::toString() const
@@ -203,16 +295,6 @@ void QQmlPointFValueType::setY(qreal y)
}
-QQmlPointValueType::QQmlPointValueType(QObject *parent)
- : QQmlValueTypeBase<QPoint>(QMetaType::QPoint, parent)
-{
-}
-
-QString QQmlPointValueType::toString() const
-{
- return QString(QLatin1String("QPoint(%1, %2)")).arg(v.x()).arg(v.y());
-}
-
int QQmlPointValueType::x() const
{
return v.x();
@@ -234,11 +316,6 @@ void QQmlPointValueType::setY(int y)
}
-QQmlSizeFValueType::QQmlSizeFValueType(QObject *parent)
- : QQmlValueTypeBase<QSizeF>(QMetaType::QSizeF, parent)
-{
-}
-
QString QQmlSizeFValueType::toString() const
{
return QString(QLatin1String("QSizeF(%1, %2)")).arg(v.width()).arg(v.height());
@@ -265,16 +342,6 @@ void QQmlSizeFValueType::setHeight(qreal h)
}
-QQmlSizeValueType::QQmlSizeValueType(QObject *parent)
- : QQmlValueTypeBase<QSize>(QMetaType::QSize, parent)
-{
-}
-
-QString QQmlSizeValueType::toString() const
-{
- return QString(QLatin1String("QSize(%1, %2)")).arg(v.width()).arg(v.height());
-}
-
int QQmlSizeValueType::width() const
{
return v.width();
@@ -295,12 +362,6 @@ void QQmlSizeValueType::setHeight(int h)
v.setHeight(h);
}
-
-QQmlRectFValueType::QQmlRectFValueType(QObject *parent)
- : QQmlValueTypeBase<QRectF>(QMetaType::QRectF, parent)
-{
-}
-
QString QQmlRectFValueType::toString() const
{
return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height());
@@ -346,17 +407,6 @@ void QQmlRectFValueType::setHeight(qreal h)
v.setHeight(h);
}
-
-QQmlRectValueType::QQmlRectValueType(QObject *parent)
- : QQmlValueTypeBase<QRect>(QMetaType::QRect, parent)
-{
-}
-
-QString QQmlRectValueType::toString() const
-{
- return QString(QLatin1String("QRect(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height());
-}
-
int QQmlRectValueType::x() const
{
return v.x();
@@ -398,16 +448,6 @@ void QQmlRectValueType::setHeight(int h)
}
-QQmlEasingValueType::QQmlEasingValueType(QObject *parent)
- : QQmlValueTypeBase<QEasingCurve>(QMetaType::QEasingCurve, parent)
-{
-}
-
-QString QQmlEasingValueType::toString() const
-{
- return QString(QLatin1String("QEasingCurve(%1, %2, %3, %4)")).arg(v.type()).arg(v.amplitude()).arg(v.overshoot()).arg(v.period());
-}
-
QQmlEasingValueType::Type QQmlEasingValueType::type() const
{
return (QQmlEasingValueType::Type)v.type();
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 5a6bcdd003..2f6a192f77 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -57,34 +57,37 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject
+class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject, public QAbstractDynamicMetaObject
{
- Q_OBJECT
public:
- QQmlValueType(int userType, QObject *parent = 0);
- virtual void read(QObject *, int) = 0;
- virtual void readVariantValue(QObject *, int, QVariant *) = 0;
- virtual void write(QObject *, int, QQmlPropertyPrivate::WriteFlags flags) = 0;
- virtual void writeVariantValue(QObject *, int, QQmlPropertyPrivate::WriteFlags, QVariant *) = 0;
- virtual QVariant value() = 0;
- virtual void setValue(const QVariant &) = 0;
-
- virtual QString toString() const = 0;
- virtual bool isEqual(const QVariant &value) const = 0;
-
- virtual void onLoad() {}
+ QQmlValueType(int userType, const QMetaObject *metaObject);
+ ~QQmlValueType();
+ void read(QObject *, int);
+ void readVariantValue(QObject *, int, QVariant *);
+ void write(QObject *, int, QQmlPropertyPrivate::WriteFlags flags);
+ void writeVariantValue(QObject *, int, QQmlPropertyPrivate::WriteFlags, QVariant *);
+ QVariant value();
+ void setValue(const QVariant &);
+
+ QString toString() const;
+ bool isEqual(const QVariant &value) const;
inline int userType() const
{
- return m_userType;
+ return typeId;
+
}
+ // ---- dynamic meta object data interface
+ virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *);
+ virtual void objectDestroyed(QObject *);
+ virtual int metaCall(QObject *obj, QMetaObject::Call type, int _id, void **argv);
+ // ----
protected:
inline void readProperty(QObject *obj, int idx, void *p)
{
void *a[] = { p, 0 };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
- onLoad();
}
inline void writeProperty(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, void *p)
@@ -95,59 +98,9 @@ protected:
}
private:
- int m_userType;
-};
-
-template <typename T>
-class QQmlValueTypeBase : public QQmlValueType
-{
-public:
- typedef T ValueType;
-
- QQmlValueTypeBase(int userType, QObject *parent)
- : QQmlValueType(userType, parent)
- {
- }
-
- virtual void read(QObject *obj, int idx)
- {
- readProperty(obj, idx, &v);
- }
-
- virtual void readVariantValue(QObject *obj, int idx, QVariant *into)
- {
- // important: must not change the userType of the variant
- readProperty(obj, idx, into);
- }
-
- virtual void write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags)
- {
- writeProperty(obj, idx, flags, &v);
- }
-
- virtual void writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from)
- {
- writeProperty(obj, idx, flags, from);
- }
-
- virtual QVariant value()
- {
- return QVariant::fromValue(v);
- }
-
- virtual void setValue(const QVariant &value)
- {
- v = qvariant_cast<T>(value);
- onLoad();
- }
-
- virtual bool isEqual(const QVariant &other) const
- {
- return QVariant::fromValue(v) == other;
- }
-
-protected:
- ValueType v;
+ const QMetaObject *_metaObject;
+ int typeId;
+ void *gadgetPtr;
};
class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
@@ -155,86 +108,75 @@ class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory
public:
static bool isValueType(int);
static QQmlValueType *valueType(int idx);
+ static const QMetaObject *metaObjectForMetaType(int type);
static void registerValueTypes(const char *uri, int versionMajor, int versionMinor);
};
-class Q_QML_PRIVATE_EXPORT QQmlPointFValueType : public QQmlValueTypeBase<QPointF>
+struct QQmlPointFValueType
{
+ QPointF v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlPointFValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
void setX(qreal);
void setY(qreal);
};
-class Q_QML_PRIVATE_EXPORT QQmlPointValueType : public QQmlValueTypeBase<QPoint>
+struct QQmlPointValueType
{
+ QPoint v;
Q_PROPERTY(int x READ x WRITE setX FINAL)
Q_PROPERTY(int y READ y WRITE setY FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlPointValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
int x() const;
int y() const;
void setX(int);
void setY(int);
};
-class Q_QML_PRIVATE_EXPORT QQmlSizeFValueType : public QQmlValueTypeBase<QSizeF>
+struct QQmlSizeFValueType
{
+ QSizeF v;
Q_PROPERTY(qreal width READ width WRITE setWidth FINAL)
Q_PROPERTY(qreal height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlSizeFValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
+ Q_INVOKABLE QString toString() const;
qreal width() const;
qreal height() const;
void setWidth(qreal);
void setHeight(qreal);
};
-class Q_QML_PRIVATE_EXPORT QQmlSizeValueType : public QQmlValueTypeBase<QSize>
+struct QQmlSizeValueType
{
+ QSize v;
Q_PROPERTY(int width READ width WRITE setWidth FINAL)
Q_PROPERTY(int height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlSizeValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
int width() const;
int height() const;
void setWidth(int);
void setHeight(int);
};
-class Q_QML_PRIVATE_EXPORT QQmlRectFValueType : public QQmlValueTypeBase<QRectF>
+struct QQmlRectFValueType
{
+ QRectF v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal width READ width WRITE setWidth FINAL)
Q_PROPERTY(qreal height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlRectFValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
void setX(qreal);
@@ -246,18 +188,15 @@ public:
void setHeight(qreal);
};
-class Q_QML_PRIVATE_EXPORT QQmlRectValueType : public QQmlValueTypeBase<QRect>
+struct QQmlRectValueType
{
+ QRect v;
Q_PROPERTY(int x READ x WRITE setX FINAL)
Q_PROPERTY(int y READ y WRITE setY FINAL)
Q_PROPERTY(int width READ width WRITE setWidth FINAL)
Q_PROPERTY(int height READ height WRITE setHeight FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQmlRectValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
int x() const;
int y() const;
void setX(int);
@@ -269,9 +208,10 @@ public:
void setHeight(int);
};
-class Q_QML_PRIVATE_EXPORT QQmlEasingValueType : public QQmlValueTypeBase<QEasingCurve>
+struct QQmlEasingValueType
{
- Q_OBJECT
+ QEasingCurve v;
+ Q_GADGET
Q_ENUMS(Type)
Q_PROPERTY(QQmlEasingValueType::Type type READ type WRITE setType FINAL)
@@ -307,10 +247,6 @@ public:
Bezier = QEasingCurve::BezierSpline
};
- QQmlEasingValueType(QObject *parent = 0);
-
- virtual QString toString() const;
-
Type type() const;
qreal amplitude() const;
qreal overshoot() const;
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index ede55d033f..d2fccb5273 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -120,7 +120,10 @@ static bool readReferenceValue(const QmlValueTypeReference *reference)
// We need to modify this reference to the updated value type, if
// possible, or return false if it is not a value type.
if (QQmlValueTypeFactory::isValueType(variantReferenceType)) {
- reference->d()->type = QQmlValueTypeFactory::valueType(variantReferenceType);
+ QQmlValueType *vt = 0;
+ if (const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType))
+ vt = new QQmlValueType(variantReferenceType, mo);
+ reference->d()->type.reset(vt);
if (!reference->d()->type) {
return false;
}
@@ -147,7 +150,7 @@ void QmlValueTypeWrapper::initProto(ExecutionEngine *v4)
v4->qmlExtensions()->valueTypeWrapperPrototype = o->d();
}
-ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type)
+ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, const QMetaObject *metaObject, int typeId)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
Scope scope(v4);
@@ -156,11 +159,11 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int pr
Scoped<QmlValueTypeReference> r(scope, v4->memoryManager->alloc<QmlValueTypeReference>(v8));
ScopedObject proto(scope, v4->qmlExtensions()->valueTypeWrapperPrototype);
r->setPrototype(proto);
- r->d()->type = type; r->d()->object = object; r->d()->property = property;
+ r->d()->type.reset(new QQmlValueType(typeId, metaObject)); r->d()->object = object; r->d()->property = property;
return r->asReturnedValue();
}
-ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type)
+ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, const QMetaObject *metaObject, int typeId)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
Scope scope(v4);
@@ -169,7 +172,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value,
Scoped<QmlValueTypeCopy> r(scope, v4->memoryManager->alloc<QmlValueTypeCopy>(v8));
ScopedObject proto(scope, v4->qmlExtensions()->valueTypeWrapperPrototype);
r->setPrototype(proto);
- r->d()->type = type; r->d()->value = value;
+ r->d()->type.reset(new QQmlValueType(typeId, metaObject)); r->d()->value = value;
return r->asReturnedValue();
}
@@ -220,11 +223,11 @@ PropertyAttributes QmlValueTypeWrapper::query(const Managed *m, String *name)
QQmlPropertyData local;
QQmlPropertyData *result = 0;
{
- QQmlData *ddata = QQmlData::get(r->d()->type, false);
+ QQmlData *ddata = QQmlData::get(r->d()->type.data(), false);
if (ddata && ddata->propertyCache)
result = ddata->propertyCache->property(name, 0, 0);
else
- result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type, name, 0, local);
+ result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type.data(), name, 0, local);
}
return result ? Attr_Data : Attr_Invalid;
}
@@ -278,6 +281,10 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QmlValueTypeWrapper *r = static_cast<QmlValueTypeWrapper *>(m);
QV4::ExecutionEngine *v4 = m->engine();
+ // ### Remove this once we can do proper this calls.
+ if (name == v4->id_toString)
+ return Object::get(m, name, hasProperty);
+
// Note: readReferenceValue() can change the reference->type.
if (r->d()->objectType == Heap::QmlValueTypeWrapper::Reference) {
QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(r);
@@ -296,11 +303,11 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QQmlPropertyData local;
QQmlPropertyData *result = 0;
{
- QQmlData *ddata = QQmlData::get(r->d()->type, false);
+ QQmlData *ddata = QQmlData::get(r->d()->type.data(), false);
if (ddata && ddata->propertyCache)
result = ddata->propertyCache->property(name, 0, 0);
else
- result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type, name, 0, local);
+ result = QQmlPropertyCache::property(r->d()->v8->engine(), r->d()->type.data(), name, 0, local);
}
if (!result)
@@ -313,14 +320,14 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
// calling a Q_INVOKABLE function of a value type
Scope scope(v4);
ScopedContext c(scope, v4->rootContext());
- return QV4::QObjectMethod::create(c, r->d()->type, result->coreIndex);
+ return QV4::QObjectMethod::create(c, r->d()->type.data(), result->coreIndex);
}
#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
if (result->propType == metatype) { \
cpptype v; \
void *args[] = { &v, 0 }; \
- r->d()->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \
+ QMetaObject::metacall(r->d()->type.data(), QMetaObject::ReadProperty, result->coreIndex, args); \
return constructor(v); \
}
@@ -332,7 +339,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QVariant v(result->propType, (void *)0);
void *args[] = { v.data(), 0 };
- r->d()->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args);
+ QMetaObject::metacall(r->d()->type.data(), QMetaObject::ReadProperty, result->coreIndex, args);
return r->d()->v8->fromVariant(v);
#undef VALUE_TYPE_ACCESSOR
}
@@ -402,7 +409,7 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
v = v.toInt();
- p.write(reference->d()->type, v);
+ p.write(reference->d()->type.data(), v);
if (writebackProperty.userType() == QMetaType::QVariant) {
QVariant variantReferenceValue = r->d()->type->value();
@@ -425,7 +432,7 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
r->d()->type->setValue(copy->d()->value);
QMetaProperty p = r->d()->type->metaObject()->property(index);
- p.write(r->d()->type, v);
+ p.write(r->d()->type.data(), v);
copy->d()->value = r->d()->type->value();
}
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index d15a4b0cef..4946c13e42 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -65,7 +65,7 @@ struct QmlValueTypeWrapper : Object {
QmlValueTypeWrapper(QV8Engine *engine, ObjectType type);
QV8Engine *v8;
ObjectType objectType;
- mutable QQmlValueType *type;
+ mutable QScopedPointer<QQmlValueType> type;
};
}
@@ -77,8 +77,8 @@ struct Q_QML_EXPORT QmlValueTypeWrapper : Object
public:
- static ReturnedValue create(QV8Engine *v8, QObject *, int, QQmlValueType *);
- static ReturnedValue create(QV8Engine *v8, const QVariant &, QQmlValueType *);
+ static ReturnedValue create(QV8Engine *v8, QObject *, int, const QMetaObject *metaObject, int typeId);
+ static ReturnedValue create(QV8Engine *v8, const QVariant &, const QMetaObject *metaObject, int typeId);
QVariant toVariant() const;
bool isEqual(const QVariant& value);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 5e9e20b416..ee124aeed0 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -413,8 +413,8 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
break;
}
- if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
- return QV4::QmlValueTypeWrapper::create(this, variant, vt);
+ if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
+ return QV4::QmlValueTypeWrapper::create(this, variant, vtmo, type);
} else {
QV4::Scope scope(m_v4Engine);
if (type == qMetaTypeId<QQmlListReference>()) {
@@ -454,8 +454,8 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
if (succeeded)
return retn.asReturnedValue();
- if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
- return QV4::QmlValueTypeWrapper::create(this, variant, vt);
+ if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
+ return QV4::QmlValueTypeWrapper::create(this, variant, vtmo, type);
}
// XXX TODO: To be compatible, we still need to handle:
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index b507b47e6b..e3250a6309 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -364,35 +364,28 @@ public:
return QMatrix4x4(matVals);
}
- template<typename T>
- bool typedCreate(QQmlValueType *&v)
- {
- v = new T;
- return true;
- }
-
- bool create(int type, QQmlValueType *&v)
+ const QMetaObject *getMetaObjectForMetaType(int type)
{
switch (type) {
case QMetaType::QColor:
- return typedCreate<QQuickColorValueType>(v);
+ return &QQuickColorValueType::staticMetaObject;
case QMetaType::QFont:
- return typedCreate<QQuickFontValueType>(v);
+ return &QQuickFontValueType::staticMetaObject;
case QMetaType::QVector2D:
- return typedCreate<QQuickVector2DValueType>(v);
+ return &QQuickVector2DValueType::staticMetaObject;
case QMetaType::QVector3D:
- return typedCreate<QQuickVector3DValueType>(v);
+ return &QQuickVector3DValueType::staticMetaObject;
case QMetaType::QVector4D:
- return typedCreate<QQuickVector4DValueType>(v);
+ return &QQuickVector4DValueType::staticMetaObject;
case QMetaType::QQuaternion:
- return typedCreate<QQuickQuaternionValueType>(v);
+ return &QQuickQuaternionValueType::staticMetaObject;
case QMetaType::QMatrix4x4:
- return typedCreate<QQuickMatrix4x4ValueType>(v);
+ return &QQuickMatrix4x4ValueType::staticMetaObject;
default:
break;
}
- return false;
+ return 0;
}
template<typename T>
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 37a5ba307f..2e4fec0599 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -48,11 +48,6 @@ namespace QQuickValueTypes {
}
}
-QQuickColorValueType::QQuickColorValueType(QObject *parent)
- : QQmlValueTypeBase<QColor>(QMetaType::QColor, parent)
-{
-}
-
QString QQuickColorValueType::toString() const
{
// to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
@@ -99,26 +94,11 @@ void QQuickColorValueType::setA(qreal a)
v.setAlphaF(a);
}
-
-QQuickVector2DValueType::QQuickVector2DValueType(QObject *parent)
- : QQmlValueTypeBase<QVector2D>(QMetaType::QVector2D, parent)
-{
-}
-
QString QQuickVector2DValueType::toString() const
{
return QString(QLatin1String("QVector2D(%1, %2)")).arg(v.x()).arg(v.y());
}
-bool QQuickVector2DValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != QMetaType::QVector2D)
- return false;
-
- QVector2D otherVector = other.value<QVector2D>();
- return (v == otherVector);
-}
-
qreal QQuickVector2DValueType::x() const
{
return v.x();
@@ -199,26 +179,11 @@ bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec) const
return qFuzzyCompare(v, vec);
}
-
-QQuickVector3DValueType::QQuickVector3DValueType(QObject *parent)
- : QQmlValueTypeBase<QVector3D>(QMetaType::QVector3D, parent)
-{
-}
-
QString QQuickVector3DValueType::toString() const
{
return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(v.x()).arg(v.y()).arg(v.z());
}
-bool QQuickVector3DValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != QMetaType::QVector3D)
- return false;
-
- QVector3D otherVector = other.value<QVector3D>();
- return (v == otherVector);
-}
-
qreal QQuickVector3DValueType::x() const
{
return v.x();
@@ -321,26 +286,11 @@ bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec) const
return qFuzzyCompare(v, vec);
}
-
-QQuickVector4DValueType::QQuickVector4DValueType(QObject *parent)
- : QQmlValueTypeBase<QVector4D>(QMetaType::QVector4D, parent)
-{
-}
-
QString QQuickVector4DValueType::toString() const
{
return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.z()).arg(v.w());
}
-bool QQuickVector4DValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != QMetaType::QVector4D)
- return false;
-
- QVector4D otherVector = other.value<QVector4D>();
- return (v == otherVector);
-}
-
qreal QQuickVector4DValueType::x() const
{
return v.x();
@@ -450,11 +400,6 @@ bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec) const
return qFuzzyCompare(v, vec);
}
-QQuickQuaternionValueType::QQuickQuaternionValueType(QObject *parent)
- : QQmlValueTypeBase<QQuaternion>(QMetaType::QQuaternion, parent)
-{
-}
-
QString QQuickQuaternionValueType::toString() const
{
return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(v.scalar()).arg(v.x()).arg(v.y()).arg(v.z());
@@ -500,12 +445,6 @@ void QQuickQuaternionValueType::setZ(qreal z)
v.setZ(z);
}
-
-QQuickMatrix4x4ValueType::QQuickMatrix4x4ValueType(QObject *parent)
- : QQmlValueTypeBase<QMatrix4x4>(QMetaType::QMatrix4x4, parent)
-{
-}
-
QMatrix4x4 QQuickMatrix4x4ValueType::times(const QMatrix4x4 &m) const
{
return v * m;
@@ -579,30 +518,6 @@ bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m) const
return qFuzzyCompare(v, m);
}
-QString QQuickMatrix4x4ValueType::toString() const
-{
- return QString(QLatin1String("QMatrix4x4(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16)"))
- .arg(v(0, 0)).arg(v(0, 1)).arg(v(0, 2)).arg(v(0, 3))
- .arg(v(1, 0)).arg(v(1, 1)).arg(v(1, 2)).arg(v(1, 3))
- .arg(v(2, 0)).arg(v(2, 1)).arg(v(2, 2)).arg(v(2, 3))
- .arg(v(3, 0)).arg(v(3, 1)).arg(v(3, 2)).arg(v(3, 3));
-}
-
-bool QQuickMatrix4x4ValueType::isEqual(const QVariant &other) const
-{
- if (other.userType() != qMetaTypeId<QMatrix4x4>())
- return false;
-
- QMatrix4x4 otherMatrix = other.value<QMatrix4x4>();
- return (v == otherMatrix);
-
-}
-
-QQuickFontValueType::QQuickFontValueType(QObject *parent)
- : QQmlValueTypeBase<QFont>(QMetaType::QFont, parent)
-{
-}
-
QString QQuickFontValueType::toString() const
{
return QString(QLatin1String("QFont(%1)")).arg(v.toString());
@@ -681,9 +596,7 @@ void QQuickFontValueType::setStrikeout(bool b)
qreal QQuickFontValueType::pointSize() const
{
if (v.pointSizeF() == -1) {
- if (dpi.isNull)
- dpi = qt_defaultDpi();
- return v.pixelSize() * qreal(72.) / qreal(dpi);
+ return v.pixelSize() * qreal(72.) / qreal(qt_defaultDpi());
}
return v.pointSizeF();
}
@@ -703,9 +616,7 @@ void QQuickFontValueType::setPointSize(qreal size)
int QQuickFontValueType::pixelSize() const
{
if (v.pixelSize() == -1) {
- if (dpi.isNull)
- dpi = qt_defaultDpi();
- return (v.pointSizeF() * dpi) / qreal(72.);
+ return (v.pointSizeF() * qt_defaultDpi()) / qreal(72.);
}
return v.pixelSize();
}
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 7c1cdd1148..7bd6d71dce 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -54,17 +54,16 @@ void registerValueTypes();
}
-class Q_AUTOTEST_EXPORT QQuickColorValueType : public QQmlValueTypeBase<QColor>
+class QQuickColorValueType
{
+ QColor v;
Q_PROPERTY(qreal r READ r WRITE setR FINAL)
Q_PROPERTY(qreal g READ g WRITE setG FINAL)
Q_PROPERTY(qreal b READ b WRITE setB FINAL)
Q_PROPERTY(qreal a READ a WRITE setA FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickColorValueType(QObject *parent = 0);
-
- virtual QString toString() const;
+ Q_INVOKABLE QString toString() const;
qreal r() const;
qreal g() const;
@@ -76,16 +75,14 @@ public:
void setA(qreal);
};
-class Q_AUTOTEST_EXPORT QQuickVector2DValueType : public QQmlValueTypeBase<QVector2D>
+class QQuickVector2DValueType
{
+ QVector2D v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickVector2DValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
@@ -105,17 +102,15 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QVector2D &vec) const;
};
-class Q_AUTOTEST_EXPORT QQuickVector3DValueType : public QQmlValueTypeBase<QVector3D>
+class QQuickVector3DValueType
{
+ QVector3D v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickVector3DValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
@@ -139,18 +134,16 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QVector3D &vec) const;
};
-class Q_AUTOTEST_EXPORT QQuickVector4DValueType : public QQmlValueTypeBase<QVector4D>
+class QQuickVector4DValueType
{
+ QVector4D v;
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)
Q_PROPERTY(qreal z READ z WRITE setZ FINAL)
Q_PROPERTY(qreal w READ w WRITE setW FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickVector4DValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
+ Q_INVOKABLE QString toString() const;
qreal x() const;
qreal y() const;
@@ -175,17 +168,16 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QVector4D &vec) const;
};
-class Q_AUTOTEST_EXPORT QQuickQuaternionValueType : public QQmlValueTypeBase<QQuaternion>
+class QQuickQuaternionValueType
{
+ QQuaternion v;
Q_PROPERTY(qreal scalar READ scalar WRITE setScalar)
Q_PROPERTY(qreal x READ x WRITE setX)
Q_PROPERTY(qreal y READ y WRITE setY)
Q_PROPERTY(qreal z READ z WRITE setZ)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickQuaternionValueType(QObject *parent = 0);
-
- virtual QString toString() const;
+ Q_INVOKABLE QString toString() const;
qreal scalar() const;
qreal x() const;
@@ -197,8 +189,9 @@ public:
void setZ(qreal);
};
-class Q_AUTOTEST_EXPORT QQuickMatrix4x4ValueType : public QQmlValueTypeBase<QMatrix4x4>
+class QQuickMatrix4x4ValueType
{
+ QMatrix4x4 v;
Q_PROPERTY(qreal m11 READ m11 WRITE setM11 FINAL)
Q_PROPERTY(qreal m12 READ m12 WRITE setM12 FINAL)
Q_PROPERTY(qreal m13 READ m13 WRITE setM13 FINAL)
@@ -215,13 +208,8 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4ValueType : public QQmlValueTypeBase<QMat
Q_PROPERTY(qreal m42 READ m42 WRITE setM42 FINAL)
Q_PROPERTY(qreal m43 READ m43 WRITE setM43 FINAL)
Q_PROPERTY(qreal m44 READ m44 WRITE setM44 FINAL)
- Q_OBJECT
+ Q_GADGET
public:
- QQuickMatrix4x4ValueType(QObject *parent = 0);
-
- virtual QString toString() const;
- virtual bool isEqual(const QVariant &other) const;
-
qreal m11() const { return v(0, 0); }
qreal m12() const { return v(0, 1); }
qreal m13() const { return v(0, 2); }
@@ -274,9 +262,10 @@ public:
Q_INVOKABLE bool fuzzyEquals(const QMatrix4x4 &m) const;
};
-class Q_AUTOTEST_EXPORT QQuickFontValueType : public QQmlValueTypeBase<QFont>
+class QQuickFontValueType
{
- Q_OBJECT
+ QFont v;
+ Q_GADGET
Q_ENUMS(FontWeight)
Q_ENUMS(Capitalization)
@@ -305,9 +294,7 @@ public:
SmallCaps = QFont::SmallCaps,
Capitalize = QFont::Capitalize };
- QQuickFontValueType(QObject *parent = 0);
-
- virtual QString toString() const;
+ Q_INVOKABLE QString toString() const;
QString family() const;
void setFamily(const QString &);
@@ -344,9 +331,6 @@ public:
qreal wordSpacing() const;
void setWordSpacing(qreal spacing);
-
-private:
- mutable QQmlNullableValue<int> dpi;
};
QT_END_NAMESPACE
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
index fdbcc0dbf2..cdbad96b2f 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
+++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
@@ -199,6 +199,8 @@ public:
bool operator==(const TestValue &other) const { return (m_p1 == other.m_p1) && (m_p2 == other.m_p2); }
bool operator!=(const TestValue &other) const { return !operator==(other); }
+ bool operator<(const TestValue &other) const { if (m_p1 < other.m_p1) return true; return m_p2 < other.m_p2; }
+
private:
int m_p1;
double m_p2;
@@ -210,16 +212,14 @@ Q_DECLARE_METATYPE(TestValue);
namespace {
-class TestValueType : public QQmlValueTypeBase<TestValue>
+class TestValueType
{
- Q_OBJECT
+ TestValue v;
+ Q_GADGET
Q_PROPERTY(int property1 READ property1 WRITE setProperty1)
Q_PROPERTY(double property2 READ property2 WRITE setProperty2)
public:
- TestValueType(QObject *parent = 0) : QQmlValueTypeBase<TestValue>(qMetaTypeId<TestValue>(), parent) {}
-
- virtual QString toString() const { return QString::number(property1()) + QLatin1Char(',') + QString::number(property2()); }
- virtual bool isEqual(const QVariant &other) const { return (other.userType() == qMetaTypeId<TestValue>()) && (v == other.value<TestValue>()); }
+ Q_INVOKABLE QString toString() const { return QString::number(property1()) + QLatin1Char(',') + QString::number(property2()); }
int property1() const { return v.property1(); }
void setProperty1(int p1) { v.setProperty1(p1); }
@@ -231,14 +231,12 @@ public:
class TestValueTypeProvider : public QQmlValueTypeProvider
{
public:
- bool create(int type, QQmlValueType *&v)
+ const QMetaObject *getMetaObjectForMetaType(int type)
{
- if (type == qMetaTypeId<TestValue>()) {
- v = new TestValueType;
- return true;
- }
+ if (type == qMetaTypeId<TestValue>())
+ return &TestValueType::staticMetaObject;
- return false;
+ return 0;
}
};
@@ -279,6 +277,7 @@ void tst_qqmlvaluetypeproviders::userType()
Q_ASSERT(qMetaTypeId<TestValue>() >= QMetaType::User);
qRegisterMetaType<TestValue>();
+ QMetaType::registerComparators<TestValue>();
qmlRegisterType<TestValueExporter>("Test", 1, 0, "TestValueExporter");
TestValueExporter exporter;
diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
index ce2723bbf9..e3703eac00 100644
--- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
+++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
@@ -79,7 +79,6 @@ private slots:
void deletedObject();
void bindingVariantCopy();
void scriptVariantCopy();
- void cppClasses();
void enums();
void conflictingBindings();
void returnValues();
@@ -1166,26 +1165,6 @@ void tst_qqmlvaluetypes::scriptVariantCopy()
delete object;
}
-
-// Test that the value type classes can be used manually
-void tst_qqmlvaluetypes::cppClasses()
-{
- CPP_TEST(QQmlPointValueType, QPoint(19, 33));
- CPP_TEST(QQmlPointFValueType, QPointF(33.6, -23));
- CPP_TEST(QQmlSizeValueType, QSize(-100, 18));
- CPP_TEST(QQmlSizeFValueType, QSizeF(-100.7, 18.2));
- CPP_TEST(QQmlRectValueType, QRect(13, 39, 10928, 88));
- CPP_TEST(QQmlRectFValueType, QRectF(88.2, -90.1, 103.2, 118));
- CPP_TEST(QQuickVector2DValueType, QVector2D(19.7f, 1002));
- CPP_TEST(QQuickVector3DValueType, QVector3D(18.2f, 19.7f, 1002));
- CPP_TEST(QQuickVector4DValueType, QVector4D(18.2f, 19.7f, 1002, 54));
- CPP_TEST(QQuickQuaternionValueType, QQuaternion(18.2f, 19.7f, 1002, 54));
- CPP_TEST(QQuickMatrix4x4ValueType,
- QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
- CPP_TEST(QQuickFontValueType, QFont("Helvetica"));
-
-}
-
void tst_qqmlvaluetypes::enums()
{
{