From 46b0aaeebe36eae52d82c3385183e6d8513ecf3a Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Tue, 21 Mar 2023 12:54:36 +0200 Subject: [PATCH] QmlDesigner: Move assignMaterialTo3dModel() to a utils class In order to avoid dependency of AbstractView on QmlObjectNode. Moreover, it seems not in the right place anymore since it is not really part of an abstract code. Change-Id: I7a64122e6ab0a2e314c593f0f47dadaa07d772e2 Reviewed-by: Miikka Heikkinen Reviewed-by: Thomas Hartmann Reviewed-by: Marco Bubke --- src/plugins/qmldesigner/CMakeLists.txt | 1 + .../components/edit3d/edit3dview.cpp | 5 +- .../components/edit3d/edit3dwidget.cpp | 3 +- .../components/formeditor/dragtool.cpp | 3 +- .../materialbrowser/materialutils.cpp | 71 +++++++++++++++++++ .../materialbrowser/materialutils.h | 20 ++++++ .../navigator/navigatortreemodel.cpp | 9 +-- .../designercore/include/abstractview.h | 1 - .../designercore/model/abstractview.cpp | 55 -------------- 9 files changed, 104 insertions(+), 64 deletions(-) create mode 100644 src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp create mode 100644 src/plugins/qmldesigner/components/materialbrowser/materialutils.h diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 866901d5418..a5644fc66e5 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -825,6 +825,7 @@ extend_qtc_plugin(QmlDesigner materialbrowserwidget.cpp materialbrowserwidget.h materialbrowsermodel.cpp materialbrowsermodel.h materialbrowsertexturesmodel.cpp materialbrowsertexturesmodel.h + materialutils.cpp materialutils.h ) extend_qtc_plugin(QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 304f8e305f9..1ebcf635d97 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -12,6 +12,7 @@ #include "edit3dcanvas.h" #include "edit3dviewconfig.h" #include "edit3dwidget.h" +#include "materialutils.h" #include "metainfo.h" #include "nodehints.h" #include "nodeinstanceview.h" @@ -324,7 +325,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos createdNode = QmlVisualNode::createQml3DNode( this, m_droppedEntry, edit3DWidget()->canvas()->activeScene(), pos3d).modelNode(); if (createdNode.metaInfo().isQtQuick3DModel()) - assignMaterialTo3dModel(createdNode); + MaterialUtils::assignMaterialTo3dModel(this, createdNode); }); if (createdNode.isValid()) setSelectedModelNode(createdNode); @@ -332,7 +333,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos bool isModel = modelNode.metaInfo().isQtQuick3DModel(); if (m_droppedModelNode.isValid() && isModel) { executeInTransaction(__FUNCTION__, [&] { - assignMaterialTo3dModel(modelNode, m_droppedModelNode); + MaterialUtils::assignMaterialTo3dModel(this, modelNode, m_droppedModelNode); }); } } else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) { diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index bf2202717f9..1e842298dd5 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -8,6 +8,7 @@ #include "edit3dcanvas.h" #include "edit3dview.h" #include "edit3dvisibilitytogglesmenu.h" +#include "materialutils.h" #include "metainfo.h" #include "modelnodeoperations.h" #include "nodeabstractproperty.h" @@ -387,7 +388,7 @@ void Edit3DWidget::onCreateAction() // if added node is a Model, assign it a material if (modelNode.metaInfo().isQtQuick3DModel()) - m_view->assignMaterialTo3dModel(modelNode); + MaterialUtils::assignMaterialTo3dModel(m_view, modelNode); }); } diff --git a/src/plugins/qmldesigner/components/formeditor/dragtool.cpp b/src/plugins/qmldesigner/components/formeditor/dragtool.cpp index 8d01c46d7cb..4b128c2d54b 100644 --- a/src/plugins/qmldesigner/components/formeditor/dragtool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/dragtool.cpp @@ -7,6 +7,7 @@ #include "formeditorview.h" #include "assetslibrarywidget.h" #include "assetslibrarymodel.h" +#include "materialutils.h" #include #include #include @@ -441,7 +442,7 @@ void DragTool::handleView3dDrop() const QList models = dragNode.modelNode().subModelNodesOfType( model->qtQuick3DModelMetaInfo()); QTC_ASSERT(models.size() == 1, return); - view()->assignMaterialTo3dModel(models.at(0)); + MaterialUtils::assignMaterialTo3dModel(view(), models.at(0)); } } } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp new file mode 100644 index 00000000000..76924bedbcd --- /dev/null +++ b/src/plugins/qmldesigner/components/materialbrowser/materialutils.cpp @@ -0,0 +1,71 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "materialutils.h" + +#include "abstractview.h" +#include "nodelistproperty.h" +#include "nodemetainfo.h" +#include "qmlobjectnode.h" +#include "variantproperty.h" + +#include + +namespace QmlDesigner { + +// Assigns given material to a 3D model. +// The assigned material is also inserted into material library if not already there. +// If given material is not valid, first existing material from material library is used, +// or if material library is empty, a new material is created. +// This function should be called only from inside a transaction, as it potentially does many +// changes to model. +void MaterialUtils::assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode, + const ModelNode &materialNode) +{ + QTC_ASSERT(modelNode.isValid() && modelNode.metaInfo().isQtQuick3DModel(), return); + + ModelNode matLib = view->materialLibraryNode(); + + if (!matLib.isValid()) + return; + + ModelNode newMaterialNode; + + if (materialNode.isValid() && materialNode.metaInfo().isQtQuick3DMaterial()) { + newMaterialNode = materialNode; + } else { + const QList materials = matLib.directSubModelNodes(); + if (materials.size() > 0) { + for (const ModelNode &mat : materials) { + if (mat.metaInfo().isQtQuick3DMaterial()) { + newMaterialNode = mat; + break; + } + } + } + + // if no valid material, create a new default material + if (!newMaterialNode.isValid()) { + NodeMetaInfo metaInfo = view->model()->qtQuick3DPrincipledMaterialMetaInfo(); + newMaterialNode = view->createModelNode("QtQuick3D.PrincipledMaterial", + metaInfo.majorVersion(), + metaInfo.minorVersion()); + newMaterialNode.validId(); + } + } + + QTC_ASSERT(newMaterialNode.isValid(), return); + + VariantProperty matNameProp = newMaterialNode.variantProperty("objectName"); + if (matNameProp.value().isNull()) + matNameProp.setValue("New Material"); + + if (!newMaterialNode.hasParentProperty() + || newMaterialNode.parentProperty() != matLib.defaultNodeListProperty()) { + matLib.defaultNodeListProperty().reparentHere(newMaterialNode); + } + + QmlObjectNode(modelNode).setBindingProperty("materials", newMaterialNode.id()); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialutils.h b/src/plugins/qmldesigner/components/materialbrowser/materialutils.h new file mode 100644 index 00000000000..e273ef74a44 --- /dev/null +++ b/src/plugins/qmldesigner/components/materialbrowser/materialutils.h @@ -0,0 +1,20 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#pragma once + +#include "modelnode.h" + +namespace QmlDesigner { + +class AbstractView; + +class MaterialUtils +{ +public: + MaterialUtils(); + + static void assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode, + const ModelNode &materialNode = {}); +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 0be28e3baf9..b63ddae890c 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -710,7 +711,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in newQmlObjectNode.destroy(); return; } - m_view->assignMaterialTo3dModel(targetNode, newModelNode); + MaterialUtils::assignMaterialTo3dModel(m_view, targetNode, newModelNode); } ChooseFromPropertyListDialog *dialog = ChooseFromPropertyListDialog::createIfNeeded( @@ -751,9 +752,9 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in const QList models = newModelNode.subModelNodesOfType( m_view->model()->qtQuick3DModelMetaInfo()); QTC_ASSERT(models.size() == 1, return); - m_view->assignMaterialTo3dModel(models.at(0)); + MaterialUtils::assignMaterialTo3dModel(m_view, models.at(0)); } else if (newModelNode.metaInfo().isQtQuick3DModel()) { - m_view->assignMaterialTo3dModel(newModelNode); + MaterialUtils::assignMaterialTo3dModel(m_view, newModelNode); } if (!validContainer) { @@ -836,7 +837,7 @@ void NavigatorTreeModel::handleMaterialDrop(const QMimeData *mimeData, const QMo ModelNode matNode = m_view->modelNodeForInternalId(internalId); m_view->executeInTransaction(__FUNCTION__, [&] { - m_view->assignMaterialTo3dModel(targetNode, matNode); + MaterialUtils::assignMaterialTo3dModel(m_view, targetNode, matNode); }); } diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index cdfd94757e8..ed618653ce6 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -231,7 +231,6 @@ public: ModelNode materialLibraryNode(); bool isPartOfMaterialLibrary(const ModelNode &node); ModelNode active3DSceneNode(); - void assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode = {}); ModelNode getTextureDefaultInstance(const QString &source); const NodeInstanceView *nodeInstanceView() const; diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 2bfc4c1c06f..409a290573a 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -8,7 +8,6 @@ #include "model_p.h" #include "internalnode_p.h" #include "nodeinstanceview.h" -#include "qmlobjectnode.h" #include #include #include @@ -879,60 +878,6 @@ ModelNode AbstractView::active3DSceneNode() return {}; } -// Assigns given material to a 3D model. -// The assigned material is also inserted into material library if not already there. -// If given material is not valid, first existing material from material library is used, -// or if material library is empty, a new material is created. -// This function should be called only from inside a transaction, as it potentially does many -// changes to model. -void AbstractView::assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode) -{ - QTC_ASSERT(modelNode.isValid() && modelNode.metaInfo().isQtQuick3DModel(), return ); - - ModelNode matLib = materialLibraryNode(); - - if (!matLib.isValid()) - return; - - ModelNode newMaterialNode; - - if (materialNode.isValid() && materialNode.metaInfo().isQtQuick3DMaterial()) { - newMaterialNode = materialNode; - } else { - const QList materials = matLib.directSubModelNodes(); - if (materials.size() > 0) { - for (const ModelNode &mat : materials) { - if (mat.metaInfo().isQtQuick3DMaterial()) { - newMaterialNode = mat; - break; - } - } - } - - // if no valid material, create a new default material - if (!newMaterialNode.isValid()) { - NodeMetaInfo metaInfo = model()->qtQuick3DPrincipledMaterialMetaInfo(); - newMaterialNode = createModelNode("QtQuick3D.PrincipledMaterial", - metaInfo.majorVersion(), - metaInfo.minorVersion()); - newMaterialNode.validId(); - } - } - - QTC_ASSERT(newMaterialNode.isValid(), return); - - VariantProperty matNameProp = newMaterialNode.variantProperty("objectName"); - if (matNameProp.value().isNull()) - matNameProp.setValue("New Material"); - - if (!newMaterialNode.hasParentProperty() - || newMaterialNode.parentProperty() != matLib.defaultNodeListProperty()) { - matLib.defaultNodeListProperty().reparentHere(newMaterialNode); - } - - QmlObjectNode(modelNode).setBindingProperty("materials", newMaterialNode.id()); -} - ModelNode AbstractView::getTextureDefaultInstance(const QString &source) { ModelNode matLib = materialLibraryNode();