From e3a817ec77f653100bf29389464af8ac8706d8e3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 17 Nov 2022 17:52:26 +0200 Subject: [PATCH] QmlDesigner: Hide or disable material browser and editor if no library If material library is missing, material browser and editor UI should be disabled, except for material editor main pane in case of root material node. Change-Id: I3d2bd545de0649fb90d3fe1f751d46b7c7054bbf Reviewed-by: Mahmoud Badri --- .../MaterialBrowser.qml | 26 +++++++++---------- .../EmptyMaterialEditorPane.qml | 10 +++++-- .../MaterialEditorToolBar.qml | 8 +++--- .../materialbrowser/materialbrowsermodel.cpp | 12 ++++----- .../materialbrowser/materialbrowsermodel.h | 10 +++---- .../materialbrowser/materialbrowserview.cpp | 9 +++++-- .../materialeditorcontextobject.cpp | 12 ++++----- .../materialeditorcontextobject.h | 10 +++---- .../materialeditor/materialeditorview.cpp | 22 ++++++++++++++-- .../materialeditor/materialeditorview.h | 4 +++ .../designercore/model/abstractview.cpp | 5 +++- .../designercore/include/nodemetainfo.h | 1 + 12 files changed, 83 insertions(+), 46 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index d93f236fede..54476c3be43 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -12,6 +12,8 @@ Item { readonly property int cellWidth: 100 readonly property int cellHeight: 120 + readonly property bool enableUiElements: materialBrowserModel.hasMaterialLibrary + && materialBrowserModel.hasQuick3DImport property var currMaterialItem: null @@ -54,16 +56,14 @@ Item { acceptedButtons: Qt.RightButton onClicked: (mouse) => { - if (materialBrowserModel.hasMaterialRoot || !materialBrowserModel.hasQuick3DImport) + if (!root.enableUiElements) return; var matsSecBottom = mapFromItem(materialsSection, 0, materialsSection.y).y + materialsSection.height; - if (!materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport - && mouse.y < matsSecBottom) { + if (mouse.y < matsSecBottom) ctxMenu.popupMenu() - } } } @@ -90,7 +90,7 @@ Item { Row { width: root.width - enabled: !materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport + enabled: root.enableUiElements StudioControls.SearchBox { id: searchBox @@ -105,10 +105,10 @@ Item { Text { text: { - if (materialBrowserModel.hasMaterialRoot) - qsTr("Material Browser is disabled inside a material component.") - else if (!materialBrowserModel.hasQuick3DImport) + if (!materialBrowserModel.hasQuick3DImport) qsTr("To use Material Browser, first add the QtQuick3D module in the Components view.") + else if (!materialBrowserModel.hasMaterialLibrary) + qsTr("Material Browser is disabled inside a non-visual component.") else "" } @@ -129,7 +129,7 @@ Item { width: root.width height: root.height - searchBox.height clip: true - visible: materialBrowserModel.hasQuick3DImport && !materialBrowserModel.hasMaterialRoot + visible: root.enableUiElements interactive: !ctxMenu.opened Column { @@ -187,7 +187,7 @@ Item { color: StudioTheme.Values.themeTextColor font.pixelSize: StudioTheme.Values.baseFontSize leftPadding: 10 - visible: materialBrowserModel.isEmpty && !searchBox.isEmpty() && !materialBrowserModel.hasMaterialRoot + visible: materialBrowserModel.isEmpty && !searchBox.isEmpty() && materialBrowserModel.hasMaterialLibrary } Text { @@ -213,7 +213,7 @@ Item { normalColor: "transparent" buttonSize: StudioTheme.Values.sectionHeadHeight onClicked: materialBrowserModel.addNewMaterial() - enabled: materialBrowserModel.hasQuick3DImport + enabled: root.enableUiElements } } @@ -254,7 +254,7 @@ Item { color: StudioTheme.Values.themeTextColor font.pixelSize: StudioTheme.Values.baseFontSize leftPadding: 10 - visible: materialBrowserModel.isEmpty && !searchBox.isEmpty() && !materialBrowserModel.hasMaterialRoot + visible: materialBrowserModel.isEmpty && !searchBox.isEmpty() && materialBrowserModel.hasMaterialLibrary } Text { @@ -280,7 +280,7 @@ Item { normalColor: "transparent" buttonSize: StudioTheme.Values.sectionHeadHeight onClicked: materialBrowserTexturesModel.addNewTexture() - enabled: materialBrowserModel.hasQuick3DImport + enabled: root.enableUiElements } } } diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/EmptyMaterialEditorPane.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/EmptyMaterialEditorPane.qml index 5b9044ac4c2..304279b63af 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/EmptyMaterialEditorPane.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/EmptyMaterialEditorPane.qml @@ -32,8 +32,14 @@ PropertyEditorPane { height: 150 Text { - text: hasQuick3DImport ? qsTr("There are no materials in this project.
Select '+' to create one.") - : qsTr("To use Material Editor, first add the QtQuick3D module in the Components view.") + text: { + if (!hasQuick3DImport) + qsTr("To use Material Editor, first add the QtQuick3D module in the Components view.") + else if (!hasMaterialLibrary) + qsTr("Material Editor is disabled inside a non-visual component.") + else + qsTr("There are no materials in this project.
Select '+' to create one.") + } textFormat: Text.RichText color: StudioTheme.Values.themeTextColor font.pixelSize: StudioTheme.Values.mediumFontSize diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorToolBar.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorToolBar.qml index 0a1b97f34bb..25edbf2d083 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorToolBar.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorToolBar.qml @@ -28,7 +28,7 @@ Rectangle { normalColor: StudioTheme.Values.themeSectionHeadBackground iconSize: StudioTheme.Values.bigIconFontSize buttonSize: root.height - enabled: hasMaterial && hasModelSelection && hasQuick3DImport && !hasMaterialRoot + enabled: hasMaterial && hasModelSelection && hasQuick3DImport && hasMaterialLibrary onClicked: root.toolBarAction(ToolBarAction.ApplyToSelected) tooltip: qsTr("Apply material to selected model.") } @@ -39,7 +39,7 @@ Rectangle { normalColor: StudioTheme.Values.themeSectionHeadBackground iconSize: StudioTheme.Values.bigIconFontSize buttonSize: root.height - enabled: hasQuick3DImport && !hasMaterialRoot + enabled: hasQuick3DImport && hasMaterialLibrary onClicked: root.toolBarAction(ToolBarAction.AddNewMaterial) tooltip: qsTr("Create new material.") } @@ -50,7 +50,7 @@ Rectangle { normalColor: StudioTheme.Values.themeSectionHeadBackground iconSize: StudioTheme.Values.bigIconFontSize buttonSize: root.height - enabled: hasMaterial && hasQuick3DImport && !hasMaterialRoot + enabled: hasMaterial && hasQuick3DImport && hasMaterialLibrary onClicked: root.toolBarAction(ToolBarAction.DeleteCurrentMaterial) tooltip: qsTr("Delete current material.") } @@ -61,7 +61,7 @@ Rectangle { normalColor: StudioTheme.Values.themeSectionHeadBackground iconSize: StudioTheme.Values.bigIconFontSize buttonSize: root.height - enabled: hasMaterial && hasQuick3DImport && !hasMaterialRoot + enabled: hasMaterial && hasQuick3DImport && hasMaterialLibrary onClicked: root.toolBarAction(ToolBarAction.OpenMaterialBrowser) tooltip: qsTr("Open material browser.") } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index ea2e1e47089..210b62d227e 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -171,18 +171,18 @@ void MaterialBrowserModel::setHasModelSelection(bool b) emit hasModelSelectionChanged(); } -bool MaterialBrowserModel::hasMaterialRoot() const +bool MaterialBrowserModel::hasMaterialLibrary() const { - return m_hasMaterialRoot; + return m_hasMaterialLibrary; } -void MaterialBrowserModel::setHasMaterialRoot(bool b) +void MaterialBrowserModel::setHasMaterialLibrary(bool b) { - if (m_hasMaterialRoot == b) + if (m_hasMaterialLibrary == b) return; - m_hasMaterialRoot = b; - emit hasMaterialRootChanged(); + m_hasMaterialLibrary = b; + emit hasMaterialLibraryChanged(); } QString MaterialBrowserModel::copiedMaterialType() const diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index f850aaedb01..ca8c5cad74f 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -21,7 +21,7 @@ class MaterialBrowserModel : public QAbstractListModel Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged) 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(bool hasMaterialLibrary READ hasMaterialLibrary WRITE setHasMaterialLibrary NOTIFY hasMaterialLibraryChanged) 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) @@ -44,8 +44,8 @@ public: bool hasModelSelection() const; void setHasModelSelection(bool b); - bool hasMaterialRoot() const; - void setHasMaterialRoot(bool b); + bool hasMaterialLibrary() const; + void setHasMaterialLibrary(bool b); QString copiedMaterialType() const; void setCopiedMaterialType(const QString &matType); @@ -87,7 +87,7 @@ signals: void isEmptyChanged(); void hasQuick3DImportChanged(); void hasModelSelectionChanged(); - void hasMaterialRootChanged(); + void hasMaterialLibraryChanged(); void copiedMaterialTypeChanged(); void materialSectionsChanged(); void selectedIndexChanged(int idx); @@ -119,7 +119,7 @@ private: bool m_isEmpty = true; bool m_hasQuick3DImport = false; bool m_hasModelSelection = false; - bool m_hasMaterialRoot = false; + bool m_hasMaterialLibrary = false; bool m_allPropsCopied = true; QString m_copiedMaterialType; }; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 5af32bce600..635e9938154 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -164,8 +164,7 @@ void MaterialBrowserView::modelAttached(Model *model) AbstractView::modelAttached(model); m_widget->clearSearchFilter(); - m_widget->materialBrowserModel()->setHasMaterialRoot( - rootModelNode().metaInfo().isQtQuick3DMaterial()); + m_widget->materialBrowserModel()->setHasMaterialLibrary(false); m_hasQuick3DImport = model->hasImport("QtQuick3D"); // Project load is already very busy and may even trigger puppet reset, so let's wait a moment @@ -198,6 +197,7 @@ void MaterialBrowserView::refreshModel(bool updateImages) m_widget->clearSearchFilter(); m_widget->materialBrowserModel()->setMaterials(materials, m_hasQuick3DImport); m_widget->materialBrowserTexturesModel()->setTextures(textures); + m_widget->materialBrowserModel()->setHasMaterialLibrary(matLib.isValid()); if (updateImages) { for (const ModelNode &node : std::as_const(materials)) @@ -223,6 +223,7 @@ bool MaterialBrowserView::isTexture(const ModelNode &node) const void MaterialBrowserView::modelAboutToBeDetached(Model *model) { m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport); + m_widget->materialBrowserModel()->setHasMaterialLibrary(false); m_widget->clearPreviewCache(); if (m_propertyGroupsLoaded) { @@ -291,6 +292,9 @@ void MaterialBrowserView::nodeReparented(const ModelNode &node, { Q_UNUSED(propertyChange) + if (node.id() == Constants::MATERIAL_LIB_ID) + m_widget->materialBrowserModel()->setHasMaterialLibrary(true); + if (!isMaterial(node) && !isTexture(node)) return; @@ -323,6 +327,7 @@ void MaterialBrowserView::nodeAboutToBeRemoved(const ModelNode &removedNode) // removing the material lib node if (removedNode.id() == Constants::MATERIAL_LIB_ID) { m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport); + m_widget->materialBrowserModel()->setHasMaterialLibrary(false); m_widget->clearPreviewCache(); return; } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp index 57e6eab9e25..3f788e7f3fd 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp @@ -227,18 +227,18 @@ void MaterialEditorContextObject::setHasQuick3DImport(bool b) emit hasQuick3DImportChanged(); } -bool MaterialEditorContextObject::hasMaterialRoot() const +bool MaterialEditorContextObject::hasMaterialLibrary() const { - return m_hasMaterialRoot; + return m_hasMaterialLibrary; } -void MaterialEditorContextObject::setHasMaterialRoot(bool b) +void MaterialEditorContextObject::setHasMaterialLibrary(bool b) { - if (b == m_hasMaterialRoot) + if (b == m_hasMaterialLibrary) return; - m_hasMaterialRoot = b; - emit hasMaterialRootChanged(); + m_hasMaterialLibrary = b; + emit hasMaterialLibraryChanged(); } bool MaterialEditorContextObject::hasModelSelection() const diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.h index af155511338..39aeff83326 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.h @@ -38,7 +38,7 @@ class MaterialEditorContextObject : public QObject Q_PROPERTY(bool hasActiveTimeline READ hasActiveTimeline NOTIFY hasActiveTimelineChanged) 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(bool hasMaterialLibrary READ hasMaterialLibrary WRITE setHasMaterialLibrary NOTIFY hasMaterialLibraryChanged) Q_PROPERTY(QQmlPropertyMap *backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged) @@ -93,8 +93,8 @@ public: bool hasQuick3DImport() const; void setHasQuick3DImport(bool b); - bool hasMaterialRoot() const; - void setHasMaterialRoot(bool b); + bool hasMaterialLibrary() const; + void setHasMaterialLibrary(bool b); bool hasModelSelection() const; void setHasModelSelection(bool b); @@ -132,7 +132,7 @@ signals: void hasAliasExportChanged(); void hasActiveTimelineChanged(); void hasQuick3DImportChanged(); - void hasMaterialRootChanged(); + void hasMaterialLibraryChanged(); void hasModelSelectionChanged(); private: @@ -161,7 +161,7 @@ private: bool m_aliasExport = false; bool m_hasActiveTimeline = false; bool m_hasQuick3DImport = false; - bool m_hasMaterialRoot = false; + bool m_hasMaterialLibrary = false; bool m_hasModelSelection = false; ModelNode m_selectedMaterial; diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 379ccc411ac..e93f99cb7d2 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -61,6 +61,8 @@ MaterialEditorView::MaterialEditorView(ExternalDependenciesInterface &externalDe if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation() && model()->rewriterView()->errors().isEmpty()) { ensureMaterialLibraryNode(); + if (m_qmlBackEnd && m_qmlBackEnd->contextObject()) + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(materialLibraryNode().isValid()); m_ensureMatLibTimer.stop(); } }); @@ -534,7 +536,7 @@ void MaterialEditorView::setupQmlBackend() QString specificQmlData; QString currentTypeName; - if (m_selectedMaterial.isValid() && m_hasQuick3DImport) { + if (m_selectedMaterial.isValid() && m_hasQuick3DImport && (materialLibraryNode().isValid() || m_hasMaterialRoot)) { qmlPaneUrl = QUrl::fromLocalFile(materialEditorResourcesPath() + "/MaterialEditorPane.qml"); TypeName diffClassName; @@ -587,7 +589,7 @@ void MaterialEditorView::setupQmlBackend() currentQmlBackend->widget()->installEventFilter(this); currentQmlBackend->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); - currentQmlBackend->contextObject()->setHasMaterialRoot(m_hasMaterialRoot); + currentQmlBackend->contextObject()->setHasMaterialLibrary(materialLibraryNode().isValid()); currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData); currentQmlBackend->contextObject()->setCurrentType(currentTypeName); @@ -781,6 +783,7 @@ void MaterialEditorView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); m_dynamicPropertiesModel->reset(); m_qmlBackEnd->materialEditorTransaction()->end(); + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); } void MaterialEditorView::propertiesRemoved(const QList &propertyList) @@ -1103,6 +1106,21 @@ void MaterialEditorView::customNotification([[maybe_unused]] const AbstractView } } +void MaterialEditorView::nodeReparented(const ModelNode &node, + const NodeAbstractProperty &newPropertyParent, + const NodeAbstractProperty &oldPropertyParent, + PropertyChangeFlags propertyChange) +{ + if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(true); +} + +void MaterialEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) +{ + if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); +} + void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highlight) { if (!m_selectedMaterial.isValid()) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index 5c0a59d3a0e..c0880c738bc 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -62,6 +62,10 @@ public: void importsChanged(const QList &addedImports, const QList &removedImports) override; void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; + void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, + const NodeAbstractProperty &oldPropertyParent, + AbstractView::PropertyChangeFlags propertyChange) override; + void nodeAboutToBeRemoved(const ModelNode &removedNode) override; void dragStarted(QMimeData *mimeData) override; void dragEnded() override; diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 8f937f97958..fe5d5a18ca8 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -806,8 +806,11 @@ void AbstractView::changeRootNodeType(const TypeName &type, int majorVersion, in void AbstractView::ensureMaterialLibraryNode() { ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); - if (matLib.isValid() || rootModelNode().metaInfo().isQtQuick3DMaterial()) + if (matLib.isValid() + || (!rootModelNode().metaInfo().isQtQuick3DNode() + && !rootModelNode().metaInfo().isQtQuickItem())) { return; + } executeInTransaction(__FUNCTION__, [&] { // Create material library node diff --git a/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h b/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h index 9a350961032..f898f752152 100644 --- a/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h +++ b/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h @@ -76,6 +76,7 @@ public: bool isQtQuick3DModel() const { return {}; } bool isQtQuick3DMaterial() const { return {}; } bool isQtQuickLoader() const { return {}; } + bool isQtQuickItem() const { return {}; } QString importDirectoryPath() const { return {}; }