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 <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2022-11-17 17:52:26 +02:00
parent f70cdf52c4
commit e3a817ec77
12 changed files with 83 additions and 46 deletions

View File

@@ -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("<b>Material Browser</b> is disabled inside a material component.")
else if (!materialBrowserModel.hasQuick3DImport)
if (!materialBrowserModel.hasQuick3DImport)
qsTr("To use <b>Material Browser</b>, first add the QtQuick3D module in the <b>Components</b> view.")
else if (!materialBrowserModel.hasMaterialLibrary)
qsTr("<b>Material Browser</b> 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
}
}
}

View File

@@ -32,8 +32,14 @@ PropertyEditorPane {
height: 150
Text {
text: hasQuick3DImport ? qsTr("There are no materials in this project.<br>Select '<b>+</b>' to create one.")
: qsTr("To use <b>Material Editor</b>, first add the QtQuick3D module in the <b>Components</b> view.")
text: {
if (!hasQuick3DImport)
qsTr("To use <b>Material Editor</b>, first add the QtQuick3D module in the <b>Components</b> view.")
else if (!hasMaterialLibrary)
qsTr("<b>Material Editor</b> is disabled inside a non-visual component.")
else
qsTr("There are no materials in this project.<br>Select '<b>+</b>' to create one.")
}
textFormat: Text.RichText
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.mediumFontSize

View File

@@ -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.")
}

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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<AbstractProperty> &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())

View File

@@ -62,6 +62,10 @@ public:
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
void customNotification(const AbstractView *view, const QString &identifier,
const QList<ModelNode> &nodeList, const QList<QVariant> &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;

View File

@@ -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

View File

@@ -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 {}; }