forked from qt-creator/qt-creator
QmlDesigner: Links that add QtQuick3D import now also add default View3D
Links in 3D view and Content Library that add QtQuick3D import now also add a View3D with extended scene environment, if View3D doesn't already exist in the scene. Fixes: QDS-14821 Change-Id: I9df6fd832e8bd0721ae2a451e7d2f3613af884fb Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Ali Kianian <ali.kianian@qt.io>
This commit is contained in:
@@ -477,7 +477,6 @@ extend_qtc_plugin(QmlDesigner
|
||||
materialbrowserwidget.cpp materialbrowserwidget.h
|
||||
materialbrowsermodel.cpp materialbrowsermodel.h
|
||||
materialbrowsertexturesmodel.cpp materialbrowsertexturesmodel.h
|
||||
materialutils.cpp materialutils.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
|
@@ -18,7 +18,6 @@
|
||||
#include <designmodewidget.h>
|
||||
#include <documentmanager.h>
|
||||
#include <itemlibraryentry.h>
|
||||
#include <materialutils.h>
|
||||
#include <modelnode.h>
|
||||
#include <modelnodeutils.h>
|
||||
#include <nodehints.h>
|
||||
@@ -2093,7 +2092,7 @@ void handleMaterialDrop(const QMimeData *mimeData, const ModelNode &targetNode)
|
||||
ModelNode matNode = view->modelNodeForInternalId(internalId);
|
||||
|
||||
view->executeInTransaction(__FUNCTION__, [&] {
|
||||
MaterialUtils::assignMaterialTo3dModel(view, targetNode, matNode);
|
||||
Utils3D::assignMaterialTo3dModel(view, targetNode, matNode);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -3,14 +3,20 @@
|
||||
|
||||
#include "utils3d.h"
|
||||
|
||||
#include <itemlibraryentry.h>
|
||||
#include <modelutils.h>
|
||||
#include <nodeabstractproperty.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <nodemetainfo.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmldesignertr.h>
|
||||
#include <qmlitemnode.h>
|
||||
#include <qmlobjectnode.h>
|
||||
#include <variantproperty.h>
|
||||
|
||||
#include <coreplugin/messagebox.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QRegularExpression>
|
||||
@@ -342,5 +348,111 @@ ModelNode createMaterial(AbstractView *view, const NodeMetaInfo &metaInfo)
|
||||
}
|
||||
#endif
|
||||
|
||||
void addQuick3DImportAndView3D(AbstractView *view)
|
||||
{
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (!view || !view->model() || !document || document->inFileComponentModelActive()) {
|
||||
Core::AsynchronousMessageBox::warning(Tr::tr("Failed to Add Import"),
|
||||
Tr::tr("Could not add QtQuick3D import to the document."));
|
||||
return;
|
||||
}
|
||||
|
||||
QString importName{"QtQuick3D"};
|
||||
if (view->model()->hasImport(importName))
|
||||
return;
|
||||
|
||||
view->executeInTransaction(__FUNCTION__, [&] {
|
||||
Import import = Import::createLibraryImport(importName);
|
||||
view->model()->changeImports({import}, {});
|
||||
|
||||
if (!view->rootModelNode().metaInfo().isQtQuickItem())
|
||||
return;
|
||||
|
||||
ensureMaterialLibraryNode(view);
|
||||
#ifndef QDS_USE_PROJECTSTORAGE
|
||||
});
|
||||
view->executeInTransaction(__FUNCTION__, [&] {
|
||||
#endif
|
||||
NodeMetaInfo view3dInfo = view->model()->qtQuick3DView3DMetaInfo();
|
||||
if (!view->allModelNodesOfType(view3dInfo).isEmpty())
|
||||
return;
|
||||
|
||||
const QList<ItemLibraryEntry> entries = view->model()->itemLibraryEntries();
|
||||
// Use template file to identify correct entry, as name could be localized in the future
|
||||
const QString view3dSource{"extendedview3D_template.qml"};
|
||||
auto templateMatch = [&view3dSource](const ItemLibraryEntry &entry) -> bool {
|
||||
return entry.templatePath().endsWith(view3dSource);
|
||||
};
|
||||
auto iter = std::ranges::find_if(entries, templateMatch);
|
||||
if (iter == entries.end())
|
||||
return;
|
||||
|
||||
NodeAbstractProperty targetProp = view->rootModelNode().defaultNodeAbstractProperty();
|
||||
QmlObjectNode newQmlObjectNode = QmlItemNode::createQmlObjectNode(
|
||||
view, *iter, QPointF(), targetProp, false);
|
||||
|
||||
const QList<ModelNode> models = newQmlObjectNode.modelNode().subModelNodesOfType(
|
||||
view->model()->qtQuick3DModelMetaInfo());
|
||||
if (!models.isEmpty())
|
||||
assignMaterialTo3dModel(view, models.at(0));
|
||||
});
|
||||
}
|
||||
|
||||
// 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 assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode,
|
||||
const ModelNode &materialNode)
|
||||
{
|
||||
QTC_ASSERT(modelNode.metaInfo().isQtQuick3DModel(), return);
|
||||
|
||||
ModelNode matLib = Utils3D::materialLibraryNode(view);
|
||||
|
||||
if (!matLib)
|
||||
return;
|
||||
|
||||
ModelNode newMaterialNode;
|
||||
|
||||
if (materialNode.metaInfo().isQtQuick3DMaterial()) {
|
||||
newMaterialNode = materialNode;
|
||||
} else {
|
||||
const QList<ModelNode> materials = matLib.directSubModelNodes();
|
||||
auto isMaterial = [](const ModelNode &node) -> bool {
|
||||
return node.metaInfo().isQtQuick3DMaterial();
|
||||
};
|
||||
if (auto iter = std::ranges::find_if(materials, isMaterial); iter != materials.end())
|
||||
newMaterialNode = *iter;
|
||||
|
||||
// if no valid material, create a new default material
|
||||
if (!newMaterialNode) {
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
newMaterialNode = view->createModelNode("PrincipledMaterial");
|
||||
#else
|
||||
NodeMetaInfo metaInfo = view->model()->qtQuick3DPrincipledMaterialMetaInfo();
|
||||
newMaterialNode = view->createModelNode("QtQuick3D.PrincipledMaterial",
|
||||
metaInfo.majorVersion(),
|
||||
metaInfo.minorVersion());
|
||||
#endif
|
||||
newMaterialNode.ensureIdExists();
|
||||
}
|
||||
}
|
||||
|
||||
QTC_ASSERT(newMaterialNode, 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 Utils3D
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -54,5 +54,10 @@ ModelNode createMaterial(AbstractView *view, const TypeName &typeName);
|
||||
ModelNode createMaterial(AbstractView *view, const NodeMetaInfo &metaInfo);
|
||||
#endif
|
||||
|
||||
void addQuick3DImportAndView3D(AbstractView *view);
|
||||
void assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode,
|
||||
const ModelNode &materialNode = {});
|
||||
|
||||
|
||||
} // namespace Utils3D
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -35,8 +35,6 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <coreplugin/messagebox.h>
|
||||
|
||||
#ifndef QMLDESIGNER_TEST
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
@@ -77,23 +75,7 @@ WidgetInfo ContentLibraryView::widgetInfo()
|
||||
m_bundleHelper = std::make_unique<BundleHelper>(this, m_widget);
|
||||
|
||||
connect(m_widget, &ContentLibraryWidget::importQtQuick3D, this, [&] {
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (document && !document->inFileComponentModelActive() && model()) {
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
Import import = Import::createLibraryImport("QtQuick3D");
|
||||
model()->changeImports({import}, {});
|
||||
return;
|
||||
#else
|
||||
if (ModelUtils::addImportWithCheck(
|
||||
"QtQuick3D",
|
||||
[](const Import &import) { return !import.hasVersion() || import.majorVersion() >= 6; },
|
||||
model())) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
||||
tr("Could not add QtQuick3D import to project."));
|
||||
Utils3D::addQuick3DImportAndView3D(this);
|
||||
});
|
||||
connect(m_widget, &ContentLibraryWidget::bundleMaterialDragStarted, this,
|
||||
[&] (QmlDesigner::ContentLibraryMaterial *mat) {
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#include <designericons.h>
|
||||
#include <designersettings.h>
|
||||
#include <designmodewidget.h>
|
||||
#include <materialutils.h>
|
||||
#include <metainfo.h>
|
||||
#include <modelutils.h>
|
||||
#include <nodeabstractproperty.h>
|
||||
@@ -33,7 +32,6 @@
|
||||
#include <variantproperty.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
|
||||
#include <qmldesignerutils/asset.h>
|
||||
|
||||
@@ -481,7 +479,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())
|
||||
MaterialUtils::assignMaterialTo3dModel(this, createdNode);
|
||||
Utils3D::assignMaterialTo3dModel(this, createdNode);
|
||||
});
|
||||
if (createdNode.isValid())
|
||||
setSelectedModelNode(createdNode);
|
||||
@@ -489,7 +487,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
|
||||
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
|
||||
if (m_droppedModelNode.isValid() && isModel) {
|
||||
executeInTransaction(__FUNCTION__, [&] {
|
||||
MaterialUtils::assignMaterialTo3dModel(this, modelNode, m_droppedModelNode);
|
||||
Utils3D::assignMaterialTo3dModel(this, modelNode, m_droppedModelNode);
|
||||
});
|
||||
}
|
||||
} else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) {
|
||||
@@ -1400,27 +1398,6 @@ Edit3DBakeLightsAction *Edit3DView::bakeLightsAction() const
|
||||
return m_bakeLightsAction.get();
|
||||
}
|
||||
|
||||
void Edit3DView::addQuick3DImport()
|
||||
{
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (document && !document->inFileComponentModelActive() && model()) {
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
Import import = Import::createLibraryImport("QtQuick3D");
|
||||
model()->changeImports({import}, {});
|
||||
return;
|
||||
#else
|
||||
if (ModelUtils::addImportWithCheck(
|
||||
"QtQuick3D",
|
||||
[](const Import &import) { return !import.hasVersion() || import.majorVersion() >= 6; },
|
||||
model())) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
||||
tr("Could not add QtQuick3D import to project."));
|
||||
}
|
||||
|
||||
// This method is called upon right-clicking the view to prepare for context-menu creation. The actual
|
||||
// context menu is created when nodeAtPosReady() is received from puppet
|
||||
void Edit3DView::startContextMenu(const QPoint &pos)
|
||||
|
@@ -93,7 +93,6 @@ public:
|
||||
Edit3DAction *edit3DAction(View3DActionType type) const;
|
||||
Edit3DBakeLightsAction *bakeLightsAction() const;
|
||||
|
||||
void addQuick3DImport();
|
||||
void startContextMenu(const QPoint &pos);
|
||||
void showContextMenu();
|
||||
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#include <designmodewidget.h>
|
||||
#include <externaldependenciesinterface.h>
|
||||
#include <generatedcomponentutils.h>
|
||||
#include <materialutils.h>
|
||||
#include <metainfo.h>
|
||||
#include <nodeabstractproperty.h>
|
||||
#include <nodehints.h>
|
||||
@@ -566,7 +565,7 @@ void Edit3DWidget::onCreateAction(QAction *action)
|
||||
|
||||
// if added node is a Model, assign it a material
|
||||
if (modelNode.metaInfo().isQtQuick3DModel())
|
||||
MaterialUtils::assignMaterialTo3dModel(m_view, modelNode);
|
||||
Utils3D::assignMaterialTo3dModel(m_view, modelNode);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -732,8 +731,7 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode
|
||||
|
||||
void Edit3DWidget::linkActivated([[maybe_unused]] const QString &link)
|
||||
{
|
||||
if (m_view)
|
||||
m_view->addQuick3DImport();
|
||||
Utils3D::addQuick3DImportAndView3D(m_view);
|
||||
}
|
||||
|
||||
Edit3DCanvas *Edit3DWidget::canvas() const
|
||||
|
@@ -7,13 +7,13 @@
|
||||
#include "assetslibrarywidget.h"
|
||||
#include "formeditorscene.h"
|
||||
#include "formeditorview.h"
|
||||
#include "materialutils.h"
|
||||
#include "qmldesignerconstants.h"
|
||||
#include <designeractionmanager.h>
|
||||
#include <itemlibraryentry.h>
|
||||
#include <modelnodeoperations.h>
|
||||
#include <nodehints.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <utils3d.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -455,7 +455,7 @@ void DragTool::handleView3dDrop()
|
||||
const QList<ModelNode> models = dragNode.modelNode().subModelNodesOfType(
|
||||
model->qtQuick3DModelMetaInfo());
|
||||
QTC_ASSERT(models.size() == 1, return);
|
||||
MaterialUtils::assignMaterialTo3dModel(view(), models.at(0));
|
||||
Utils3D::assignMaterialTo3dModel(view(), models.at(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,76 +0,0 @@
|
||||
// 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 <utils3d.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
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 = Utils3D::materialLibraryNode(view);
|
||||
|
||||
if (!matLib.isValid())
|
||||
return;
|
||||
|
||||
ModelNode newMaterialNode;
|
||||
|
||||
if (materialNode.isValid() && materialNode.metaInfo().isQtQuick3DMaterial()) {
|
||||
newMaterialNode = materialNode;
|
||||
} else {
|
||||
const QList<ModelNode> 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()) {
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
newMaterialNode = view->createModelNode("PrincipledMaterial");
|
||||
#else
|
||||
NodeMetaInfo metaInfo = view->model()->qtQuick3DPrincipledMaterialMetaInfo();
|
||||
newMaterialNode = view->createModelNode("QtQuick3D.PrincipledMaterial",
|
||||
metaInfo.majorVersion(),
|
||||
metaInfo.minorVersion());
|
||||
#endif
|
||||
newMaterialNode.ensureIdExists();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
@@ -1,20 +0,0 @@
|
||||
// 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
|
@@ -20,7 +20,6 @@
|
||||
#include <designmodewidget.h>
|
||||
#include <import.h>
|
||||
#include <itemlibraryentry.h>
|
||||
#include <materialutils.h>
|
||||
#include <modelutils.h>
|
||||
#include <nodeabstractproperty.h>
|
||||
#include <nodehints.h>
|
||||
@@ -773,7 +772,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
newQmlObjectNode.destroy();
|
||||
return;
|
||||
}
|
||||
MaterialUtils::assignMaterialTo3dModel(m_view, targetNode, newModelNode);
|
||||
Utils3D::assignMaterialTo3dModel(m_view, targetNode, newModelNode);
|
||||
} else {
|
||||
ChooseFromPropertyListDialog *dialog = ChooseFromPropertyListDialog::createIfNeeded(
|
||||
targetNode, newModelNode, Core::ICore::dialogParent());
|
||||
@@ -814,9 +813,9 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
const QList<ModelNode> models = newModelNode.subModelNodesOfType(
|
||||
m_view->model()->qtQuick3DModelMetaInfo());
|
||||
QTC_ASSERT(models.size() == 1, return);
|
||||
MaterialUtils::assignMaterialTo3dModel(m_view, models.at(0));
|
||||
Utils3D::assignMaterialTo3dModel(m_view, models.at(0));
|
||||
} else if (newModelNode.metaInfo().isQtQuick3DModel()) {
|
||||
MaterialUtils::assignMaterialTo3dModel(m_view, newModelNode);
|
||||
Utils3D::assignMaterialTo3dModel(m_view, newModelNode);
|
||||
}
|
||||
|
||||
if (!validContainer) {
|
||||
|
Reference in New Issue
Block a user