diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml index 1376610984d..34090031897 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml @@ -363,7 +363,7 @@ Item { } } - function handleObjectClicked(object, multi) + function handleObjectClicked(object, button, multi) { if (object instanceof View3D) { // View3D can be the resolved pick target in case the 3D editor is showing content @@ -393,7 +393,14 @@ Item { // Null object always clears entire selection var newSelection = []; if (clickedObject) { - if (multi && selectedNodes.length > 0) { + if (button === Qt.RightButton) { + // Right-clicking does only single selection (when clickedObject is unselected) + // This is needed for selecting a target for the context menu + if (!selectedNodes.includes(clickedObject)) + newSelection[0] = clickedObject; + else + newSelection = selectedNodes; + } else if (multi && selectedNodes.length > 0) { var deselect = false; for (var i = 0; i < selectedNodes.length; ++i) { // Multiselecting already selected object clears that object from selection @@ -697,10 +704,10 @@ Item { view3D: overlayView dragHelper: gizmoDragHelper - onPropertyValueCommit: (propName)=> { + onPropertyValueCommit: (propName) => { viewRoot.commitObjectProperty([targetNode], [propName]); } - onPropertyValueChange: (propName)=> { + onPropertyValueChange: (propName) => { viewRoot.changeObjectProperty([targetNode], [propName]); } } @@ -772,17 +779,17 @@ Item { MouseArea { anchors.fill: parent - acceptedButtons: Qt.LeftButton + acceptedButtons: Qt.LeftButton | Qt.RightButton hoverEnabled: false property MouseArea3D freeDraggerArea property point pressPoint property bool initialMoveBlock: false - onPressed: (mouse)=> { + onPressed: (mouse) => { if (viewRoot.editView) { var pickResult = viewRoot.editView.pick(mouse.x, mouse.y); - handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit), + handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit), mouse.button, mouse.modifiers & Qt.ControlModifier); if (pickResult.objectHit && pickResult.objectHit instanceof Node) { @@ -800,7 +807,7 @@ Item { } } } - onPositionChanged: (mouse)=> { + onPositionChanged: (mouse) => { if (freeDraggerArea) { if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) { // Don't force press event at actual press, as that puts the gizmo @@ -825,10 +832,10 @@ Item { } } - onReleased: (mouse)=> { + onReleased: (mouse) => { handleRelease(mouse); } - onCanceled: (mouse)=> { + onCanceled: (mouse) => { handleRelease(mouse); } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml index 721e74ac303..5fa269a916d 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml @@ -363,7 +363,7 @@ Item { } } - function handleObjectClicked(object, multi) + function handleObjectClicked(object, button, multi) { if (object instanceof View3D) { // View3D can be the resolved pick target in case the 3D editor is showing content @@ -393,7 +393,14 @@ Item { // Null object always clears entire selection var newSelection = []; if (clickedObject) { - if (multi && selectedNodes.length > 0) { + if (button === Qt.RightButton) { + // Right-clicking does only single selection (when clickedObject is unselected) + // This is needed for selecting a target for the context menu + if (!selectedNodes.includes(clickedObject)) + newSelection[0] = clickedObject; + else + newSelection = selectedNodes; + } else if (multi && selectedNodes.length > 0) { var deselect = false; for (var i = 0; i < selectedNodes.length; ++i) { // Multiselecting already selected object clears that object from selection @@ -841,10 +848,10 @@ Item { view3D: overlayView dragHelper: gizmoDragHelper - onPropertyValueCommit: (propName)=> { + onPropertyValueCommit: (propName) => { viewRoot.commitObjectProperty([targetNode], [propName]); } - onPropertyValueChange: (propName)=> { + onPropertyValueChange: (propName) => { viewRoot.changeObjectProperty([targetNode], [propName]); } } @@ -917,14 +924,14 @@ Item { MouseArea { anchors.fill: parent - acceptedButtons: Qt.LeftButton + acceptedButtons: Qt.LeftButton | Qt.RightButton hoverEnabled: false property MouseArea3D freeDraggerArea property point pressPoint property bool initialMoveBlock: false - onPressed: (mouse)=> { + onPressed: (mouse) => { if (viewRoot.editView) { // First pick overlay to check for hits there var pickResult = _generalHelper.pickViewAt(overlayView, mouse.x, mouse.y); @@ -935,7 +942,7 @@ Item { resolvedResult = _generalHelper.resolvePick(pickResult.objectHit); } - handleObjectClicked(resolvedResult, mouse.modifiers & Qt.ControlModifier); + handleObjectClicked(resolvedResult, mouse.button, mouse.modifiers & Qt.ControlModifier); if (pickResult.objectHit && pickResult.objectHit instanceof Node) { if (transformMode === EditView3D.TransformMode.Move) @@ -952,7 +959,7 @@ Item { } } } - onPositionChanged: (mouse)=> { + onPositionChanged: (mouse) => { if (freeDraggerArea) { if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) { // Don't force press event at actual press, as that puts the gizmo @@ -977,10 +984,10 @@ Item { } } - onReleased: (mouse)=> { + onReleased: (mouse) => { handleRelease(mouse); } - onCanceled: (mouse)=> { + onCanceled: (mouse) => { handleRelease(mouse); } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index b94fa31fc63..852572ebf13 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -285,12 +285,12 @@ void Qt5InformationNodeInstanceServer::handleInputEvents() continue; } } - auto me = new QMouseEvent(command.type(), command.pos(), command.button(), - command.buttons(), command.modifiers()); + QMouseEvent me(command.type(), command.pos(), command.button(), command.buttons(), + command.modifiers()); // We must use sendEvent in Qt 6, as using postEvent allows the associated position // data stored internally in QMutableEventPoint to potentially be updated by system // before the event is delivered. - QGuiApplication::sendEvent(m_editView3DData.window, me); + QGuiApplication::sendEvent(m_editView3DData.window, &me); // Context menu requested if (command.button() == Qt::RightButton && command.modifiers() == Qt::NoModifier) @@ -428,7 +428,8 @@ void Qt5InformationNodeInstanceServer::getModelAtPos(const QPointF &pos) QVariant instance = resolvedPick ? instanceForObject(resolvedPick).instanceId() : -1; nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ModelAtPos, instance}); - return; +#else + Q_UNUSED(pos) #endif } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index fb844b1c858..5a598dbd0e5 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -249,6 +249,10 @@ void Edit3DView::customNotification(const AbstractView *view, const QString &ide void Edit3DView::modelAtPosReady(const ModelNode &modelNode) { if (m_modelAtPosReqType == ModelAtPosReqType::ContextMenu) { + // Make sure right-clicked item is selected. Due to a bug in puppet side right-clicking an item + // while the context-menu is shown doesn't select the item. + if (modelNode.isValid() && !modelNode.isSelected()) + setSelectedModelNode(modelNode); m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode); } else if (m_modelAtPosReqType == ModelAtPosReqType::MaterialDrop) { if (m_droppedMaterial.isValid() && modelNode.isValid()) { diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 8643bc091b1..c7885996cec 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -185,7 +185,12 @@ void Edit3DWidget::createContextMenu() ModelNodeOperations::editMaterial(selCtx); }); - // TODO: add more actions: delete, create, etc + m_deleteAction = m_contextMenu->addAction(tr("Delete"), [&] { + view()->executeInTransaction("Edit3DWidget::createContextMenu", [&] { + for (ModelNode &node : m_view->selectedModelNodes()) + node.destroy(); + }); + }); } void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const @@ -241,6 +246,7 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode m_contextMenuTarget = modelNode; m_editMaterialAction->setEnabled(modelNode.isValid()); + m_deleteAction->setEnabled(modelNode.isValid()); m_contextMenu->popup(mapToGlobal(pos)); } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 6b3e773fdc4..7315f5a6b1d 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -76,6 +76,7 @@ private: QPointer m_backgroundColorMenu; QPointer m_contextMenu; QPointer m_editMaterialAction; + QPointer m_deleteAction; ModelNode m_contextMenuTarget; };