QmlDesigner: Ensure material lib node exists on project launch

In this commit material library node is created on model attach.
A timer keeps monitoring until it is suitable to create the node.

This will properly move materials into material library for
projects created with previous QDS versions.

Also removed unnecessary handling on new material dragging, as
rewriter now works properly with material library creation.

Fixes: QDS-7178
Change-Id: Idf6f41906e02bc064961d8de9841ba1644bd3552
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Mahmoud Badri
2022-06-22 14:46:27 +03:00
committed by Miikka Heikkinen
parent 9caa28754c
commit cc1bf95dc2
4 changed files with 33 additions and 31 deletions

View File

@@ -74,8 +74,11 @@ MaterialEditorView::MaterialEditorView(QWidget *parent)
connect(m_updateShortcut, &QShortcut::activated, this, &MaterialEditorView::reloadQml);
m_ensureMatLibTimer.callOnTimeout([this] {
if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation()) {
materialLibraryNode(); // create the material library node
if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation()
&& model()->rewriterView()->errors().isEmpty()) {
executeInTransaction("MaterialEditorView::MaterialEditorView", [this] {
ensureMaterialLibraryNode();
});
m_ensureMatLibTimer.stop();
}
});

View File

@@ -697,17 +697,6 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
newQmlObjectNode.destroy();
return;
}
// We can't have material initially parented if material library is created in this
// same transaction (rewriter will not allow it for some reason)
ModelNode matLib = m_view->modelNodeForId(Constants::MATERIAL_LIB_ID);
if (!matLib.isValid()) {
newQmlObjectNode.destroy();
newQmlObjectNode = QmlItemNode::createQmlObjectNode(
m_view, itemLibraryEntry, QPointF(), NodeAbstractProperty(), false);
newModelNode = newQmlObjectNode.modelNode();
if (!newModelNode.isValid())
return;
}
m_view->assignMaterialTo3dModel(targetNode, newModelNode);
}

View File

@@ -259,6 +259,7 @@ public:
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
void ensureMaterialLibraryNode();
ModelNode materialLibraryNode();
void assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode = {});

View File

@@ -809,16 +809,14 @@ void AbstractView::changeRootNodeType(const TypeName &type, int majorVersion, in
m_model.data()->d->changeRootNodeType(type, majorVersion, minorVersion);
}
// Returns ModelNode for project's material library.
// If the material library doesn't exist yet, it is created and all existing materials are moved
// under material library.
// This function should be called only form inside a transaction, as it potentially does many
// changes to model.
ModelNode AbstractView::materialLibraryNode()
// Creates material library if it doesn't exist and moves any existing materials into it
// This function should be called only from inside a transaction, as it potentially does many
// changes to model, or undo stack should be cleared after the call.
void AbstractView::ensureMaterialLibraryNode()
{
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
if (matLib.isValid())
return matLib;
return;
// Create material library node
TypeName nodeType = rootModelNode().isSubclassOf("QtQuick3D.Node") ? "QtQuick3D.Node"
@@ -830,20 +828,28 @@ ModelNode AbstractView::materialLibraryNode()
rootModelNode().defaultNodeListProperty().reparentHere(matLib);
const QList<ModelNode> materials = rootModelNode().subModelNodesOfType("QtQuick3D.Material");
if (materials.isEmpty())
return matLib;
if (!materials.isEmpty()) {
// Move all materials to under material library node
for (const ModelNode &node : materials) {
// If material has no name, set name to id
QString matName = node.variantProperty("objectName").value().toString();
if (matName.isEmpty()) {
VariantProperty objNameProp = node.variantProperty("objectName");
objNameProp.setValue(node.id());
}
// Move all materials to under material library node
for (const ModelNode &node : materials) {
// If material has no name, set name to id
QString matName = node.variantProperty("objectName").value().toString();
if (matName.isEmpty()) {
VariantProperty objNameProp = node.variantProperty("objectName");
objNameProp.setValue(node.id());
matLib.defaultNodeListProperty().reparentHere(node);
}
matLib.defaultNodeListProperty().reparentHere(node);
}
}
// Returns ModelNode for project's material library.
ModelNode AbstractView::materialLibraryNode()
{
ensureMaterialLibraryNode();
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
QTC_ASSERT(matLib.isValid(), return {});
return matLib;
}
@@ -859,6 +865,9 @@ void AbstractView::assignMaterialTo3dModel(const ModelNode &modelNode, const Mod
QTC_ASSERT(modelNode.isValid() && modelNode.isSubclassOf("QtQuick3D.Model"), return);
ModelNode matLib = materialLibraryNode();
QTC_ASSERT(matLib.isValid(), return);
ModelNode newMaterialNode;
if (materialNode.isValid() && materialNode.isSubclassOf("QtQuick3D.Material")) {