diff options
Diffstat (limited to 'src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp')
-rw-r--r-- | src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index 1f1dff4eef..c075a582e4 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -7,7 +7,8 @@ #include <designmodewidget.h> #include <qmldesignerplugin.h> #include <qmlobjectnode.h> -#include "variantproperty.h" +#include <variantproperty.h> +#include <qmltimelinekeyframegroup.h> #include "utils/qtcassert.h" namespace QmlDesigner { @@ -326,40 +327,84 @@ void MaterialBrowserModel::duplicateMaterial(int idx) void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §ion) { - ModelNode mat = m_materialList.at(idx); - QString matType = QString::fromLatin1(mat.type()); + m_copiedMaterial = m_materialList.at(idx); + + QTC_ASSERT(m_copiedMaterial.isValid(), return); + + QString matType = QString::fromLatin1(m_copiedMaterial.type()); if (matType.startsWith("QtQuick3D.")) matType.remove("QtQuick3D."); setCopiedMaterialType(matType); m_allPropsCopied = section == "All"; + QmlObjectNode mat(m_copiedMaterial); + + QSet<PropertyName> validProps; + 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 (mat.timelineIsActive()) { + const QList<QmlTimelineKeyframeGroup> keyframeGroups + = mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial); + for (const auto &kfg : keyframeGroups) + validProps.insert(kfg.propertyName()); + } if (m_allPropsCopied || m_propertyGroupsObj.empty()) { - m_copiedMaterialProps = mat.properties(); + copiedProps = validProps.values(); } else { QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject(); if (propsSpecObj.contains(section)) { // should always be true - m_copiedMaterialProps.clear(); const QJsonArray propNames = propsSpecObj.value(section).toArray(); // auto == QJsonValueConstRef after 04dc959d49e5e3 / Qt 6.4, QJsonValueRef before for (const auto &propName : propNames) - m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1())); + copiedProps.append(propName.toString().toLatin1()); if (section == "Base") { // add QtQuick3D.Material base props as well QJsonObject propsMatObj = m_propertyGroupsObj.value("Material").toObject(); const QJsonArray propNames = propsMatObj.value("Base").toArray(); // auto == QJsonValueConstRef after 04dc959d49e5e3 / Qt 6.4, QJsonValueRef before for (const auto &propName : propNames) - m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1())); + copiedProps.append(propName.toString().toLatin1()); } } } + + m_copiedMaterialProps.clear(); + for (const auto &propName : copiedProps) { + PropertyCopyData data; + data.name = propName; + data.isValid = m_allPropsCopied || validProps.contains(propName); + data.isBinding = mat.hasBindingProperty(propName); + if (data.isValid) { + if (data.isBinding) + data.value = mat.expression(propName); + else + data.value = mat.modelValue(propName); + } + m_copiedMaterialProps.append(data); + } } void MaterialBrowserModel::pasteMaterialProperties(int idx) { - emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps, m_allPropsCopied); + ModelNode targetMat = m_materialList.at(idx); + if (targetMat.isValid() && m_copiedMaterial.isValid() && targetMat != m_copiedMaterial) + emit pasteMaterialPropertiesTriggered(targetMat, m_copiedMaterialProps, m_allPropsCopied); } void MaterialBrowserModel::deleteMaterial(int idx) @@ -396,4 +441,11 @@ void MaterialBrowserModel::openMaterialEditor() QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); } +// This is provided as invokable instead of property, as it is difficult to know when ModelNode +// becomes invalid. Much simpler to evaluate this on demand. +bool MaterialBrowserModel::isCopiedMaterialValid() const +{ + return m_copiedMaterial.isValid(); +} + } // namespace QmlDesigner |