QmlDesigner: Create dragged item to correct position in 3d view

Fixes: QDS-8655
Change-Id: I8ab397e4dc571e50c4495f6690418b177afa4dbe
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2023-01-05 13:08:27 +02:00
parent c1a16d51a6
commit ff59de94e9
6 changed files with 49 additions and 45 deletions

View File

@@ -5,9 +5,6 @@
#include "edit3dview.h"
#include "edit3dwidget.h"
#include "nodehints.h"
#include "qmlvisualnode.h"
#include <bindingproperty.h>
#include <nodemetainfo.h>
#include <nodelistproperty.h>
@@ -143,41 +140,6 @@ void Edit3DCanvas::resizeEvent(QResizeEvent *e)
m_parent->view()->edit3DViewResized(e->size());
}
void Edit3DCanvas::dragEnterEvent(QDragEnterEvent *e)
{
// Block all drags if scene root node is locked
ModelNode node;
if (m_parent->view()->hasModelNodeForInternalId(m_activeScene))
node = m_parent->view()->modelNodeForInternalId(m_activeScene);
// Allow drop when there is no valid active scene, as the drop goes under the root node of
// the document in that case.
if (!ModelNode::isThisOrAncestorLocked(node)) {
QByteArray data = e->mimeData()->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO);
if (!data.isEmpty()) {
QDataStream stream(data);
stream >> m_itemLibraryEntry;
if (NodeHints::fromItemLibraryEntry(m_itemLibraryEntry).canBeDroppedInView3D())
e->accept();
}
}
}
void Edit3DCanvas::dropEvent(QDropEvent *e)
{
m_parent->view()->executeInTransaction(__FUNCTION__, [&] {
auto modelNode = QmlVisualNode::createQml3DNode(m_parent->view(), m_itemLibraryEntry, m_activeScene).modelNode();
QTC_ASSERT(modelNode.isValid(), return);
e->accept();
m_parent->view()->setSelectedModelNode(modelNode);
// if added node is a Model, assign it a material
if (modelNode.metaInfo().isQtQuick3DModel())
m_parent->view()->assignMaterialTo3dModel(modelNode);
});
}
void Edit3DCanvas::focusOutEvent(QFocusEvent *focusEvent)
{
QmlDesignerPlugin::emitUsageStatisticsTime(Constants::EVENT_3DEDITOR_TIME,

View File

@@ -2,8 +2,6 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include "itemlibraryinfo.h"
#include <QtWidgets/qwidget.h>
#include <QtGui/qimage.h>
#include <QtGui/qevent.h>
@@ -38,8 +36,6 @@ protected:
void keyReleaseEvent(QKeyEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void dragEnterEvent(QDragEnterEvent *e) override;
void dropEvent(QDropEvent *e) override;
void focusOutEvent(QFocusEvent *focusEvent) override;
void focusInEvent(QFocusEvent *focusEvent) override;
@@ -49,7 +45,6 @@ private:
QPointer<Edit3DWidget> m_parent;
QImage m_image;
qint32 m_activeScene = -1;
ItemLibraryEntry m_itemLibraryEntry;
QElapsedTimer m_usageTimer;
qreal m_opacity = 1.0;
QWidget *m_busyIndicator = nullptr;

View File

@@ -16,6 +16,7 @@
#include "qmldesignerconstants.h"
#include "qmldesignericons.h"
#include "qmldesignerplugin.h"
#include "qmlvisualnode.h"
#include "seekerslider.h"
#include <coreplugin/icore.h>
@@ -304,6 +305,16 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
if (modelNode.isValid() && !modelNode.isSelected())
setSelectedModelNode(modelNode);
m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode, pos3d);
} else if (m_nodeAtPosReqType == NodeAtPosReqType::ComponentDrop) {
ModelNode createdNode;
executeInTransaction(__FUNCTION__, [&] {
createdNode = QmlVisualNode::createQml3DNode(
this, m_droppedEntry, edit3DWidget()->canvas()->activeScene(), pos3d).modelNode();
if (createdNode.metaInfo().isQtQuick3DModel())
assignMaterialTo3dModel(createdNode);
});
if (createdNode.isValid())
setSelectedModelNode(createdNode);
} else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) {
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
if (m_droppedModelNode.isValid() && modelNode.isValid() && isModel) {
@@ -895,4 +906,11 @@ void Edit3DView::dropTexture(const ModelNode &textureNode, const QPointF &pos)
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
}
void Edit3DView::dropComponent(const ItemLibraryEntry &entry, const QPointF &pos)
{
m_nodeAtPosReqType = NodeAtPosReqType::ComponentDrop;
m_droppedEntry = entry;
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
}
} // namespace QmlDesigner

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include "itemlibraryinfo.h"
#include <qmldesignercomponents_global.h>
#include <abstractview.h>
@@ -65,6 +66,7 @@ public:
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
void dropBundleMaterial(const QPointF &pos);
void dropTexture(const ModelNode &textureNode, const QPointF &pos);
void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos);
private slots:
void onEntriesChanged();
@@ -72,6 +74,7 @@ private slots:
private:
enum class NodeAtPosReqType {
BundleMaterialDrop,
ComponentDrop,
MaterialDrop,
TextureDrop,
ContextMenu,
@@ -122,6 +125,7 @@ private:
int particlemode;
ModelCache<QImage> m_canvasCache;
ModelNode m_droppedModelNode;
ItemLibraryEntry m_droppedEntry;
NodeAtPosReqType m_nodeAtPosReqType;
QPoint m_contextMenuPos;
QTimer m_compressionTimer;

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "edit3dwidget.h"
#include "designdocumentview.h"
#include "designdocument.h"
#include "edit3dactions.h"
#include "edit3dcanvas.h"
#include "edit3dview.h"
@@ -10,10 +10,10 @@
#include "metainfo.h"
#include "modelnodeoperations.h"
#include "nodeabstractproperty.h"
#include "nodehints.h"
#include "qmldesignerconstants.h"
#include "qmldesignerplugin.h"
#include "qmlvisualnode.h"
#include "timelineactions.h"
#include "viewmanager.h"
#include <auxiliarydataproperties.h>
@@ -407,6 +407,15 @@ Edit3DView *Edit3DWidget::view() const
void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
{
// Block all drags if scene root node is locked
if (m_view->hasModelNodeForInternalId(m_canvas->activeScene())) {
ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene());
if (ModelNode::isThisOrAncestorLocked(node))
return;
}
m_draggedEntry = {};
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
->viewManager().designerActionManager();
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
@@ -414,6 +423,14 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|| 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);
if (!data.isEmpty()) {
QDataStream stream(data);
stream >> m_draggedEntry;
if (NodeHints::fromItemLibraryEntry(m_draggedEntry).canBeDroppedInView3D())
dragEnterEvent->acceptProposedAction();
}
}
}
@@ -443,6 +460,13 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
return;
}
// handle dropping from component view
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
if (!m_draggedEntry.name().isEmpty())
m_view->dropComponent(m_draggedEntry, pos);
return;
}
// handle dropping external assets
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
->viewManager().designerActionManager();

View File

@@ -77,6 +77,7 @@ private:
ModelNode m_contextMenuTarget;
QVector3D m_contextMenuPos3d;
QHash<QString, ItemLibraryEntry> m_nameToEntry;
ItemLibraryEntry m_draggedEntry;
};
} // namespace QmlDesigner