summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2022-08-12 11:47:36 +0300
committerMahmoud Badri <mahmoud.badri@qt.io>2022-08-18 15:11:18 +0000
commit2d86c290ce52953dbb723017b8b226b8599bbeed (patch)
tree5a5cfdbeb283285012b5c1bfd6130bb61aa4dcab
parentc7f742a54603b77b9ad34da299996122b970574b (diff)
downloadqt-creator-2d86c290ce52953dbb723017b8b226b8599bbeed.tar.gz
QmlDesigner: Implement copying specific material properties section
Change-Id: I34bed00c89018e86941c4e5a7ddeae44c06f850d Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
-rw-r--r--share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml41
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp88
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h24
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp20
4 files changed, 147 insertions, 26 deletions
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
index 468b4fb424..a8692f3ef9 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
@@ -39,6 +39,8 @@ Item {
property var currentMaterial: null
property int currentMaterialIdx: 0
+ property var matSectionsModel: []
+
// Called also from C++ to close context menu on focus out
function closeContextMenu()
{
@@ -108,16 +110,45 @@ Item {
height: StudioTheme.Values.border
}
- StudioControls.MenuItem {
- text: qsTr("Copy properties")
+ StudioControls.Menu {
+ title: qsTr("Copy properties")
enabled: root.currentMaterial
- onTriggered: materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx)
+
+ width: parent.width
+
+ onAboutToShow: {
+ root.matSectionsModel = ["All"];
+
+ switch (root.currentMaterial.materialType) {
+ case "DefaultMaterial":
+ root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.defaultMaterialSections);
+ break;
+
+ case "PrincipledMaterial":
+ root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.principledMaterialSections);
+ break;
+
+ case "CustomMaterial":
+ root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.customMaterialSections);
+ break;
+ }
+ }
+
+ Repeater {
+ model: root.matSectionsModel
+
+ StudioControls.MenuItem {
+ text: modelData
+ enabled: root.currentMaterial
+ onTriggered: materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData)
+ }
+ }
}
StudioControls.MenuItem {
text: qsTr("Paste properties")
- enabled: root.currentMaterial && root.currentMaterial.materialType.toString()
- === materialBrowserModel.copiedMaterialType.toString()
+ enabled: root.currentMaterial && root.currentMaterial.materialType
+ === materialBrowserModel.copiedMaterialType
onTriggered: materialBrowserModel.pasteMaterialProperties(root.currentMaterialIdx)
}
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
index 78c25d2c2b..4027a1c75a 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
@@ -65,8 +65,12 @@ QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const
if (roleName == "materialVisible")
return isMaterialVisible(index.row());
- if (roleName == "materialType")
- return m_materialList.at(index.row()).type();
+ if (roleName == "materialType") {
+ QString matType = QString::fromLatin1(m_materialList.at(index.row()).type());
+ if (matType.startsWith("QtQuick3D."))
+ matType.remove("QtQuick3D.");
+ return matType;
+ }
return {};
}
@@ -85,6 +89,50 @@ bool MaterialBrowserModel::isValidIndex(int idx) const
return idx > -1 && idx < rowCount();
}
+/**
+ * @brief Loads and parses propertyGroups.json from QtQuick3D module's designer folder
+ *
+ * propertyGroups.json contains lists of QtQuick3D objects' properties grouped by sections
+ *
+ * @param path path to propertyGroups.json file
+ */
+void MaterialBrowserModel::loadPropertyGroups(const QString &path)
+{
+ bool ok = true;
+
+ if (m_propertyGroupsObj.isEmpty()) {
+ QFile matPropsFile(path);
+
+ if (!matPropsFile.open(QIODevice::ReadOnly)) {
+ qWarning("Couldn't open propertyGroups.json");
+ ok = false;
+ }
+
+ if (ok) {
+ QJsonDocument matPropsJsonDoc = QJsonDocument::fromJson(matPropsFile.readAll());
+ if (matPropsJsonDoc.isNull()) {
+ qWarning("Invalid propertyGroups.json file");
+ ok = false;
+ } else {
+ m_propertyGroupsObj = matPropsJsonDoc.object();
+ }
+ }
+ }
+
+ m_defaultMaterialSections.clear();
+ m_principledMaterialSections.clear();
+ m_customMaterialSections.clear();
+ if (ok) {
+ m_defaultMaterialSections.append(m_propertyGroupsObj.value("DefaultMaterial").toObject().keys());
+ m_principledMaterialSections.append(m_propertyGroupsObj.value("PrincipledMaterial").toObject().keys());
+
+ QStringList customMatSections = m_propertyGroupsObj.value("CustomMaterial").toObject().keys();
+ if (customMatSections.size() > 1) // as of now custom material has only 1 section, so we don't add it
+ m_customMaterialSections.append(customMatSections);
+ }
+ emit materialSectionsChanged();
+}
+
QHash<int, QByteArray> MaterialBrowserModel::roleNames() const
{
static const QHash<int, QByteArray> roles {
@@ -138,12 +186,12 @@ void MaterialBrowserModel::setHasMaterialRoot(bool b)
emit hasMaterialRootChanged();
}
-TypeName MaterialBrowserModel::copiedMaterialType() const
+QString MaterialBrowserModel::copiedMaterialType() const
{
return m_copiedMaterialType;
}
-void MaterialBrowserModel::setCopiedMaterialType(const TypeName &matType)
+void MaterialBrowserModel::setCopiedMaterialType(const QString &matType)
{
if (matType == m_copiedMaterialType)
return;
@@ -294,16 +342,40 @@ void MaterialBrowserModel::duplicateMaterial(int idx)
emit duplicateMaterialTriggered(m_materialList.at(idx));
}
-void MaterialBrowserModel::copyMaterialProperties(int idx)
+void MaterialBrowserModel::copyMaterialProperties(int idx, const QString &section)
{
ModelNode mat = m_materialList.at(idx);
- m_copiedMaterialProps = mat.properties();
- setCopiedMaterialType(mat.type());
+ QString matType = QString::fromLatin1(mat.type());
+
+ if (matType.startsWith("QtQuick3D."))
+ matType.remove("QtQuick3D.");
+
+ setCopiedMaterialType(matType);
+ m_allPropsCopied = section == "All";
+
+ if (m_allPropsCopied || m_propertyGroupsObj.empty()) {
+ m_copiedMaterialProps = mat.properties();
+ } 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();
+ for (const QJsonValueRef &propName : propNames)
+ m_copiedMaterialProps.append(mat.property(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();
+ for (const QJsonValueRef &propName : propNames)
+ m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
+ }
+ }
+ }
}
void MaterialBrowserModel::pasteMaterialProperties(int idx)
{
- emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps);
+ emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps, m_allPropsCopied);
}
void MaterialBrowserModel::deleteMaterial(int idx)
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h
index bafcdc1fa8..5f38e7488e 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h
@@ -25,6 +25,7 @@
#pragma once
+#include "qjsonobject.h"
#include <modelnode.h>
#include <qmlobjectnode.h>
@@ -43,7 +44,10 @@ class MaterialBrowserModel : public QAbstractListModel
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
- Q_PROPERTY(TypeName copiedMaterialType READ copiedMaterialType WRITE setCopiedMaterialType NOTIFY copiedMaterialTypeChanged)
+ Q_PROPERTY(QString copiedMaterialType READ copiedMaterialType WRITE setCopiedMaterialType NOTIFY copiedMaterialTypeChanged)
+ Q_PROPERTY(QStringList defaultMaterialSections MEMBER m_defaultMaterialSections NOTIFY materialSectionsChanged)
+ Q_PROPERTY(QStringList principledMaterialSections MEMBER m_principledMaterialSections NOTIFY materialSectionsChanged)
+ Q_PROPERTY(QStringList customMaterialSections MEMBER m_customMaterialSections NOTIFY materialSectionsChanged)
public:
MaterialBrowserModel(QObject *parent = nullptr);
@@ -64,8 +68,8 @@ public:
bool hasMaterialRoot() const;
void setHasMaterialRoot(bool b);
- TypeName copiedMaterialType() const;
- void setCopiedMaterialType(const TypeName &matType);
+ QString copiedMaterialType() const;
+ void setCopiedMaterialType(const QString &matType);
QList<ModelNode> materials() const;
void setMaterials(const QList<ModelNode> &materials, bool hasQuick3DImport);
@@ -75,12 +79,13 @@ public:
void updateSelectedMaterial();
int materialIndex(const ModelNode &material) const;
ModelNode materialAt(int idx) const;
+ void loadPropertyGroups(const QString &path);
void resetModel();
Q_INVOKABLE void selectMaterial(int idx, bool force = false);
Q_INVOKABLE void duplicateMaterial(int idx);
- Q_INVOKABLE void copyMaterialProperties(int idx);
+ Q_INVOKABLE void copyMaterialProperties(int idx, const QString &section);
Q_INVOKABLE void pasteMaterialProperties(int idx);
Q_INVOKABLE void deleteMaterial(int idx);
Q_INVOKABLE void renameMaterial(int idx, const QString &newName);
@@ -94,13 +99,15 @@ signals:
void hasModelSelectionChanged();
void hasMaterialRootChanged();
void copiedMaterialTypeChanged();
+ void materialSectionsChanged();
void selectedIndexChanged(int idx);
void renameMaterialTriggered(const QmlDesigner::ModelNode &material, const QString &newName);
void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
void addNewMaterialTriggered();
void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material);
void pasteMaterialPropertiesTriggered(const QmlDesigner::ModelNode &material,
- const QList<QmlDesigner::AbstractProperty> &props);
+ const QList<QmlDesigner::AbstractProperty> &props,
+ bool all);
private:
bool isMaterialVisible(int idx) const;
@@ -108,15 +115,20 @@ private:
QString m_searchText;
QList<ModelNode> m_materialList;
+ QStringList m_defaultMaterialSections;
+ QStringList m_principledMaterialSections;
+ QStringList m_customMaterialSections;
QList<AbstractProperty> m_copiedMaterialProps;
QHash<qint32, int> m_materialIndexHash; // internalId -> index
+ QJsonObject m_propertyGroupsObj;
int m_selectedIndex = 0;
bool m_isEmpty = true;
bool m_hasQuick3DImport = false;
bool m_hasModelSelection = false;
bool m_hasMaterialRoot = false;
- TypeName m_copiedMaterialType;
+ bool m_allPropsCopied = true;
+ QString m_copiedMaterialType;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
index ac792f6470..0d05b12d6a 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
@@ -29,6 +29,7 @@
#include "materialbrowserwidget.h"
#include "materialbrowsermodel.h"
#include "nodeabstractproperty.h"
+#include "nodemetainfo.h"
#include "qmlobjectnode.h"
#include "variantproperty.h"
@@ -43,7 +44,6 @@ namespace QmlDesigner {
MaterialBrowserView::MaterialBrowserView(QObject *parent)
: AbstractView(parent)
-
{}
MaterialBrowserView::~MaterialBrowserView()
@@ -91,14 +91,16 @@ WidgetInfo MaterialBrowserView::widgetInfo()
});
connect(matBrowserModel, &MaterialBrowserModel::pasteMaterialPropertiesTriggered, this,
- [&] (const ModelNode &material, const QList<AbstractProperty> &props) {
+ [&] (const ModelNode &material, const QList<AbstractProperty> &props, bool all) {
QmlObjectNode mat(material);
executeInTransaction(__FUNCTION__, [&] {
- // remove current properties
- const PropertyNameList propNames = material.propertyNames();
- for (const PropertyName &propName : propNames) {
- if (propName != "objectName")
- mat.removeProperty(propName);
+ if (all) { // all material properties copied
+ // remove current properties
+ const PropertyNameList propNames = material.propertyNames();
+ for (const PropertyName &propName : propNames) {
+ if (propName != "objectName")
+ mat.removeProperty(propName);
+ }
}
// apply pasted properties
@@ -126,6 +128,10 @@ void MaterialBrowserView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
+ QString matPropsPath = model->metaInfo("QtQuick3D.Material").importDirectoryPath()
+ + "/designer/propertyGroups.json";
+ m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
+
m_widget->clearSearchFilter();
m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material"));
m_hasQuick3DImport = model->hasImport("QtQuick3D");