aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2022-09-27 15:05:26 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2022-10-10 13:53:03 +0000
commitb8f4cd97d1bd495f04167e845ba049e54ad68f05 (patch)
tree09a31f04d2ed9e08b5c6ae0bb7a1d2ac64381127
parentb0fa74756504e83b690ca737c6a67de1de8e32ba (diff)
Fix copying dynamic properties on materials
Fixes: QDS-7803 Change-Id: I24c8cd269965552a62fbbbc521efbff00811fa43 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml5
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp58
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h1
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp38
-rw-r--r--src/plugins/qmldesigner/designercore/include/modelnode.h1
-rw-r--r--src/plugins/qmldesigner/designercore/model/modelnode.cpp12
6 files changed, 87 insertions, 28 deletions
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
index 1e50f3f99b..2fecc7582a 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
@@ -125,7 +125,10 @@ Item {
width: parent.width
onAboutToShow: {
- root.matSectionsModel = ["All"];
+ if (root.currentMaterial.hasDynamicProperties)
+ root.matSectionsModel = ["All", "Custom"];
+ else
+ root.matSectionsModel = ["All"];
switch (root.currentMaterial.materialType) {
case "DefaultMaterial":
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
index e9af23eb80..cb3a295259 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
@@ -73,6 +73,9 @@ QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const
return matType;
}
+ if (roleName == "hasDynamicProperties")
+ return !m_materialList.at(index.row()).dynamicProperties().isEmpty();
+
return {};
}
@@ -143,7 +146,8 @@ QHash<int, QByteArray> MaterialBrowserModel::roleNames() const
{Qt::UserRole + 1, "materialName"},
{Qt::UserRole + 2, "materialInternalId"},
{Qt::UserRole + 3, "materialVisible"},
- {Qt::UserRole + 4, "materialType"}
+ {Qt::UserRole + 4, "materialType"},
+ {Qt::UserRole + 5, "hasDynamicProperties"}
};
return roles;
}
@@ -360,33 +364,47 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString &sectio
setCopiedMaterialType(matType);
m_allPropsCopied = section == "All";
+ bool dynamicPropsCopied = section == "Custom";
QmlObjectNode mat(m_copiedMaterial);
QSet<PropertyName> validProps;
+ QHash<PropertyName, TypeName> dynamicProps;
PropertyNameList copiedProps;
- // Base state properties are always valid
- const auto baseProps = m_copiedMaterial.propertyNames();
- for (const auto &baseProp : baseProps)
- validProps.insert(baseProp);
-
- if (!mat.isInBaseState()) {
- QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
- if (changes.isValid()) {
- const QList<AbstractProperty> changedProps = changes.targetProperties();
- for (const auto &changedProp : changedProps)
- validProps.insert(changedProp.name());
+ if (dynamicPropsCopied || m_allPropsCopied) {
+ // Dynamic properties must always be set in base state
+ const QList<AbstractProperty> dynProps = m_copiedMaterial.dynamicProperties();
+ for (const auto &prop : dynProps) {
+ dynamicProps.insert(prop.name(), prop.dynamicTypeName());
+ validProps.insert(prop.name());
}
}
- if (mat.timelineIsActive()) {
- const QList<QmlTimelineKeyframeGroup> keyframeGroups
- = mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial);
- for (const auto &kfg : keyframeGroups)
- validProps.insert(kfg.propertyName());
+ if (!dynamicPropsCopied) {
+ // Base state properties are always valid
+ const auto baseProps = m_copiedMaterial.propertyNames();
+ for (const auto &baseProp : baseProps)
+ validProps.insert(baseProp);
+
+ if (!mat.isInBaseState()) {
+ QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
+ if (changes.isValid()) {
+ const QList<AbstractProperty> changedProps = changes.targetProperties();
+ for (const auto &changedProp : changedProps)
+ validProps.insert(changedProp.name());
+ }
+ }
+
+ if (mat.timelineIsActive()) {
+ const QList<QmlTimelineKeyframeGroup> keyframeGroups
+ = mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial);
+ for (const auto &kfg : keyframeGroups)
+ validProps.insert(kfg.propertyName());
+ }
}
+ validProps.remove("objectName");
- if (m_allPropsCopied || m_propertyGroupsObj.empty()) {
+ if (m_allPropsCopied || dynamicPropsCopied || m_propertyGroupsObj.empty()) {
copiedProps = validProps.values();
} else {
QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject();
@@ -411,8 +429,10 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString &sectio
PropertyCopyData data;
data.name = propName;
data.isValid = m_allPropsCopied || validProps.contains(propName);
- data.isBinding = mat.hasBindingProperty(propName);
if (data.isValid) {
+ if (dynamicProps.contains(propName))
+ data.dynamicTypeName = dynamicProps[propName];
+ data.isBinding = mat.hasBindingProperty(propName);
if (data.isBinding)
data.value = mat.expression(propName);
else
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h
index c054d07527..3cd8b65a41 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h
@@ -97,6 +97,7 @@ public:
struct PropertyCopyData
{
PropertyName name;
+ TypeName dynamicTypeName;
QVariant value;
bool isBinding = false;
bool isValid = false;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
index 01ee657f84..94c75d93a7 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
@@ -25,6 +25,7 @@
#include "materialbrowserview.h"
+#include "bindingproperty.h"
#include "bundlematerial.h"
#include "materialbrowserwidget.h"
#include "materialbrowsermodel.h"
@@ -105,13 +106,19 @@ WidgetInfo MaterialBrowserView::widgetInfo()
// remove current properties
PropertyNameList propNames;
if (mat.isInBaseState()) {
- propNames = material.propertyNames();
+ const QList<AbstractProperty> baseProps = material.properties();
+ for (const auto &baseProp : baseProps) {
+ if (!baseProp.isDynamic())
+ propNames.append(baseProp.name());
+ }
} else {
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
if (changes.isValid()) {
const QList<AbstractProperty> changedProps = changes.targetProperties();
- for (const auto &changedProp : changedProps)
- propNames.append(changedProp.name());
+ for (const auto &changedProp : changedProps) {
+ if (!changedProp.isDynamic())
+ propNames.append(changedProp.name());
+ }
}
}
for (const PropertyName &propName : qAsConst(propNames)) {
@@ -122,14 +129,29 @@ WidgetInfo MaterialBrowserView::widgetInfo()
// apply pasted properties
for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) {
- if (propData.name == "objectName")
- continue;
-
if (propData.isValid) {
- if (propData.isBinding)
+ const bool isDynamic = !propData.dynamicTypeName.isEmpty();
+ const bool isBaseState = currentState().isBaseState();
+ const bool hasProperty = mat.hasProperty(propData.name);
+ if (propData.isBinding) {
+ if (isDynamic && (!hasProperty || isBaseState)) {
+ mat.modelNode().bindingProperty(propData.name)
+ .setDynamicTypeNameAndExpression(
+ propData.dynamicTypeName, propData.value.toString());
+ continue;
+ }
mat.setBindingProperty(propData.name, propData.value.toString());
- else
+ } else {
+ const bool isRecording = mat.timelineIsActive()
+ && mat.currentTimeline().isRecording();
+ if (isDynamic && (!hasProperty || (isBaseState && !isRecording))) {
+ mat.modelNode().variantProperty(propData.name)
+ .setDynamicTypeNameAndValue(
+ propData.dynamicTypeName, propData.value);
+ continue;
+ }
mat.setVariantProperty(propData.name, propData.value);
+ }
} else {
mat.removeProperty(propData.name);
}
diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h
index def083f02f..e44234fffb 100644
--- a/src/plugins/qmldesigner/designercore/include/modelnode.h
+++ b/src/plugins/qmldesigner/designercore/include/modelnode.h
@@ -145,6 +145,7 @@ public:
QList<NodeListProperty> nodeListProperties() const;
QList<BindingProperty> bindingProperties() const;
QList<SignalHandlerProperty> signalProperties() const;
+ QList<AbstractProperty> dynamicProperties() const;
PropertyNameList propertyNames() const;
bool hasProperties() const;
diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
index 913c67b1a2..c221215acc 100644
--- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
@@ -691,6 +691,18 @@ QList<SignalHandlerProperty> ModelNode::signalProperties() const
return propertyList;
}
+QList<AbstractProperty> ModelNode::dynamicProperties() const
+{
+ QList<AbstractProperty> propertyList;
+
+ const QList<AbstractProperty> abstractProperties = properties();
+ for (const AbstractProperty &abstractProperty : abstractProperties) {
+ if (abstractProperty.isDynamic())
+ propertyList.append(abstractProperty);
+ }
+ return propertyList;
+}
+
/*!
\brief removes a property from this node
\param name name of the property