diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2024-04-23 11:39:53 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2024-04-23 13:16:53 +0000 |
commit | 651d7f5d8504fa6d0311fb23dd172ade34d44da2 (patch) | |
tree | 9d847f453a084c3695730b42c997386c268d1373 /src/plugins | |
parent | 7dfa7469207f899e347dc6f2bf0c3011140a9b23 (diff) |
QmlDesigner: Select correct underlying View3D for "Edit in 3D View"
If the selected node is not View3D, check if the topmost item in
scenePosition is View3D and target that instead for "Edit in 3D View"
action.
Fixes: QDS-12347
Change-Id: I06b59f55246e828cced8dd3c15ee9b297e5edeb7
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Diffstat (limited to 'src/plugins')
5 files changed, 58 insertions, 14 deletions
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 4e32237ee9..8d2b2c43c2 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -61,11 +61,6 @@ inline static QString captionForModelNode(const ModelNode &modelNode) return modelNode.id(); } -inline static bool contains(const QmlItemNode &node, const QPointF &position) -{ - return node.isValid() && node.instanceSceneTransform().mapRect(node.instanceBoundingRect()).contains(position); -} - DesignerActionManagerView *DesignerActionManager::view() { return m_designerActionManagerView; @@ -438,8 +433,8 @@ public: } for (const ModelNode &node : selectionContext().view()->allModelNodes()) { if (node != selectionContext().currentSingleSelectedNode() && node != parentNode - && contains(node, selectionContext().scenePosition()) && !node.isRootNode() - && !ModelUtils::isThisOrAncestorLocked(node)) { + && SelectionContextHelpers::contains(node, selectionContext().scenePosition()) + && !node.isRootNode() && !ModelUtils::isThisOrAncestorLocked(node)) { selectionContext().setTargetNode(node); QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node)); ActionTemplate *selectionAction = new ActionTemplate("SELECT", what, &ModelNodeOperations::select); @@ -1971,7 +1966,7 @@ void DesignerActionManager::createDefaultDesignerActions() QKeySequence(), Priorities::ComponentActions + 1, &editIn3dView, - &singleSelectionView3D, + &SelectionContextFunctors::always, // If action is visible, it is usable &singleSelectionView3D)); addDesignerAction(new ModelNodeContextMenuAction( diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h index eb4915b1d0..aec14e9d04 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h @@ -25,6 +25,16 @@ namespace QmlDesigner { using SelectionContextPredicate = std::function<bool (const SelectionContext&)>; using SelectionContextOperation = std::function<void (const SelectionContext&)>; +namespace SelectionContextHelpers { + +inline bool contains(const QmlItemNode &node, const QPointF &position) +{ + return node.isValid() + && node.instanceSceneTransform().mapRect(node.instanceBoundingRect()).contains(position); +} + +} // namespace SelectionContextHelpers + namespace SelectionContextFunctors { inline bool always(const SelectionContext &) @@ -99,8 +109,22 @@ inline bool singleSelectionNotRoot(const SelectionContext &selectionState) inline bool singleSelectionView3D(const SelectionContext &selectionState) { - return selectionState.singleNodeIsSelected() - && selectionState.currentSingleSelectedNode().metaInfo().isQtQuick3DView3D(); + if (selectionState.singleNodeIsSelected() + && selectionState.currentSingleSelectedNode().metaInfo().isQtQuick3DView3D()) { + return true; + } + + // If currently selected node is not View3D, check if there is a View3D under the cursor. + if (!selectionState.scenePosition().isNull()) { + // Assumption is that last match in allModelNodes() list is the topmost one. + const QList<ModelNode> allNodes = selectionState.view()->allModelNodes(); + for (int i = allNodes.size() - 1; i >= 0; --i) { + if (SelectionContextHelpers::contains(allNodes[i], selectionState.scenePosition())) + return allNodes[i].metaInfo().isQtQuick3DView3D(); + } + } + + return false; } inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index a5274c70e2..c24ec9aa3e 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1685,16 +1685,37 @@ void updateImported3DAsset(const SelectionContext &selectionContext) void editIn3dView(const SelectionContext &selectionContext) { - if (selectionContext.view() && selectionContext.hasSingleSelectedModelNode() + if (!selectionContext.view()) + return; + + ModelNode targetNode; + + if (selectionContext.hasSingleSelectedModelNode() && selectionContext.currentSingleSelectedNode().metaInfo().isQtQuick3DView3D()) { + targetNode = selectionContext.currentSingleSelectedNode(); + } + + const QPointF scenePos = selectionContext.scenePosition(); + if (!targetNode.isValid() && !scenePos.isNull()) { + // If currently selected node is not View3D, check if there is a View3D under the cursor. + // Assumption is that last match in allModelNodes() list is the topmost one. + const QList<ModelNode> allNodes = selectionContext.view()->allModelNodes(); + for (int i = allNodes.size() - 1; i >= 0; --i) { + if (SelectionContextHelpers::contains(allNodes[i], selectionContext.scenePosition())) { + if (allNodes[i].metaInfo().isQtQuick3DView3D()) + targetNode = allNodes[i]; + break; + } + } + } + + if (targetNode.isValid()) { QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Editor3D", true); - const QPointF scenePos = selectionContext.scenePosition(); if (scenePos.isNull()) { selectionContext.view()->emitView3DAction(View3DActionType::AlignViewToCamera, true); } else { selectionContext.view()->emitCustomNotification("pick_3d_node_from_2d_scene", - {selectionContext.currentSingleSelectedNode()}, - {scenePos}); + {targetNode}, {scenePos}); } } } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index a20904b2e5..4712b048b1 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -462,6 +462,7 @@ void Edit3DView::customNotification([[maybe_unused]] const AbstractView *view, self->emitView3DAction(View3DActionType::GetNodeAtMainScenePos, QVariantList{data[0], nodeList[0].internalId()}); self->m_nodeAtPosReqType = NodeAtPosReqType::MainScenePick; + self->m_pickView3dNode = nodeList[0]; }); } } @@ -514,6 +515,8 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos } else if (m_nodeAtPosReqType == NodeAtPosReqType::MainScenePick) { if (modelNode.isValid()) setSelectedModelNode(modelNode); + else if (m_pickView3dNode.isValid() && !m_pickView3dNode.isSelected()) + setSelectedModelNode(m_pickView3dNode); emitView3DAction(View3DActionType::AlignViewToCamera, true); } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index fad87aae1f..ade2ef6a8f 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -189,6 +189,7 @@ private: QList<SplitToolState> m_splitToolStates; QList<Edit3DAction *> m_flyModeDisabledActions; ModelNode m_contextMenuPendingNode; + ModelNode m_pickView3dNode; double m_previousCameraSpeed = -1.; double m_previousCameraMultiplier = -1.; |