diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index b7dd9d10820..2bb6b5aded8 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -551,20 +551,46 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i NodeAbstractProperty targetProperty; bool foundTarget = findTargetProperty(rowModelIndex, this, &targetProperty, &targetRowNumber); - if (foundTarget) { - const QString imageFileName = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource")); - const QmlItemNode newQmlItemNode = QmlItemNode::createQmlItemNodeFromImage(m_view, imageFileName, QPointF(), targetProperty); + ModelNode targetNode(modelNodeForIndex(rowModelIndex)); - if (newQmlItemNode.isValid()) { - QList newModelNodeList; - newModelNodeList.append(newQmlItemNode); + const QString imageSource = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource")); // absolute path + const QString imageFileName = imageSource.mid(imageSource.lastIndexOf('/') + 1); + ModelNode newModelNode; - moveNodesInteractive(targetProperty, newModelNodeList, targetRowNumber); + if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial")) { + // if dropping an image on a default material, create a texture instead of image + m_view->executeInTransaction("QmlItemNode::createQmlItemNode", [&] { + // create a texture item lib + ItemLibraryEntry itemLibraryEntry; + itemLibraryEntry.setName("Texture"); + itemLibraryEntry.setType("QtQuick3D.Texture", 1, 0); + + // set texture source + PropertyName prop = "source"; + QString type = "QUrl"; + QVariant val = imageFileName; + itemLibraryEntry.addProperty(prop, type, val); + + // create a texture + newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {}, targetProperty, false); + + // set the texture to parent material's diffuseMap property + // TODO: allow the user to choose which map property to set the texture for + targetNode.bindingProperty("diffuseMap").setExpression(newModelNode.validId()); + }); + } else if (targetNode.isSubclassOf("QtQuick3D.Texture")) { + // if dropping an image on a texture, set the texture source + targetNode.variantProperty("source").setValue(imageFileName); + } else { + // create an image + newModelNode = QmlItemNode::createQmlItemNodeFromImage(m_view, imageSource , QPointF(), targetProperty); } - if (newQmlItemNode.isValid()) - m_view->selectModelNode(newQmlItemNode.modelNode()); + if (newModelNode.isValid()) { + moveNodesInteractive(targetProperty, {newModelNode}, targetRowNumber); + m_view->setSelectedModelNode(newModelNode); + } } } diff --git a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h index 65f3e96aa08..aae262686ae 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h @@ -94,13 +94,11 @@ public: const Position &position, QmlVisualNode parentQmlItemNode); - - - static QmlObjectNode createQmlObjectNode(AbstractView *view, const ItemLibraryEntry &itemLibraryEntry, const Position &position, - NodeAbstractProperty parentproperty); + NodeAbstractProperty parentProperty, + bool createInTransaction = true); static QmlVisualNode createQml3DNode(AbstractView *view, const ItemLibraryEntry &itemLibraryEntry, diff --git a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp index fe2e2fd49e8..ab9acc25e8c 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp @@ -243,11 +243,12 @@ static QmlObjectNode createQmlObjectNodeFromSource(AbstractView *view, QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view, const ItemLibraryEntry &itemLibraryEntry, const Position &position, - NodeAbstractProperty parentproperty) + NodeAbstractProperty parentProperty, + bool createInTransaction) { QmlObjectNode newQmlObjectNode; - view->executeInTransaction("QmlItemNode::createQmlItemNode", [=, &newQmlObjectNode, &parentproperty](){ + auto createNodeFunc = [=, &newQmlObjectNode, &parentProperty]() { NodeMetaInfo metaInfo = view->model()->metaInfo(itemLibraryEntry.typeName()); int minorVersion = metaInfo.minorVersion(); @@ -274,8 +275,8 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view, newQmlObjectNode = createQmlObjectNodeFromSource(view, itemLibraryEntry.qmlSource(), position); } - if (parentproperty.isValid()) - parentproperty.reparentHere(newQmlObjectNode); + if (parentProperty.isValid()) + parentProperty.reparentHere(newQmlObjectNode); if (!newQmlObjectNode.isValid()) return; @@ -289,7 +290,12 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view, newQmlObjectNode.modelNode().variantProperty(propertyBindingEntry.first).setEnumeration(propertyBindingEntry.second.toUtf8()); Q_ASSERT(newQmlObjectNode.isValid()); - }); + }; + + if (createInTransaction) + view->executeInTransaction("QmlItemNode::createQmlItemNode", createNodeFunc); + else + createNodeFunc(); Q_ASSERT(newQmlObjectNode.isValid());