diff --git a/share/qtcreator/qml/qmlpuppet/commands/view3dactioncommand.h b/share/qtcreator/qml/qmlpuppet/commands/view3dactioncommand.h index 43bd32e1a20..cb23b2c9ad5 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/view3dactioncommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/view3dactioncommand.h @@ -47,6 +47,9 @@ public: OrientationToggle, EditLightToggle, ShowGrid, + ShowSelectionBox, + ShowIconGizmo, + ShowCameraFrustum, Edit3DParticleModeToggle, ParticlesPlay, ParticlesRestart, diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/CameraGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/CameraGizmo.qml index a108190ff7a..11976378d27 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/CameraGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/CameraGizmo.qml @@ -30,6 +30,7 @@ IconGizmo { id: cameraGizmo property Model frustumModel: null + property bool globalShowFrustum: false iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png" @@ -46,8 +47,12 @@ IconGizmo { frustum.targetNode = targetNode; frustum.targetNode = Qt.binding(function() {return targetNode;}); - frustum.visible = visible || (targetNode && selected && activeScene === scene); - frustum.visible = Qt.binding(function() {return visible || (targetNode && selected && activeScene === scene);}); + frustum.visible = (canBeVisible && globalShowFrustum) + || (targetNode && selected && activeScene === scene); + frustum.visible = Qt.binding(function() { + return (canBeVisible && globalShowFrustum) + || (targetNode && selected && activeScene === scene); + }); } onActiveSceneChanged: { diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml index 592e4ab72eb..0b15f190673 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/EditView3D.qml @@ -39,6 +39,9 @@ Item { property bool showEditLight: false property bool showGrid: true + property bool showSelectionBox: true + property bool showIconGizmo: true + property bool showCameraFrustum: false property bool usePerspective: true property bool globalOrientation: false property alias contentItem: contentItem @@ -70,6 +73,9 @@ Item { onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight) onGlobalOrientationChanged: _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) onShowGridChanged: _generalHelper.storeToolState(sceneId, "showGrid", showGrid); + onShowSelectionBoxChanged: _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox); + onShowIconGizmoChanged: _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo); + onShowCameraFrustumChanged: _generalHelper.storeToolState(sceneId, "showCameraFrustum", showCameraFrustum); onSelectionModeChanged: _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode); onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode); @@ -220,6 +226,21 @@ Item { else if (resetToDefault) showGrid = true; + if ("showSelectionBox" in toolStates) + showSelectionBox = toolStates.showSelectionBox; + else if (resetToDefault) + showSelectionBox = true; + + if ("showIconGizmo" in toolStates) + showIconGizmo = toolStates.showIconGizmo; + else if (resetToDefault) + showIconGizmo = true; + + if ("showCameraFrustum" in toolStates) + showCameraFrustum = toolStates.showCameraFrustum; + else if (resetToDefault) + showCameraFrustum = false; + if ("usePerspective" in toolStates) usePerspective = toolStates.usePerspective; else if (resetToDefault) @@ -250,6 +271,9 @@ Item { { _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight) _generalHelper.storeToolState(sceneId, "showGrid", showGrid) + _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox) + _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo) + _generalHelper.storeToolState(sceneId, "showCameraFrustum", showCameraFrustum) _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective) _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode); @@ -273,6 +297,7 @@ Item { "geometryName": geometryName}); selectionBoxes[selectionBoxes.length] = box; box.view3D = Qt.binding(function() {return editView;}); + box.visible = Qt.binding(function() {return showSelectionBox;}); } } } @@ -373,11 +398,13 @@ Item { "selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene, "locked": _generalHelper.isLocked(obj), - "hidden": _generalHelper.isHidden(obj)}); + "hidden": _generalHelper.isHidden(obj), + "globalShow": showIconGizmo}); lightIconGizmos[lightIconGizmos.length] = gizmo; gizmo.clicked.connect(handleObjectClicked); gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;}); gizmo.activeScene = Qt.binding(function() {return activeScene;}); + gizmo.globalShow = Qt.binding(function() {return showIconGizmo;}); } } @@ -416,12 +443,15 @@ Item { overlayView, {"view3D": overlayView, "targetNode": obj, "selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene, - "locked": _generalHelper.isLocked(obj), "hidden": _generalHelper.isHidden(obj)}); + "locked": _generalHelper.isLocked(obj), "hidden": _generalHelper.isHidden(obj), + "globalShow": showIconGizmo, "globalShowFrustum": showCameraFrustum}); cameraGizmos[cameraGizmos.length] = gizmo; gizmo.clicked.connect(handleObjectClicked); gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;}); gizmo.activeScene = Qt.binding(function() {return activeScene;}); + gizmo.globalShow = Qt.binding(function() {return showIconGizmo;}); + gizmo.globalShowFrustum = Qt.binding(function() {return showCameraFrustum;}); frustum.viewPortRect = Qt.binding(function() {return viewPortRect;}); gizmo.connectFrustum(frustum); } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/IconGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/IconGizmo.qml index 24459e08d4f..3ee4776aa52 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/IconGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt5/IconGizmo.qml @@ -45,6 +45,8 @@ Item { property bool hasMouse: false property bool hidden: false property bool locked: false + property bool globalShow: true + property bool canBeVisible: activeScene === scene && !hidden && (targetNode ? targetNode.visible : false) property alias iconSource: iconImage.source @@ -55,7 +57,7 @@ Item { hasMouse = false; } - visible: activeScene === scene && !hidden && (targetNode ? targetNode.visible : false) + visible: canBeVisible && globalShow Overlay2D { id: iconOverlay diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraGizmo.qml index 42a7bc7bfaa..872c30a3452 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraGizmo.qml @@ -30,6 +30,7 @@ IconGizmo { id: cameraGizmo property Model frustumModel: null + property bool globalShowFrustum: false iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png" @@ -46,8 +47,12 @@ IconGizmo { frustum.targetNode = targetNode; frustum.targetNode = Qt.binding(function() {return targetNode;}); - frustum.visible = visible || (targetNode && selected && activeScene === scene); - frustum.visible = Qt.binding(function() {return visible || (targetNode && selected && activeScene === scene);}); + frustum.visible = (canBeVisible && globalShowFrustum) + || (targetNode && selected && activeScene === scene); + frustum.visible = Qt.binding(function() { + return (canBeVisible && globalShowFrustum) + || (targetNode && selected && activeScene === scene); + }); } onActiveSceneChanged: { diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml index 944c42b653b..a1061ba672c 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml @@ -39,6 +39,9 @@ Item { property bool showEditLight: false property bool showGrid: true + property bool showSelectionBox: true + property bool showIconGizmo: true + property bool showCameraFrustum: false property bool usePerspective: true property bool globalOrientation: false property alias contentItem: contentItem @@ -71,6 +74,9 @@ Item { onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight) onGlobalOrientationChanged: _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) onShowGridChanged: _generalHelper.storeToolState(sceneId, "showGrid", showGrid); + onShowSelectionBoxChanged: _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox); + onShowIconGizmoChanged: _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo); + onShowCameraFrustumChanged: _generalHelper.storeToolState(sceneId, "showCameraFrustum", showCameraFrustum); onSelectionModeChanged: _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode); onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode); @@ -211,6 +217,21 @@ Item { else if (resetToDefault) showGrid = true; + if ("showSelectionBox" in toolStates) + showSelectionBox = toolStates.showSelectionBox; + else if (resetToDefault) + showSelectionBox = true; + + if ("showIconGizmo" in toolStates) + showIconGizmo = toolStates.showIconGizmo; + else if (resetToDefault) + showIconGizmo = true; + + if ("showCameraFrustum" in toolStates) + showCameraFrustum = toolStates.showCameraFrustum; + else if (resetToDefault) + showCameraFrustum = false; + if ("usePerspective" in toolStates) usePerspective = toolStates.usePerspective; else if (resetToDefault) @@ -241,6 +262,9 @@ Item { { _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight) _generalHelper.storeToolState(sceneId, "showGrid", showGrid) + _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox) + _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo) + _generalHelper.storeToolState(sceneId, "showCameraFrustum", showCameraFrustum) _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective) _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode); @@ -264,6 +288,7 @@ Item { "geometryName": geometryName}); selectionBoxes[selectionBoxes.length] = box; box.view3D = Qt.binding(function() {return editView;}); + box.visible = Qt.binding(function() {return showSelectionBox;}); } } } @@ -364,11 +389,13 @@ Item { "selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene, "locked": _generalHelper.isLocked(obj), - "hidden": _generalHelper.isHidden(obj)}); + "hidden": _generalHelper.isHidden(obj), + "globalShow": showIconGizmo}); lightIconGizmos[lightIconGizmos.length] = gizmo; gizmo.clicked.connect(handleObjectClicked); gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;}); gizmo.activeScene = Qt.binding(function() {return activeScene;}); + gizmo.globalShow = Qt.binding(function() {return showIconGizmo;}); } } @@ -407,12 +434,15 @@ Item { overlayView, {"view3D": overlayView, "targetNode": obj, "selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene, - "locked": _generalHelper.isLocked(obj), "hidden": _generalHelper.isHidden(obj)}); + "locked": _generalHelper.isLocked(obj), "hidden": _generalHelper.isHidden(obj), + "globalShow": showIconGizmo, "globalShowFrustum": showCameraFrustum}); cameraGizmos[cameraGizmos.length] = gizmo; gizmo.clicked.connect(handleObjectClicked); gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;}); gizmo.activeScene = Qt.binding(function() {return activeScene;}); + gizmo.globalShow = Qt.binding(function() {return showIconGizmo;}); + gizmo.globalShowFrustum = Qt.binding(function() {return showCameraFrustum;}); frustum.viewPortRect = Qt.binding(function() {return viewPortRect;}); gizmo.connectFrustum(frustum); } @@ -449,11 +479,13 @@ Item { "selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene, "locked": _generalHelper.isLocked(obj), - "hidden": _generalHelper.isHidden(obj)}); + "hidden": _generalHelper.isHidden(obj), + "globalShow": showIconGizmo}); particleSystemIconGizmos[particleSystemIconGizmos.length] = gizmo; gizmo.clicked.connect(handleObjectClicked); gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;}); gizmo.activeScene = Qt.binding(function() {return activeScene;}); + gizmo.globalShow = Qt.binding(function() {return showIconGizmo;}); } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/IconGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/IconGizmo.qml index 03087b658a9..7752693d559 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/IconGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/IconGizmo.qml @@ -45,6 +45,8 @@ Item { property bool hasMouse: false property bool hidden: false property bool locked: false + property bool globalShow: true + property bool canBeVisible: activeScene === scene && !hidden && (targetNode ? targetNode.visible : false) property alias iconSource: iconImage.source @@ -55,7 +57,7 @@ Item { hasMouse = false; } - visible: activeScene === scene && !hidden && (targetNode ? targetNode.visible : false) + visible: canBeVisible && globalShow Overlay2D { id: iconOverlay diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index b2a84ff53f3..afde832afcb 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -2116,6 +2116,15 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c case View3DActionCommand::ShowGrid: updatedState.insert("showGrid", command.isEnabled()); break; + case View3DActionCommand::ShowSelectionBox: + updatedState.insert("showSelectionBox", command.isEnabled()); + break; + case View3DActionCommand::ShowIconGizmo: + updatedState.insert("showIconGizmo", command.isEnabled()); + break; + case View3DActionCommand::ShowCameraFrustum: + updatedState.insert("showCameraFrustum", command.isEnabled()); + break; #ifdef QUICK3D_PARTICLES_MODULE case View3DActionCommand::ParticlesPlay: m_particleAnimationPlaying = command.isEnabled(); diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index fcf71902c8e..68532c1a534 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -158,6 +158,7 @@ extend_qtc_plugin(QmlDesigner edit3dwidget.cpp edit3dwidget.h edit3dcanvas.cpp edit3dcanvas.h edit3dactions.cpp edit3dactions.h + edit3dvisibilitytogglesmenu.cpp edit3dvisibilitytogglesmenu.h edit3d.qrc ) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3d.qrc b/src/plugins/qmldesigner/components/edit3d/edit3d.qrc index bb1f6fd09c1..bf042b645b2 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3d.qrc +++ b/src/plugins/qmldesigner/components/edit3d/edit3d.qrc @@ -8,10 +8,6 @@ images/edit_light_off@2x.png images/edit_light_on.png images/edit_light_on@2x.png - images/grid_off.png - images/grid_off@2x.png - images/grid_on.png - images/grid_on@2x.png images/fit_selected.png images/fit_selected@2x.png images/move_off.png diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp index e7838e720e8..c5240a0cbd6 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp @@ -60,7 +60,7 @@ void Edit3DActionTemplate::actionTriggered(bool b) Edit3DAction::Edit3DAction(const QByteArray &menuId, View3DActionCommand::Type type, const QString &description, const QKeySequence &key, bool checkable, bool checked, const QIcon &iconOff, const QIcon &iconOn, - SelectionContextOperation selectionAction) + SelectionContextOperation selectionAction, const QString &toolTip) : AbstractAction(new Edit3DActionTemplate(description, selectionAction, type)) , m_menuId(menuId) { @@ -68,6 +68,11 @@ Edit3DAction::Edit3DAction(const QByteArray &menuId, View3DActionCommand::Type t action()->setShortcutContext(Qt::WidgetWithChildrenShortcut); action()->setCheckable(checkable); action()->setChecked(checked); + + // Description will be used as tooltip by default if no explicit tooltip is provided + if (!toolTip.isEmpty()) + action()->setToolTip(toolTip); + if (checkable) { QIcon onOffIcon; const auto onAvail = iconOn.availableSizes(); // Assume both icons have same sizes available diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h index 27b8fb7342d..ca95608629e 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h @@ -54,7 +54,8 @@ public: Edit3DAction(const QByteArray &menuId, View3DActionCommand::Type type, const QString &description, const QKeySequence &key, bool checkable, bool checked, const QIcon &iconOff, const QIcon &iconOn, - SelectionContextOperation selectionAction = nullptr); + SelectionContextOperation selectionAction = nullptr, + const QString &toolTip = {}); QByteArray category() const override; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 386f6a1137f..8e6d75efc37 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -42,6 +42,7 @@ #include #include +#include namespace QmlDesigner { @@ -113,14 +114,17 @@ void Edit3DView::renderImage3DChanged(const QImage &img) void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) { - const QString sceneKey = QStringLiteral("sceneInstanceId"); - const QString selectKey = QStringLiteral("selectionMode"); - const QString transformKey = QStringLiteral("transformMode"); - const QString perspectiveKey = QStringLiteral("usePerspective"); - const QString orientationKey = QStringLiteral("globalOrientation"); - const QString editLightKey = QStringLiteral("showEditLight"); - const QString gridKey = QStringLiteral("showGrid"); - const QString particlesPlayKey = QStringLiteral("particlePlay"); + const QString sceneKey = QStringLiteral("sceneInstanceId"); + const QString selectKey = QStringLiteral("selectionMode"); + const QString transformKey = QStringLiteral("transformMode"); + const QString perspectiveKey = QStringLiteral("usePerspective"); + const QString orientationKey = QStringLiteral("globalOrientation"); + const QString editLightKey = QStringLiteral("showEditLight"); + const QString gridKey = QStringLiteral("showGrid"); + const QString selectionBoxKey = QStringLiteral("showSelectionBox"); + const QString iconGizmoKey = QStringLiteral("showIconGizmo"); + const QString cameraFrustumKey = QStringLiteral("showCameraFrustum"); + const QString particlesPlayKey = QStringLiteral("particlePlay"); if (sceneState.contains(sceneKey)) { qint32 newActiveScene = sceneState[sceneKey].value(); @@ -165,6 +169,21 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) else m_showGridAction->action()->setChecked(false); + if (sceneState.contains(selectionBoxKey)) + m_showSelectionBoxAction->action()->setChecked(sceneState[selectionBoxKey].toBool()); + else + m_showSelectionBoxAction->action()->setChecked(false); + + if (sceneState.contains(iconGizmoKey)) + m_showIconGizmoAction->action()->setChecked(sceneState[iconGizmoKey].toBool()); + else + m_showIconGizmoAction->action()->setChecked(false); + + if (sceneState.contains(cameraFrustumKey)) + m_showCameraFrustumAction->action()->setChecked(sceneState[cameraFrustumKey].toBool()); + else + m_showCameraFrustumAction->action()->setChecked(false); + if (sceneState.contains(particlesPlayKey)) m_particlesPlayAction->action()->setChecked(sceneState[particlesPlayKey].toBool()); else @@ -301,9 +320,27 @@ void Edit3DView::createEdit3DActions() m_showGridAction = new Edit3DAction( QmlDesigner::Constants::EDIT3D_EDIT_SHOW_GRID, View3DActionCommand::ShowGrid, - QCoreApplication::translate("ShowGridAction", "Toggle Grid Visibility"), - QKeySequence(Qt::Key_G), true, true, Icons::EDIT3D_GRID_OFF.icon(), - Icons::EDIT3D_GRID_ON.icon()); + QCoreApplication::translate("ShowGridAction", "Show Grid"), + QKeySequence(Qt::Key_G), true, true, {}, {}, nullptr, + QCoreApplication::translate("ShowGridAction", "Toggle the visibility of the helper grid.")); + + m_showSelectionBoxAction = new Edit3DAction( + QmlDesigner::Constants::EDIT3D_EDIT_SHOW_SELECTION_BOX, View3DActionCommand::ShowSelectionBox, + QCoreApplication::translate("ShowSelectionBoxAction", "Show Selection Boxes"), + QKeySequence(Qt::Key_S), true, true, {}, {}, nullptr, + QCoreApplication::translate("ShowSelectionBoxAction", "Toggle the visibility of selection boxes.")); + + m_showIconGizmoAction = new Edit3DAction( + QmlDesigner::Constants::EDIT3D_EDIT_SHOW_ICON_GIZMO, View3DActionCommand::ShowIconGizmo, + QCoreApplication::translate("ShowIconGizmoAction", "Show Icon Gizmos"), + QKeySequence(Qt::Key_I), true, true, {}, {}, nullptr, + QCoreApplication::translate("ShowIconGizmoAction", "Toggle the visibility of icon gizmos, such as light and camera icons.")); + + m_showCameraFrustumAction = new Edit3DAction( + QmlDesigner::Constants::EDIT3D_EDIT_SHOW_CAMERA_FRUSTUM, View3DActionCommand::ShowCameraFrustum, + QCoreApplication::translate("ShowCameraFrustumAction", "Always Show Camera Frustums"), + QKeySequence(Qt::Key_C), true, false, {}, {}, nullptr, + QCoreApplication::translate("ShowCameraFrustumAction", "Toggle between always showing the camera frustum visualization and only showing it when the camera is selected.")); SelectionContextOperation resetTrigger = [this](const SelectionContext &) { m_particlesPlayAction->action()->setEnabled(particlemode); @@ -360,6 +397,29 @@ void Edit3DView::createEdit3DActions() QKeySequence(Qt::Key_P), false, false, Utils::Icons::RESET_TOOLBAR.icon(), {}, resetTrigger); + SelectionContextOperation visibilityTogglesTrigger = [this](const SelectionContext &) { + if (!edit3DWidget()->visibilityTogglesMenu()) + return; + + QPoint pos; + const auto &actionWidgets = m_visibilityTogglesAction->action()->associatedWidgets(); + for (auto actionWidget : actionWidgets) { + if (auto button = qobject_cast(actionWidget)) { + pos = button->mapToGlobal(QPoint(0, 0)); + break; + } + } + + edit3DWidget()->showVisibilityTogglesMenu(!edit3DWidget()->visibilityTogglesMenu()->isVisible(), + pos); + }; + + m_visibilityTogglesAction = new Edit3DAction( + QmlDesigner::Constants::EDIT3D_VISIBILITY_TOGGLES, View3DActionCommand::Empty, + QCoreApplication::translate("VisibilityTogglesAction", "Visibility Toggles"), + QKeySequence(), false, false, Utils::Icons::EYE_OPEN_TOOLBAR.icon(), + {}, visibilityTogglesTrigger); + m_leftActions << m_selectionModeAction; m_leftActions << nullptr; // Null indicates separator m_leftActions << nullptr; // Second null after separator indicates an exclusive group @@ -372,16 +432,22 @@ void Edit3DView::createEdit3DActions() m_leftActions << m_cameraModeAction; m_leftActions << m_orientationModeAction; m_leftActions << m_editLightAction; - m_leftActions << m_showGridAction; m_leftActions << nullptr; m_leftActions << m_alignCamerasAction; m_leftActions << m_alignViewAction; + m_leftActions << nullptr; + m_leftActions << m_visibilityTogglesAction; m_rightActions << m_particleViewModeAction; m_rightActions << m_particlesPlayAction; m_rightActions << m_particlesRestartAction; m_rightActions << nullptr; m_rightActions << m_resetAction; + + m_visibilityToggleActions << m_showGridAction; + m_visibilityToggleActions << m_showSelectionBoxAction; + m_visibilityToggleActions << m_showIconGizmoAction; + m_visibilityToggleActions << m_showCameraFrustumAction; } QVector Edit3DView::leftActions() const @@ -394,6 +460,11 @@ QVector Edit3DView::rightActions() const return m_rightActions; } +QVector Edit3DView::visibilityToggleActions() const +{ + return m_visibilityToggleActions; +} + void Edit3DView::addQuick3DImport() { DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index a61f78301c0..721a69bfa2e 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -71,6 +71,7 @@ public: void createEdit3DActions(); QVector leftActions() const; QVector rightActions() const; + QVector visibilityToggleActions() const; void setSeeker(SeekerSlider *slider); void addQuick3DImport(); @@ -84,6 +85,7 @@ private: QPointer m_edit3DWidget; QVector m_leftActions; QVector m_rightActions; + QVector m_visibilityToggleActions; Edit3DAction *m_selectionModeAction = nullptr; Edit3DAction *m_moveToolAction = nullptr; Edit3DAction *m_rotateToolAction = nullptr; @@ -95,10 +97,14 @@ private: Edit3DAction *m_orientationModeAction = nullptr; Edit3DAction *m_editLightAction = nullptr; Edit3DAction *m_showGridAction = nullptr; + Edit3DAction *m_showSelectionBoxAction = nullptr; + Edit3DAction *m_showIconGizmoAction = nullptr; + Edit3DAction *m_showCameraFrustumAction = nullptr; Edit3DAction *m_resetAction = nullptr; Edit3DAction *m_particleViewModeAction = nullptr; Edit3DAction *m_particlesPlayAction = nullptr; Edit3DAction *m_particlesRestartAction = nullptr; + Edit3DAction *m_visibilityTogglesAction = nullptr; SeekerSlider *m_seeker = nullptr; int particlemode; }; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dvisibilitytogglesmenu.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dvisibilitytogglesmenu.cpp new file mode 100644 index 00000000000..9769411e904 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/edit3dvisibilitytogglesmenu.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "edit3dvisibilitytogglesmenu.h" + +namespace QmlDesigner { + +Edit3DVisibilityTogglesMenu::Edit3DVisibilityTogglesMenu(QWidget *parent) : + QMenu(parent) +{ + setToolTipsVisible(true); +} + +void Edit3DVisibilityTogglesMenu::mouseReleaseEvent(QMouseEvent *e) +{ + QAction *action = activeAction(); + if (action && action->isEnabled()) { + // Prevent the menu from closing on click on any item + action->setEnabled(false); + QMenu::mouseReleaseEvent(e); + action->setEnabled(true); + action->trigger(); + } else { + QMenu::mouseReleaseEvent(e); + } +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dvisibilitytogglesmenu.h b/src/plugins/qmldesigner/components/edit3d/edit3dvisibilitytogglesmenu.h new file mode 100644 index 00000000000..1838068b0f3 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/edit3dvisibilitytogglesmenu.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ +#pragma once + +#include + +namespace QmlDesigner { + +class Edit3DVisibilityTogglesMenu : public QMenu +{ + Q_OBJECT + +public: + explicit Edit3DVisibilityTogglesMenu(QWidget *parent = nullptr); + +protected: + void mouseReleaseEvent(QMouseEvent *e) override; + +private: +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 06630e3a4de..d88cf612c15 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -28,6 +28,7 @@ #include "edit3dcanvas.h" #include "edit3dview.h" #include "edit3dwidget.h" +#include "edit3dvisibilitytogglesmenu.h" #include "metainfo.h" #include "qmldesignerconstants.h" #include "qmldesignerplugin.h" @@ -75,27 +76,37 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) : // Iterate through view actions. A null action indicates a separator and a second null action // after separator indicates an exclusive group. - auto addActionsToToolBox = [this, &context](const QVector &actions, bool left) { + auto handleActions = [this, &context](const QVector &actions, QMenu *menu, bool left) { bool previousWasSeparator = true; QActionGroup *group = nullptr; for (auto action : actions) { if (action) { + QAction *a = action->action(); if (group) - group->addAction(action->action()); - addAction(action->action()); - if (left) - m_toolBox->addLeftSideAction(action->action()); - else - m_toolBox->addRightSideAction(action->action()); + group->addAction(a); + if (menu) { + menu->addAction(a); + } else { + addAction(a); + if (left) + m_toolBox->addLeftSideAction(a); + else + m_toolBox->addRightSideAction(a); + } previousWasSeparator = false; // Register action as creator command to make it configurable Core::Command *command = Core::ActionManager::registerAction( - action->action(), action->menuId().constData(), context); - command->setDefaultKeySequence(action->action()->shortcut()); - command->augmentActionWithShortcutToolTip(action->action()); + a, action->menuId().constData(), context); + command->setDefaultKeySequence(a->shortcut()); + // Menu actions will have custom tooltips + if (menu) + a->setToolTip(command->stringWithAppendedShortcut(a->toolTip())); + else + command->augmentActionWithShortcutToolTip(a); + // Clear action shortcut so it doesn't conflict with command's override action - action->action()->setShortcut({}); + a->setShortcut({}); } else { if (previousWasSeparator) { group = new QActionGroup(this); @@ -104,18 +115,26 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) : group = nullptr; auto separator = new QAction(this); separator->setSeparator(true); - addAction(separator); - if (left) - m_toolBox->addLeftSideAction(separator); - else - m_toolBox->addRightSideAction(separator); + if (menu) { + menu->addAction(separator); + } else { + addAction(separator); + if (left) + m_toolBox->addLeftSideAction(separator); + else + m_toolBox->addRightSideAction(separator); + } previousWasSeparator = true; } } } }; - addActionsToToolBox(view->leftActions(), true); - addActionsToToolBox(view->rightActions(), false); + + handleActions(view->leftActions(), nullptr, true); + handleActions(view->rightActions(), nullptr, false); + + m_visibilityTogglesMenu = new Edit3DVisibilityTogglesMenu(this); + handleActions(view->visibilityToggleActions(), m_visibilityTogglesMenu, false); view->setSeeker(seeker); seeker->setToolTip(QLatin1String("Seek particle system time when paused.")); @@ -162,6 +181,21 @@ void Edit3DWidget::showCanvas(bool show) m_onboardingLabel->setVisible(!show); } +QMenu *Edit3DWidget::visibilityTogglesMenu() const +{ + return m_visibilityTogglesMenu.data(); +} + +void Edit3DWidget::showVisibilityTogglesMenu(bool show, const QPoint &pos) +{ + if (m_visibilityTogglesMenu.isNull()) + return; + if (show) + m_visibilityTogglesMenu->popup(pos); + else + m_visibilityTogglesMenu->close(); +} + void Edit3DWidget::linkActivated(const QString &link) { Q_UNUSED(link) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index e7223ceb8c9..5a4ed48e28e 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -47,6 +48,8 @@ public: void contextHelp(const Core::IContext::HelpCallback &callback) const; void showCanvas(bool show); + QMenu *visibilityTogglesMenu() const; + void showVisibilityTogglesMenu(bool show, const QPoint &pos); protected: void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override; @@ -61,6 +64,7 @@ private: QPointer m_onboardingLabel; QPointer m_toolBox; Core::IContext *m_context = nullptr; + QPointer m_visibilityTogglesMenu; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/images/grid_off.png b/src/plugins/qmldesigner/components/edit3d/images/grid_off.png deleted file mode 100644 index 4c355f70a89..00000000000 Binary files a/src/plugins/qmldesigner/components/edit3d/images/grid_off.png and /dev/null differ diff --git a/src/plugins/qmldesigner/components/edit3d/images/grid_off@2x.png b/src/plugins/qmldesigner/components/edit3d/images/grid_off@2x.png deleted file mode 100644 index 88db6b9badd..00000000000 Binary files a/src/plugins/qmldesigner/components/edit3d/images/grid_off@2x.png and /dev/null differ diff --git a/src/plugins/qmldesigner/components/edit3d/images/grid_on.png b/src/plugins/qmldesigner/components/edit3d/images/grid_on.png deleted file mode 100644 index 4c355f70a89..00000000000 Binary files a/src/plugins/qmldesigner/components/edit3d/images/grid_on.png and /dev/null differ diff --git a/src/plugins/qmldesigner/components/edit3d/images/grid_on@2x.png b/src/plugins/qmldesigner/components/edit3d/images/grid_on@2x.png deleted file mode 100644 index 88db6b9badd..00000000000 Binary files a/src/plugins/qmldesigner/components/edit3d/images/grid_on@2x.png and /dev/null differ diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 53edd711d5c..3830c9e8da8 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -65,10 +65,14 @@ const char EDIT3D_EDIT_CAMERA[] = "QmlDesigner.Editor3D.EditCameraToggle"; const char EDIT3D_ORIENTATION[] = "QmlDesigner.Editor3D.OrientationToggle"; const char EDIT3D_EDIT_LIGHT[] = "QmlDesigner.Editor3D.EditLightToggle"; const char EDIT3D_EDIT_SHOW_GRID[] = "QmlDesigner.Editor3D.ToggleGrid"; +const char EDIT3D_EDIT_SHOW_SELECTION_BOX[] = "QmlDesigner.Editor3D.ToggleSelectionBox"; +const char EDIT3D_EDIT_SHOW_ICON_GIZMO[] = "QmlDesigner.Editor3D.ToggleIconGizmo"; +const char EDIT3D_EDIT_SHOW_CAMERA_FRUSTUM[] = "QmlDesigner.Editor3D.ToggleCameraFrustum"; const char EDIT3D_RESET_VIEW[] = "QmlDesigner.Editor3D.ResetView"; const char EDIT3D_PARTICLE_MODE[] = "QmlDesigner.Editor3D.ParticleViewModeToggle"; const char EDIT3D_PARTICLES_PLAY[] = "QmlDesigner.Editor3D.ParticlesPlay"; const char EDIT3D_PARTICLES_RESTART[] = "QmlDesigner.Editor3D.ParticlesRestart"; +const char EDIT3D_VISIBILITY_TOGGLES[] = "QmlDesigner.Editor3D.VisibilityToggles"; const char QML_DESIGNER_SUBFOLDER[] = "/designer/"; diff --git a/src/plugins/qmldesigner/qmldesignericons.h b/src/plugins/qmldesigner/qmldesignericons.h index 3323ceb49a9..75ec4ab2d3f 100644 --- a/src/plugins/qmldesigner/qmldesignericons.h +++ b/src/plugins/qmldesigner/qmldesignericons.h @@ -61,10 +61,6 @@ const Utils::Icon EDIT3D_PARTICLE_PAUSE({ {":/edit3d/images/particles_pause.png", Utils::Theme::QmlDesigner_HighlightColor}}); const Utils::Icon EDIT3D_PARTICLE_RESTART({ {":/edit3d/images/particles_restart.png", Utils::Theme::QmlDesigner_HighlightColor}}); -const Utils::Icon EDIT3D_GRID_ON({ - {":/edit3d/images/grid_on.png", Utils::Theme::QmlDesigner_HighlightColor}}); -const Utils::Icon EDIT3D_GRID_OFF({ - {":/edit3d/images/grid_off.png", Utils::Theme::IconsBaseColor}}); const Utils::Icon EDIT3D_SELECTION_MODE_ON({ {":/edit3d/images/select_group.png", Utils::Theme::QmlDesigner_HighlightColor}}); const Utils::Icon EDIT3D_SELECTION_MODE_OFF({ diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index ff16d0de7e3..e8bd9e68a04 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -514,6 +514,8 @@ Project { "edit3d/edit3dcanvas.h", "edit3d/edit3dactions.cpp", "edit3d/edit3dactions.h", + "edit3d/edit3dvisibilitytogglesmenu.cpp", + "edit3d/edit3dvisibilitytogglesmenu.h", "edit3d/edit3d.qrc", "formeditor/abstractcustomtool.cpp", "formeditor/abstractcustomtool.h",