QmlDesigner: Add support for vector2d type qml properties

Change-Id: I418353cf9d5d31241c4c327d41e4457df19fe0bd
Fixes: QDS-2189
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-05-29 17:47:57 +03:00
parent 9b91b51285
commit caf0f6e132
7 changed files with 127 additions and 24 deletions

View File

@@ -48,6 +48,7 @@
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QVector3D> #include <QVector3D>
#include <QVector2D>
#include <QLoggingCategory> #include <QLoggingCategory>
@@ -311,8 +312,19 @@ void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qm
void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyName &name, const QVariant &value) void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyName &name, const QVariant &value)
{ {
if (value.type() == QVariant::Vector3D) { // Vector*D values need to be split into their subcomponents
// Vector3D values need to be split into their subcomponents if (value.type() == QVariant::Vector2D) {
const char *suffix[2] = {"_x", "_y"};
auto vecValue = value.value<QVector2D>();
for (int i = 0; i < 2; ++i) {
PropertyName subPropName(name.size() + 2, '\0');
subPropName.replace(0, name.size(), name);
subPropName.replace(name.size(), 2, suffix[i]);
auto propertyValue = qobject_cast<PropertyEditorValue *>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName))));
if (propertyValue)
propertyValue->setValue(QVariant(vecValue[i]));
}
} else if (value.type() == QVariant::Vector3D) {
const char *suffix[3] = {"_x", "_y", "_z"}; const char *suffix[3] = {"_x", "_y", "_z"};
auto vecValue = value.value<QVector3D>(); auto vecValue = value.value<QVector3D>();
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {

View File

@@ -225,8 +225,9 @@ void PropertyEditorView::changeValue(const QString &name)
if (!value->value().isValid()) { //reset if (!value->value().isValid()) { //reset
removePropertyFromModel(propertyName); removePropertyFromModel(propertyName);
} else { } else {
// QVector3D(0, 0, 0) detects as null variant though it is valid value // QVector*D(0, 0, 0) detects as null variant though it is valid value
if (castedValue.isValid() && (!castedValue.isNull() if (castedValue.isValid() && (!castedValue.isNull()
|| castedValue.type() == QVariant::Vector2D
|| castedValue.type() == QVariant::Vector3D)) { || castedValue.type() == QVariant::Vector3D)) {
commitVariantValueToModel(propertyName, castedValue); commitVariantValueToModel(propertyName, castedValue);
} }

View File

@@ -33,6 +33,7 @@
#include <QDebug> #include <QDebug>
#include <QPainter> #include <QPainter>
#include <QVector3D> #include <QVector3D>
#include <QVector2D>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
void qt_blurImage(QPainter *painter, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); void qt_blurImage(QPainter *painter, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
@@ -316,7 +317,23 @@ QVariant NodeInstance::property(const PropertyName &name) const
if (index != -1) { if (index != -1) {
PropertyName parentPropName = name.left(index); PropertyName parentPropName = name.left(index);
QVariant varValue = d->propertyValues.value(parentPropName); QVariant varValue = d->propertyValues.value(parentPropName);
if (varValue.type() == QVariant::Vector3D) { if (varValue.type() == QVariant::Vector2D) {
auto value = varValue.value<QVector2D>();
char subProp = name.right(1)[0];
float subValue = 0.f;
switch (subProp) {
case 'x':
subValue = value.x();
break;
case 'y':
subValue = value.y();
break;
default:
subValue = 0.f;
break;
}
return QVariant(subValue);
} else if (varValue.type() == QVariant::Vector3D) {
auto value = varValue.value<QVector3D>(); auto value = varValue.value<QVector3D>();
char subProp = name.right(1)[0]; char subProp = name.right(1)[0];
float subValue = 0.f; float subValue = 0.f;
@@ -397,22 +414,38 @@ void NodeInstance::setProperty(const PropertyName &name, const QVariant &value)
if (index != -1) { if (index != -1) {
PropertyName parentPropName = name.left(index); PropertyName parentPropName = name.left(index);
QVariant oldValue = d->propertyValues.value(parentPropName); QVariant oldValue = d->propertyValues.value(parentPropName);
QVector3D newValue; QVariant newValueVar;
if (oldValue.type() == QVariant::Vector3D)
newValue = oldValue.value<QVector3D>();
bool update = false; bool update = false;
if (name.endsWith(".x")) { if (oldValue.type() == QVariant::Vector2D) {
newValue.setX(value.toFloat()); QVector2D newValue;
update = true; if (oldValue.type() == QVariant::Vector2D)
} else if (name.endsWith(".y")) { newValue = oldValue.value<QVector2D>();
newValue.setY(value.toFloat()); if (name.endsWith(".x")) {
update = true; newValue.setX(value.toFloat());
} else if (name.endsWith(".z")) { update = true;
newValue.setZ(value.toFloat()); } else if (name.endsWith(".y")) {
update = true; newValue.setY(value.toFloat());
update = true;
}
newValueVar = newValue;
} else if (oldValue.type() == QVariant::Vector3D) {
QVector3D newValue;
if (oldValue.type() == QVariant::Vector3D)
newValue = oldValue.value<QVector3D>();
if (name.endsWith(".x")) {
newValue.setX(value.toFloat());
update = true;
} else if (name.endsWith(".y")) {
newValue.setY(value.toFloat());
update = true;
} else if (name.endsWith(".z")) {
newValue.setZ(value.toFloat());
update = true;
}
newValueVar = newValue;
} }
if (update) { if (update) {
d->propertyValues.insert(parentPropName, newValue); d->propertyValues.insert(parentPropName, newValueVar);
return; return;
} }
} }

View File

@@ -336,14 +336,14 @@ private:
static inline bool isValueType(const TypeName &type) static inline bool isValueType(const TypeName &type)
{ {
static const PropertyTypeList objectValuesList({"QFont", "QPoint", "QPointF", static const PropertyTypeList objectValuesList({"QFont", "QPoint", "QPointF",
"QSize", "QSizeF", "QVector3D", "QVector2D", "font"}); "QSize", "QSizeF", "QVector3D", "QVector2D", "vector2d", "vector3d", "font"});
return objectValuesList.contains(type); return objectValuesList.contains(type);
} }
static inline bool isValueType(const QString &type) static inline bool isValueType(const QString &type)
{ {
static const QStringList objectValuesList({"QFont", "QPoint", "QPointF", static const QStringList objectValuesList({"QFont", "QPoint", "QPointF",
"QSize", "QSizeF", "QVector3D", "QVector2D", "font"}); "QSize", "QSizeF", "QVector3D", "QVector2D", "vector2d", "vector3d", "font"});
return objectValuesList.contains(type); return objectValuesList.contains(type);
} }
@@ -494,8 +494,28 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
PropertyMemberProcessor processor(context); PropertyMemberProcessor processor(context);
objectValue->processMembers(&processor); objectValue->processMembers(&processor);
const auto props = processor.properties();
propertyList.append(processor.properties()); for (const PropertyInfo &property : props) {
const PropertyName name = property.first;
const QString nameAsString = QString::fromUtf8(name);
if (isValueType(property.second)) {
const Value *dotValue = objectValue->lookupMember(nameAsString, context);
if (const Reference *ref = dotValue->asReference())
dotValue = context->lookupReference(ref);
if (const ObjectValue *dotObjectValue = dotValue->asObjectValue()) {
const QVector<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue, context, false, rec + 1);
for (const PropertyInfo &propertyInfo : dotProperties) {
const PropertyName dotName = name + '.' + propertyInfo.first;
const TypeName type = propertyInfo.second;
propertyList.append({dotName, type});
}
}
}
propertyList.append(property);
}
if (!local) { if (!local) {
const ObjectValue* prototype = objectValue->prototype(context); const ObjectValue* prototype = objectValue->prototype(context);
@@ -1067,6 +1087,9 @@ QVariant::Type NodeMetaInfoPrivate::variantTypeId(const PropertyName &propertyNa
if (typeName == "var") if (typeName == "var")
return QVariant::UserType; return QVariant::UserType;
if (typeName == "vector2d")
return QVariant::Vector2D;
if (typeName == "vector3d") if (typeName == "vector3d")
return QVariant::Vector3D; return QVariant::Vector3D;

View File

@@ -31,6 +31,7 @@
#include <QUrl> #include <QUrl>
#include <QVector3D> #include <QVector3D>
#include <QVector2D>
#include <QDebug> #include <QDebug>
namespace { namespace {
@@ -151,6 +152,29 @@ QSizeF sizeFFromString(const QString &s, bool *ok)
return QSizeF(width, height); return QSizeF(width, height);
} }
QVector2D vector2DFromString(const QString &s, bool *ok)
{
if (s.count(QLatin1Char(',')) != 1) {
if (ok)
*ok = false;
return {};
}
bool xGood, yGood;
int index = s.indexOf(QLatin1Char(','));
qreal xCoord = s.leftRef(index).toDouble(&xGood);
qreal yCoord = s.midRef(index + 1).toDouble(&yGood);
if (!xGood || !yGood) {
if (ok)
*ok = false;
return QVector2D();
}
if (ok)
*ok = true;
return QVector2D(xCoord, yCoord);
}
QVector3D vector3DFromString(const QString &s, bool *ok) QVector3D vector3DFromString(const QString &s, bool *ok)
{ {
if (s.count(QLatin1Char(',')) != 2) { if (s.count(QLatin1Char(',')) != 2) {
@@ -241,6 +265,9 @@ QVariant read(int variantType, const QString &str)
case QMetaType::QColor: case QMetaType::QColor:
value = colorFromString(str, &conversionOk); value = colorFromString(str, &conversionOk);
break; break;
case QMetaType::QVector2D:
value = vector2DFromString(str, &conversionOk);
break;
case QMetaType::QVector3D: case QMetaType::QVector3D:
value = vector3DFromString(str, &conversionOk); value = vector3DFromString(str, &conversionOk);
break; break;
@@ -277,8 +304,10 @@ QVariant variantFromString(const QString &s)
if (ok) return QVariant(p); if (ok) return QVariant(p);
QSizeF sz = sizeFFromString(s, &ok); QSizeF sz = sizeFFromString(s, &ok);
if (ok) return QVariant(sz); if (ok) return QVariant(sz);
QVector3D v = vector3DFromString(s, &ok); QVector3D v3 = vector3DFromString(s, &ok);
if (ok) return QVariant::fromValue(v); if (ok) return QVariant::fromValue(v3);
QVector2D v2 = vector2DFromString(s, &ok);
if (ok) return QVariant::fromValue(v2);
return QVariant(s); return QVariant(s);
} }

View File

@@ -28,6 +28,7 @@
#include <QVariant> #include <QVariant>
#include <QColor> #include <QColor>
#include <QVector3D> #include <QVector3D>
#include <QVector2D>
#include "bindingproperty.h" #include "bindingproperty.h"
#include "signalhandlerproperty.h" #include "signalhandlerproperty.h"
@@ -150,6 +151,10 @@ QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDept
case QMetaType::QString: case QMetaType::QString:
case QMetaType::QChar: case QMetaType::QChar:
return QStringLiteral("\"%1\"").arg(escape(unicodeEscape(stringValue))); return QStringLiteral("\"%1\"").arg(escape(unicodeEscape(stringValue)));
case QMetaType::QVector2D: {
auto vec = value.value<QVector2D>();
return QStringLiteral("Qt.vector2d(%1, %2)").arg(vec.x()).arg(vec.y());
}
case QMetaType::QVector3D: { case QMetaType::QVector3D: {
auto vec = value.value<QVector3D>(); auto vec = value.value<QVector3D>();
return QStringLiteral("Qt.vector3d(%1, %2, %3)").arg(vec.x()).arg(vec.y()).arg(vec.z()); return QStringLiteral("Qt.vector3d(%1, %2, %3)").arg(vec.x()).arg(vec.y()).arg(vec.z());

View File

@@ -57,8 +57,8 @@ void VariantProperty::setValue(const QVariant &value)
if (isDynamic()) if (isDynamic())
qWarning() << "Calling VariantProperty::setValue on dynamic property."; qWarning() << "Calling VariantProperty::setValue on dynamic property.";
// QVector3D(0, 0, 0) detects as null variant though it is valid value // QVector*D(0, 0, 0) detects as null variant though it is valid value
if (value.isNull() && value.type() != QVariant::Vector3D) if (value.isNull() && (value.type() != QVariant::Vector3D && value.type() != QVariant::Vector2D))
throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, name()); throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, name());
if (internalNode()->hasProperty(name())) { //check if oldValue != value if (internalNode()->hasProperty(name())) { //check if oldValue != value