forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -125,6 +125,9 @@ Item {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
onAboutToShow: {
|
onAboutToShow: {
|
||||||
|
if (root.currentMaterial.hasDynamicProperties)
|
||||||
|
root.matSectionsModel = ["All", "Custom"];
|
||||||
|
else
|
||||||
root.matSectionsModel = ["All"];
|
root.matSectionsModel = ["All"];
|
||||||
|
|
||||||
switch (root.currentMaterial.materialType) {
|
switch (root.currentMaterial.materialType) {
|
||||||
|
@@ -73,6 +73,9 @@ QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const
|
|||||||
return matType;
|
return matType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (roleName == "hasDynamicProperties")
|
||||||
|
return !m_materialList.at(index.row()).dynamicProperties().isEmpty();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +146,8 @@ QHash<int, QByteArray> MaterialBrowserModel::roleNames() const
|
|||||||
{Qt::UserRole + 1, "materialName"},
|
{Qt::UserRole + 1, "materialName"},
|
||||||
{Qt::UserRole + 2, "materialInternalId"},
|
{Qt::UserRole + 2, "materialInternalId"},
|
||||||
{Qt::UserRole + 3, "materialVisible"},
|
{Qt::UserRole + 3, "materialVisible"},
|
||||||
{Qt::UserRole + 4, "materialType"}
|
{Qt::UserRole + 4, "materialType"},
|
||||||
|
{Qt::UserRole + 5, "hasDynamicProperties"}
|
||||||
};
|
};
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
@@ -360,11 +364,23 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io
|
|||||||
|
|
||||||
setCopiedMaterialType(matType);
|
setCopiedMaterialType(matType);
|
||||||
m_allPropsCopied = section == "All";
|
m_allPropsCopied = section == "All";
|
||||||
|
bool dynamicPropsCopied = section == "Custom";
|
||||||
QmlObjectNode mat(m_copiedMaterial);
|
QmlObjectNode mat(m_copiedMaterial);
|
||||||
|
|
||||||
QSet<PropertyName> validProps;
|
QSet<PropertyName> validProps;
|
||||||
|
QHash<PropertyName, TypeName> dynamicProps;
|
||||||
PropertyNameList copiedProps;
|
PropertyNameList copiedProps;
|
||||||
|
|
||||||
|
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 (!dynamicPropsCopied) {
|
||||||
// Base state properties are always valid
|
// Base state properties are always valid
|
||||||
const auto baseProps = m_copiedMaterial.propertyNames();
|
const auto baseProps = m_copiedMaterial.propertyNames();
|
||||||
for (const auto &baseProp : baseProps)
|
for (const auto &baseProp : baseProps)
|
||||||
@@ -385,8 +401,10 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io
|
|||||||
for (const auto &kfg : keyframeGroups)
|
for (const auto &kfg : keyframeGroups)
|
||||||
validProps.insert(kfg.propertyName());
|
validProps.insert(kfg.propertyName());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
validProps.remove("objectName");
|
||||||
|
|
||||||
if (m_allPropsCopied || m_propertyGroupsObj.empty()) {
|
if (m_allPropsCopied || dynamicPropsCopied || m_propertyGroupsObj.empty()) {
|
||||||
copiedProps = validProps.values();
|
copiedProps = validProps.values();
|
||||||
} else {
|
} else {
|
||||||
QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject();
|
QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject();
|
||||||
@@ -411,8 +429,10 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io
|
|||||||
PropertyCopyData data;
|
PropertyCopyData data;
|
||||||
data.name = propName;
|
data.name = propName;
|
||||||
data.isValid = m_allPropsCopied || validProps.contains(propName);
|
data.isValid = m_allPropsCopied || validProps.contains(propName);
|
||||||
data.isBinding = mat.hasBindingProperty(propName);
|
|
||||||
if (data.isValid) {
|
if (data.isValid) {
|
||||||
|
if (dynamicProps.contains(propName))
|
||||||
|
data.dynamicTypeName = dynamicProps[propName];
|
||||||
|
data.isBinding = mat.hasBindingProperty(propName);
|
||||||
if (data.isBinding)
|
if (data.isBinding)
|
||||||
data.value = mat.expression(propName);
|
data.value = mat.expression(propName);
|
||||||
else
|
else
|
||||||
|
@@ -97,6 +97,7 @@ public:
|
|||||||
struct PropertyCopyData
|
struct PropertyCopyData
|
||||||
{
|
{
|
||||||
PropertyName name;
|
PropertyName name;
|
||||||
|
TypeName dynamicTypeName;
|
||||||
QVariant value;
|
QVariant value;
|
||||||
bool isBinding = false;
|
bool isBinding = false;
|
||||||
bool isValid = false;
|
bool isValid = false;
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "materialbrowserview.h"
|
#include "materialbrowserview.h"
|
||||||
|
|
||||||
|
#include "bindingproperty.h"
|
||||||
#include "bundlematerial.h"
|
#include "bundlematerial.h"
|
||||||
#include "materialbrowserwidget.h"
|
#include "materialbrowserwidget.h"
|
||||||
#include "materialbrowsermodel.h"
|
#include "materialbrowsermodel.h"
|
||||||
@@ -105,15 +106,21 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
|||||||
// remove current properties
|
// remove current properties
|
||||||
PropertyNameList propNames;
|
PropertyNameList propNames;
|
||||||
if (mat.isInBaseState()) {
|
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 {
|
} else {
|
||||||
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
|
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
|
||||||
if (changes.isValid()) {
|
if (changes.isValid()) {
|
||||||
const QList<AbstractProperty> changedProps = changes.targetProperties();
|
const QList<AbstractProperty> changedProps = changes.targetProperties();
|
||||||
for (const auto &changedProp : changedProps)
|
for (const auto &changedProp : changedProps) {
|
||||||
|
if (!changedProp.isDynamic())
|
||||||
propNames.append(changedProp.name());
|
propNames.append(changedProp.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (const PropertyName &propName : qAsConst(propNames)) {
|
for (const PropertyName &propName : qAsConst(propNames)) {
|
||||||
if (propName != "objectName")
|
if (propName != "objectName")
|
||||||
mat.removeProperty(propName);
|
mat.removeProperty(propName);
|
||||||
@@ -122,14 +129,29 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
|||||||
|
|
||||||
// apply pasted properties
|
// apply pasted properties
|
||||||
for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) {
|
for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) {
|
||||||
if (propData.name == "objectName")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (propData.isValid) {
|
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());
|
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);
|
mat.setVariantProperty(propData.name, propData.value);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mat.removeProperty(propData.name);
|
mat.removeProperty(propData.name);
|
||||||
}
|
}
|
||||||
|
@@ -145,6 +145,7 @@ public:
|
|||||||
QList<NodeListProperty> nodeListProperties() const;
|
QList<NodeListProperty> nodeListProperties() const;
|
||||||
QList<BindingProperty> bindingProperties() const;
|
QList<BindingProperty> bindingProperties() const;
|
||||||
QList<SignalHandlerProperty> signalProperties() const;
|
QList<SignalHandlerProperty> signalProperties() const;
|
||||||
|
QList<AbstractProperty> dynamicProperties() const;
|
||||||
PropertyNameList propertyNames() const;
|
PropertyNameList propertyNames() const;
|
||||||
|
|
||||||
bool hasProperties() const;
|
bool hasProperties() const;
|
||||||
|
@@ -691,6 +691,18 @@ QList<SignalHandlerProperty> ModelNode::signalProperties() const
|
|||||||
return propertyList;
|
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
|
\brief removes a property from this node
|
||||||
\param name name of the property
|
\param name name of the property
|
||||||
|
Reference in New Issue
Block a user