forked from qt-creator/qt-creator
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:
@@ -36,7 +36,7 @@ class CreateTextures : public CreateTexture
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CreateTexture::CreateTexture;
|
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)
|
for (const QString &path : filePaths)
|
||||||
CreateTexture::execute(path, mode, sceneId);
|
CreateTexture::execute(path, mode, sceneId);
|
||||||
|
@@ -330,7 +330,7 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
|
|||||||
setSelectedModelNode(createdNode);
|
setSelectedModelNode(createdNode);
|
||||||
} else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) {
|
} else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) {
|
||||||
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
|
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
|
||||||
if (m_droppedModelNode.isValid() && modelNode.isValid() && isModel) {
|
if (m_droppedModelNode.isValid() && isModel) {
|
||||||
executeInTransaction(__FUNCTION__, [&] {
|
executeInTransaction(__FUNCTION__, [&] {
|
||||||
assignMaterialTo3dModel(modelNode, m_droppedModelNode);
|
assignMaterialTo3dModel(modelNode, m_droppedModelNode);
|
||||||
});
|
});
|
||||||
@@ -339,9 +339,14 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
|
|||||||
emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView
|
emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView
|
||||||
} else if (m_nodeAtPosReqType == NodeAtPosReqType::TextureDrop) {
|
} else if (m_nodeAtPosReqType == NodeAtPosReqType::TextureDrop) {
|
||||||
emitCustomNotification("apply_texture_to_model3D", {modelNode, m_droppedModelNode});
|
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_droppedModelNode = {};
|
||||||
|
m_droppedFile.clear();
|
||||||
m_nodeAtPosReqType = NodeAtPosReqType::None;
|
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
|
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
|
} // namespace QmlDesigner
|
||||||
|
@@ -64,6 +64,7 @@ public:
|
|||||||
void dropBundleMaterial(const QPointF &pos);
|
void dropBundleMaterial(const QPointF &pos);
|
||||||
void dropTexture(const ModelNode &textureNode, const QPointF &pos);
|
void dropTexture(const ModelNode &textureNode, const QPointF &pos);
|
||||||
void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos);
|
void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos);
|
||||||
|
void dropAsset(const QString &file, const QPointF &pos);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onEntriesChanged();
|
void onEntriesChanged();
|
||||||
@@ -75,6 +76,7 @@ private:
|
|||||||
MaterialDrop,
|
MaterialDrop,
|
||||||
TextureDrop,
|
TextureDrop,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
|
AssetDrop,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,6 +126,7 @@ private:
|
|||||||
ModelCache<QImage> m_canvasCache;
|
ModelCache<QImage> m_canvasCache;
|
||||||
ModelNode m_droppedModelNode;
|
ModelNode m_droppedModelNode;
|
||||||
ItemLibraryEntry m_droppedEntry;
|
ItemLibraryEntry m_droppedEntry;
|
||||||
|
QString m_droppedFile;
|
||||||
NodeAtPosReqType m_nodeAtPosReqType;
|
NodeAtPosReqType m_nodeAtPosReqType;
|
||||||
QPoint m_contextMenuPos;
|
QPoint m_contextMenuPos;
|
||||||
QTimer m_compressionTimer;
|
QTimer m_compressionTimer;
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <toolbox.h>
|
#include <toolbox.h>
|
||||||
|
#include <utils/asset.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
@@ -498,10 +499,18 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
|||||||
|
|
||||||
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
|
if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ASSETS)
|
||||||
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)
|
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) {
|
||||||
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)
|
const auto urls = dragEnterEvent->mimeData()->urls();
|
||||||
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) {
|
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();
|
dragEnterEvent->acceptProposedAction();
|
||||||
} else if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
|
} else if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
|
||||||
QByteArray data = dragEnterEvent->mimeData()->data(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;
|
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
|
// handle dropping external assets
|
||||||
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
|
@@ -21,6 +21,9 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/projecttree.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -517,7 +520,7 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
|
|||||||
});
|
});
|
||||||
} else if (identifier == "delete_selected_material") {
|
} else if (identifier == "delete_selected_material") {
|
||||||
m_widget->deleteSelectedItem();
|
m_widget->deleteSelectedItem();
|
||||||
} else if (identifier == "apply_bundle_texture_to_model3D") {
|
} else if (identifier == "apply_asset_to_model3D") {
|
||||||
m_appliedTexturePath = data.at(0).toString();
|
m_appliedTexturePath = data.at(0).toString();
|
||||||
applyTextureToModel3D(nodeList.at(0));
|
applyTextureToModel3D(nodeList.at(0));
|
||||||
} else if (identifier == "apply_texture_to_model3D") {
|
} else if (identifier == "apply_texture_to_model3D") {
|
||||||
@@ -645,7 +648,16 @@ void MaterialBrowserView::applyTextureToProperty(const QString &matId, const QSt
|
|||||||
{
|
{
|
||||||
executeInTransaction(__FUNCTION__, [&] {
|
executeInTransaction(__FUNCTION__, [&] {
|
||||||
if (m_appliedTextureId.isEmpty() && !m_appliedTexturePath.isEmpty()) {
|
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);
|
ModelNode tex = texCreator->execute(m_appliedTexturePath, AddTextureMode::Texture);
|
||||||
m_appliedTextureId = tex.id();
|
m_appliedTextureId = tex.id();
|
||||||
m_appliedTexturePath.clear();
|
m_appliedTexturePath.clear();
|
||||||
|
@@ -221,6 +221,11 @@ void NameItemDelegate::paint(QPainter *painter,
|
|||||||
bool validDrop = false;
|
bool validDrop = false;
|
||||||
if (dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) {
|
if (dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) {
|
||||||
validDrop = metaInfo.isQtQuick3DModel();
|
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 {
|
} else {
|
||||||
const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType);
|
const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType);
|
||||||
ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true);
|
ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true);
|
||||||
|
@@ -558,7 +558,7 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
QByteArray filePath = mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE);
|
QByteArray filePath = mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE);
|
||||||
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
|
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
|
||||||
if (targetNode.metaInfo().isQtQuick3DModel())
|
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)) {
|
} else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
|
||||||
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
|
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
|
||||||
if (targetNode.isValid())
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1120,6 +1123,16 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|
|||||||
// if dropping an image on an existing texture, set the source
|
// if dropping an image on an existing texture, set the source
|
||||||
targetNode.variantProperty("source").setValue(imagePath);
|
targetNode.variantProperty("source").setValue(imagePath);
|
||||||
return true;
|
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;
|
return false;
|
||||||
|
@@ -288,6 +288,12 @@ void NavigatorView::dragStarted(QMimeData *mimeData)
|
|||||||
// specific type
|
// specific type
|
||||||
m_widget->setDragType(Storage::Info::EffectMaker);
|
m_widget->setDragType(Storage::Info::EffectMaker);
|
||||||
m_widget->update();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user