QmlDesigner: Allow drag from assets to 3D model in navigator and 3D view

Fixes: QDS-8784
Fixes: QDS-8785
Change-Id: Ib33fe615137c3c29d9071cab01ba26f6b4f751af
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2023-02-28 12:25:09 +02:00
parent 8aa9fae33a
commit 47cabc308e
8 changed files with 77 additions and 9 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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<QImage> m_canvasCache;
ModelNode m_droppedModelNode;
ItemLibraryEntry m_droppedEntry;
QString m_droppedFile;
NodeAtPosReqType m_nodeAtPosReqType;
QPoint m_contextMenuPos;
QTimer m_compressionTimer;

View File

@@ -28,6 +28,7 @@
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/icore.h>
#include <toolbox.h>
#include <utils/asset.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
@@ -498,7 +499,15 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
->viewManager().designerActionManager();
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
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)) {
@@ -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();

View File

@@ -21,6 +21,9 @@
#include <coreplugin/icore.h>
#include <coreplugin/messagebox.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}
}
}