diff --git a/src/plugins/qmldesigner/components/createtexture.h b/src/plugins/qmldesigner/components/createtexture.h index 6a0280ac06b..27a4c5870e4 100644 --- a/src/plugins/qmldesigner/components/createtexture.h +++ b/src/plugins/qmldesigner/components/createtexture.h @@ -36,7 +36,7 @@ class CreateTextures : public CreateTexture { public: using CreateTexture::CreateTexture; - void execute(const QStringList &filePaths, AddTextureMode mode, int sceneId) + void execute(const QStringList &filePaths, AddTextureMode mode, int sceneId = -1) { for (const QString &path : filePaths) CreateTexture::execute(path, mode, sceneId); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index c47ba93d3c7..304f8e305f9 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -330,7 +330,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos setSelectedModelNode(createdNode); } else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) { bool isModel = modelNode.metaInfo().isQtQuick3DModel(); - if (m_droppedModelNode.isValid() && modelNode.isValid() && isModel) { + if (m_droppedModelNode.isValid() && isModel) { executeInTransaction(__FUNCTION__, [&] { assignMaterialTo3dModel(modelNode, m_droppedModelNode); }); @@ -339,9 +339,14 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView } else if (m_nodeAtPosReqType == NodeAtPosReqType::TextureDrop) { emitCustomNotification("apply_texture_to_model3D", {modelNode, m_droppedModelNode}); + } else if (m_nodeAtPosReqType == NodeAtPosReqType::AssetDrop) { + bool isModel = modelNode.metaInfo().isQtQuick3DModel(); + if (!m_droppedFile.isEmpty() && isModel) + emitCustomNotification("apply_asset_to_model3D", {modelNode}, {m_droppedFile}); // To MaterialBrowserView } m_droppedModelNode = {}; + m_droppedFile.clear(); m_nodeAtPosReqType = NodeAtPosReqType::None; } @@ -926,4 +931,11 @@ void Edit3DView::dropComponent(const ItemLibraryEntry &entry, const QPointF &pos nodeAtPosReady({}, {}); // No need to actually resolve position for non-node items } +void Edit3DView::dropAsset(const QString &file, const QPointF &pos) +{ + m_nodeAtPosReqType = NodeAtPosReqType::AssetDrop; + m_droppedFile = file; + emitView3DAction(View3DActionType::GetNodeAtPos, pos); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 5d9d11953fd..b7acdccacd3 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -64,6 +64,7 @@ public: void dropBundleMaterial(const QPointF &pos); void dropTexture(const ModelNode &textureNode, const QPointF &pos); void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos); + void dropAsset(const QString &file, const QPointF &pos); private slots: void onEntriesChanged(); @@ -75,6 +76,7 @@ private: MaterialDrop, TextureDrop, ContextMenu, + AssetDrop, None }; @@ -124,6 +126,7 @@ private: ModelCache m_canvasCache; ModelNode m_droppedModelNode; ItemLibraryEntry m_droppedEntry; + QString m_droppedFile; NodeAtPosReqType m_nodeAtPosReqType; QPoint m_contextMenuPos; QTimer m_compressionTimer; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 651dcd98a90..f8eb49d1101 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -498,10 +499,18 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent) const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() ->viewManager().designerActionManager(); - if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()) - || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL) - || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL) - || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) { + if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ASSETS) + || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { + const auto urls = dragEnterEvent->mimeData()->urls(); + if (!urls.isEmpty()) { + Asset asset(urls.first().toLocalFile()); + if (asset.isTexture3D() || asset.isImage()) + dragEnterEvent->acceptProposedAction(); + } + } else if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()) + || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL) + || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL) + || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) { dragEnterEvent->acceptProposedAction(); } else if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) { QByteArray data = dragEnterEvent->mimeData()->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO); @@ -552,6 +561,14 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent) return; } + // handle dropping image assets + if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ASSETS) + || dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { + m_view->dropAsset(dropEvent->mimeData()->urls().first().toLocalFile(), pos); + m_view->model()->endDrag(); + return; + } + // handle dropping external assets const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() ->viewManager().designerActionManager(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 5066d8aefe2..3b5364b6928 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -21,6 +21,9 @@ #include #include +#include +#include + #include #include @@ -517,7 +520,7 @@ void MaterialBrowserView::customNotification(const AbstractView *view, }); } else if (identifier == "delete_selected_material") { m_widget->deleteSelectedItem(); - } else if (identifier == "apply_bundle_texture_to_model3D") { + } else if (identifier == "apply_asset_to_model3D") { m_appliedTexturePath = data.at(0).toString(); applyTextureToModel3D(nodeList.at(0)); } else if (identifier == "apply_texture_to_model3D") { @@ -645,7 +648,16 @@ void MaterialBrowserView::applyTextureToProperty(const QString &matId, const QSt { executeInTransaction(__FUNCTION__, [&] { if (m_appliedTextureId.isEmpty() && !m_appliedTexturePath.isEmpty()) { - auto texCreator = new CreateTexture(this, true); + bool import = true; + using namespace ProjectExplorer; + + if (Project *proj = ProjectTree::currentProject()) { + Utils::FilePath projDir = proj->projectFilePath().parentDir().pathAppended("content"); + if (m_appliedTexturePath.startsWith(projDir.toString())) + import = false; + } + + auto texCreator = new CreateTexture(this, import); ModelNode tex = texCreator->execute(m_appliedTexturePath, AddTextureMode::Texture); m_appliedTextureId = tex.id(); m_appliedTexturePath.clear(); diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index b60164dd30f..7578d61a0ce 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -221,6 +221,11 @@ void NameItemDelegate::paint(QPainter *painter, bool validDrop = false; if (dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) { validDrop = metaInfo.isQtQuick3DModel(); + } else if (dragType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { + validDrop = metaInfo.isQtQuick3DModel() || metaInfo.isQtQuick3DTexture(); + } else if (dragType == Constants::MIME_TYPE_ASSET_IMAGE) { + validDrop = metaInfo.isQtQuick3DModel() || metaInfo.isQtQuick3DTexture() + || metaInfo.isQtQuickImage() || metaInfo.isQtQuickBorderImage(); } else { const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType); ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 2fa06b1ead3..0be28e3baf9 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -558,7 +558,7 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, QByteArray filePath = mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE); ModelNode targetNode(modelNodeForIndex(dropModelIndex)); if (targetNode.metaInfo().isQtQuick3DModel()) - m_view->emitCustomNotification("apply_bundle_texture_to_model3D", {targetNode}, {filePath}); // To MaterialBrowserView + m_view->emitCustomNotification("apply_asset_to_model3D", {targetNode}, {filePath}); // To MaterialBrowserView } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) { ModelNode targetNode(modelNodeForIndex(dropModelIndex)); if (targetNode.isValid()) @@ -636,6 +636,9 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, } } + if (m_view && m_view->model()) + m_view->model()->endDrag(); + return true; } @@ -1120,6 +1123,16 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode, // if dropping an image on an existing texture, set the source targetNode.variantProperty("source").setValue(imagePath); return true; + } else if (targetNode.metaInfo().isQtQuick3DModel()) { + QTimer::singleShot(0, this, [this, targetNode, imagePath]() { + if (m_view && targetNode.isValid()) { + // To MaterialBrowserView. Done async to avoid custom notification in transaction + m_view->emitCustomNotification( + "apply_asset_to_model3D", {targetNode}, + {DocumentManager::currentFilePath().absolutePath().pathAppended(imagePath).cleanPath().toString()}); + } + }); + return true; } return false; diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 32f45fc6003..a2560bc267b 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -288,6 +288,12 @@ void NavigatorView::dragStarted(QMimeData *mimeData) // specific type m_widget->setDragType(Storage::Info::EffectMaker); m_widget->update(); + } else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { + m_widget->setDragType(Constants::MIME_TYPE_ASSET_TEXTURE3D); + m_widget->update(); + } else if (assetType == Constants::MIME_TYPE_ASSET_IMAGE) { + m_widget->setDragType(Constants::MIME_TYPE_ASSET_IMAGE); + m_widget->update(); } } }