diff --git a/share/qtcreator/qmldesigner/edit3dQmlSource/SnapConfigurationDialog.qml b/share/qtcreator/qmldesigner/edit3dQmlSource/SnapConfigurationDialog.qml index d34a210ae8c..b246eb62daf 100644 --- a/share/qtcreator/qmldesigner/edit3dQmlSource/SnapConfigurationDialog.qml +++ b/share/qtcreator/qmldesigner/edit3dQmlSource/SnapConfigurationDialog.qml @@ -3,6 +3,7 @@ import QtQuick import QtQuick.Controls +import QtQuick.Layouts import QtQuickDesignerTheme import HelperWidgets as HelperWidgets import StudioControls as StudioControls @@ -13,175 +14,229 @@ Rectangle { property int toolTipDelay: 1000 + width: 230 + height: 270 color: StudioTheme.Values.themePanelBackground + border.color: StudioTheme.Values.themeControlOutline + border.width: StudioTheme.Values.border - Column { - id: col - padding: 8 - spacing: 4 + Connections { + target: rootView - Rectangle { - id: ctrlRect - width: root.width - 16 - height: posIntValue.height + rotIntValue.height + scaleIntValue.height + 32 + // Spinboxes lose the initial binding if the value changes so we need these connections + onPosIntChanged: posIntSpin.realValue = rootView.posInt + onRotIntChanged: rotIntSpin.realValue = rootView.rotInt + onScaleIntChanged: scaleIntSpin.realValue = rootView.scaleInt + } - color: StudioTheme.Values.themePanelBackground - border.color: StudioTheme.Values.themeControlOutline - border.width: StudioTheme.Values.border + ColumnLayout { + anchors.fill: parent + spacing: 0 - Column { - padding: 8 - spacing: 8 - Row { - height: posIntValue.height - width: parent.width - 16 - spacing: StudioTheme.Values.sectionRowSpacing + RowLayout { + height: 32 + Layout.topMargin: 8 + Layout.rightMargin: 8 + Layout.leftMargin: 8 + Layout.fillWidth: true + spacing: 16 - Text { - id: posIntLabel - text: qsTr("Position Snap Interval:") - color: enabled ? StudioTheme.Values.themeTextColor - : StudioTheme.Values.themeTextColorDisabled - verticalAlignment: Qt.AlignVCenter - horizontalAlignment: Qt.AlignRight - height: posIntValue.height - } + Rectangle { + width: 40 + height: 40 + radius: 5 + Layout.fillHeight: false + color: StudioTheme.Values.themePanelBackground + border.color: StudioTheme.Values.themeControlOutline + border.width: StudioTheme.Values.border - Item { // Spacer - width: Math.max(ctrlRect.width - posIntLabel.width - posIntValue.width - 32, 1) - height: 1 - } - - StudioControls.RealSpinBox { - id: posIntValue - realFrom: 1 - realTo: 100000 - realValue: rootView.posInt - realStepSize: 1 - width: 80 - actionIndicatorVisible: false - - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("Snap interval for move gizmo.") - ToolTip.delay: root.toolTipDelay - - onRealValueChanged: rootView.posInt = realValue - } - } - - Row { - height: rotIntValue.height - width: parent.width - 16 - spacing: StudioTheme.Values.sectionRowSpacing - - Text { - id: rotIntLabel - text: qsTr("Rotation Snap Interval:") - color: enabled ? StudioTheme.Values.themeTextColor - : StudioTheme.Values.themeTextColorDisabled - verticalAlignment: Qt.AlignVCenter - horizontalAlignment: Qt.AlignRight - height: rotIntValue.height - } - - Item { // Spacer - width: Math.max(ctrlRect.width - rotIntLabel.width - rotIntValue.width - 32, 1) - height: 1 - } - - StudioControls.RealSpinBox { - id: rotIntValue - realFrom: 1 - realTo: 360 - realValue: rootView.rotInt - realStepSize: 1 - width: 80 - actionIndicatorVisible: false - - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("Snap interval in degrees for rotation gizmo.") - ToolTip.delay: root.toolTipDelay - - onRealValueChanged: rootView.rotInt = realValue - } - } - - Row { - height: scaleIntValue.height - width: parent.width - 16 - spacing: StudioTheme.Values.sectionRowSpacing - - Text { - id: scaleIntLabel - text: qsTr("Scale Snap Interval (%):") - color: enabled ? StudioTheme.Values.themeTextColor - : StudioTheme.Values.themeTextColorDisabled - verticalAlignment: Qt.AlignVCenter - horizontalAlignment: Qt.AlignRight - height: scaleIntValue.height - } - - Item { // Spacer - width: Math.max(ctrlRect.width - scaleIntLabel.width - scaleIntValue.width - 32, 1) - height: 1 - } - - StudioControls.RealSpinBox { - id: scaleIntValue - realFrom: 1 - realTo: 100000 - realValue: rootView.scaleInt - realStepSize: 1 - width: 80 - actionIndicatorVisible: false - - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("Snap interval for scale gizmo in percentage of original scale.") - ToolTip.delay: root.toolTipDelay - - onRealValueChanged: rootView.scaleInt = realValue - } + HelperWidgets.IconIndicator { + anchors.fill: parent + icon: StudioTheme.Constants.snapping_conf_medium + pixelSize: StudioTheme.Values.myIconFontSize * 1.4 + iconColor: StudioTheme.Values.themeLinkIndicatorColorHover + enabled: false + states: [] // Disable normal state based coloring } } + Text { + text: qsTr("Snap Configuration") + font.pixelSize: 12 + horizontalAlignment: Text.AlignLeft + Layout.fillWidth: true + font.bold: true + color: StudioTheme.Values.themeTextColor + } } - Item { // Spacer - width: 1 - height: Math.max(root.height - buttons.height - ctrlRect.height - 16, 2) + GridLayout { + Layout.margins:10 + Layout.fillWidth: true + Layout.fillHeight: true + + rowSpacing: 5 + columnSpacing: 5 + rows: 5 + columns: 3 + + Text { + text: qsTr("Interval") + Layout.column: 1 + Layout.row: 0 + Layout.leftMargin: 10 + font.pixelSize: 12 + font.bold: true + color: StudioTheme.Values.themeTextColor + } + + StudioControls.CheckBox { + text: qsTr("Position") + Layout.column: 0 + Layout.row: 1 + Layout.minimumWidth: 100 + checked: rootView.posEnabled + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Snap position.") + ToolTip.delay: root.toolTipDelay + + onToggled: rootView.posEnabled = checked + } + + StudioControls.RealSpinBox { + id: posIntSpin + Layout.fillWidth: true + Layout.column: 1 + Layout.row: 1 + Layout.leftMargin: 10 + realFrom: 1 + realTo: 10000 + realValue: rootView.posInt + realStepSize: 1 + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Snap interval for move gizmo.") + ToolTip.delay: root.toolTipDelay + + onRealValueChanged: rootView.posInt = realValue + } + + StudioControls.CheckBox { + text: qsTr("Rotation") + Layout.column: 0 + Layout.row: 2 + Layout.minimumWidth: 100 + checked: rootView.rotEnabled + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Snap rotation.") + ToolTip.delay: root.toolTipDelay + + onToggled: rootView.rotEnabled = checked + } + + StudioControls.RealSpinBox { + id: rotIntSpin + Layout.fillWidth: true + Layout.column: 1 + Layout.row: 2 + Layout.leftMargin: 10 + realFrom: 1 + realTo: 90 + realValue: rootView.rotInt + realStepSize: 1 + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Snap interval in degrees for rotation gizmo.") + ToolTip.delay: root.toolTipDelay + + onRealValueChanged: rootView.rotInt = realValue + } + + StudioControls.CheckBox { + text: qsTr("Scale") + Layout.column: 0 + Layout.row: 3 + Layout.minimumWidth: 100 + checked: rootView.scaleEnabled + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Snap scale.") + ToolTip.delay: root.toolTipDelay + + onToggled: rootView.scaleEnabled = checked + } + + StudioControls.RealSpinBox { + id: scaleIntSpin + Layout.fillWidth: true + Layout.column: 1 + Layout.row: 3 + Layout.leftMargin: 10 + realFrom: 1 + realTo: 100 + realValue: rootView.scaleInt + realStepSize: 1 + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Snap interval for scale gizmo in percentage of original scale.") + ToolTip.delay: root.toolTipDelay + + onRealValueChanged: rootView.scaleInt = realValue + } + + StudioControls.CheckBox { + text: qsTr("Absolute Position") + Layout.fillWidth: false + Layout.leftMargin: 0 + Layout.column: 0 + Layout.row: 4 + Layout.columnSpan: 3 + checked: rootView.absolute + actionIndicatorVisible: false + + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Toggles if the position snaps to absolute values or relative to object position.") + ToolTip.delay: root.toolTipDelay + + onToggled: rootView.absolute = checked + } + + Text { + text: qsTr("deg") + font.pixelSize: 12 + Layout.column: 2 + Layout.row: 2 + color: StudioTheme.Values.themeTextColor + } + + Text { + text: qsTr("%") + font.pixelSize: 12 + Layout.column: 2 + Layout.row: 3 + color: StudioTheme.Values.themeTextColor + } } - Item { - id: buttons - height: cancelButton.height + 8 - width: ctrlRect.width - - Row { - spacing: StudioTheme.Values.dialogButtonSpacing - height: cancelButton.height - anchors.right: parent.right - - HelperWidgets.Button { - id: cancelButton - text: qsTr("Cancel") - leftPadding: StudioTheme.Values.dialogButtonPadding - rightPadding: StudioTheme.Values.dialogButtonPadding - onClicked: rootView.cancel() - } - - HelperWidgets.Button { - id: applyButton - text: qsTr("Ok") - leftPadding: StudioTheme.Values.dialogButtonPadding - rightPadding: StudioTheme.Values.dialogButtonPadding - onClicked: { - rootView.apply() - rootView.cancel() - } - } - } + HelperWidgets.Button { + text: qsTr("Reset All") + Layout.bottomMargin: 8 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + onClicked: rootView.resetDefaults() } } } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 4890c031a25..588aad00c1d 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -200,16 +200,7 @@ void Edit3DView::modelAttached(Model *model) { AbstractView::modelAttached(model); - rootModelNode().setAuxiliaryData(edit3dSnapPosProperty, m_snapPositionAction->action()->isChecked()); - rootModelNode().setAuxiliaryData(edit3dSnapRotProperty, m_snapRotationAction->action()->isChecked()); - rootModelNode().setAuxiliaryData(edit3dSnapScaleProperty, m_snapScaleAction->action()->isChecked()); - rootModelNode().setAuxiliaryData(edit3dSnapAbsProperty, m_snapAbsoluteAction->action()->isChecked()); - rootModelNode().setAuxiliaryData(edit3dSnapPosIntProperty, - Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL)); - rootModelNode().setAuxiliaryData(edit3dSnapRotIntProperty, - Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL)); - rootModelNode().setAuxiliaryData(edit3dSnapScaleIntProperty, - Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL)); + syncSnapAuxPropsToSettings(); checkImports(); auto cachedImage = m_canvasCache.take(model); @@ -551,7 +542,32 @@ void Edit3DView::createSeekerSliderAction() &SeekerSliderAction::valueChanged, this, [=] (int value) { this->emitView3DAction(View3DActionType::ParticlesSeek, value); - }); + }); +} + +void Edit3DView::syncSnapAuxPropsToSettings() +{ + if (!model()) + return; + + bool snapToggle = m_snapToggleAction->action()->isChecked(); + rootModelNode().setAuxiliaryData(edit3dSnapPosProperty, + snapToggle ? Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION) + : false); + rootModelNode().setAuxiliaryData(edit3dSnapRotProperty, + snapToggle ? Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION) + : false); + rootModelNode().setAuxiliaryData(edit3dSnapScaleProperty, + snapToggle ? Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE) + : false); + rootModelNode().setAuxiliaryData(edit3dSnapAbsProperty, + Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ABSOLUTE)); + rootModelNode().setAuxiliaryData(edit3dSnapPosIntProperty, + Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL)); + rootModelNode().setAuxiliaryData(edit3dSnapRotIntProperty, + Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL)); + rootModelNode().setAuxiliaryData(edit3dSnapScaleIntProperty, + Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL)); } void Edit3DView::createEdit3DActions() @@ -887,37 +903,32 @@ void Edit3DView::createEdit3DActions() this, bakeLightsTrigger); - SelectionContextOperation snapMenuTrigger = [this](const SelectionContext &) { - if (!edit3DWidget()->snapMenu()) - return; + SelectionContextOperation snapToggleTrigger = [this](const SelectionContext &) { + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_ENABLED, + m_snapToggleAction->action()->isChecked()); + syncSnapAuxPropsToSettings(); + }; + m_snapToggleAction = std::make_unique( + QmlDesigner::Constants::EDIT3D_SNAP_TOGGLE, + View3DActionType::Empty, + QCoreApplication::translate("SnapToggleAction", "Toggle snapping during node drag"), + QKeySequence(Qt::SHIFT | Qt::Key_Tab), + true, + Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ENABLED, false).toBool(), + toolbarIcon(DesignerIcons::SnappingIcon), + this, + snapToggleTrigger); + + SelectionContextOperation snapConfigTrigger = [this](const SelectionContext &) { QPoint pos; - const auto &actionWidgets = m_snapMenuAction->action()->associatedWidgets(); + const auto &actionWidgets = m_snapConfigAction->action()->associatedWidgets(); for (auto actionWidget : actionWidgets) { if (auto button = qobject_cast(actionWidget)) { pos = button->mapToGlobal(QPoint(0, 0)); break; } } - - edit3DWidget()->showSnapMenu(!edit3DWidget()->snapMenu()->isVisible(), pos); - }; - - m_snapMenuAction = std::make_unique( - QmlDesigner::Constants::EDIT3D_SNAP_MENU, - View3DActionType::Empty, - QCoreApplication::translate("Snapping", "Snapping"), - QKeySequence(), - false, - false, - toolbarIcon(DesignerIcons::SnappingIcon), - this, - snapMenuTrigger); - - SelectionContextOperation snapConfigTrigger = [this](const SelectionContext &) { - QPoint pos; - pos = m_edit3DWidget->mapToGlobal(QPoint(m_edit3DWidget->width() / 2, - m_edit3DWidget->height() / 2)); if (!m_snapConfiguration) m_snapConfiguration = new SnapConfiguration(this); m_snapConfiguration->showConfigDialog(pos); @@ -926,82 +937,13 @@ void Edit3DView::createEdit3DActions() m_snapConfigAction = std::make_unique( QmlDesigner::Constants::EDIT3D_SNAP_CONFIG, View3DActionType::Empty, - QCoreApplication::translate("SnapConfigAction", "Snap Configuration"), + QCoreApplication::translate("SnapConfigAction", "Open snap configuration dialog"), QKeySequence(), false, false, - toolbarIcon(DesignerIcons::SnappingIcon), + toolbarIcon(DesignerIcons::SnappingConfIcon), this, - snapConfigTrigger, - QCoreApplication::translate("SnapConfigAction", "Open snap configuration dialog.")); - - SelectionContextOperation snapPositionTrigger = [this](const SelectionContext &) { - if (model()) - rootModelNode().setAuxiliaryData(edit3dSnapPosProperty, m_snapPositionAction->action()->isChecked()); - }; - - m_snapPositionAction = std::make_unique( - QmlDesigner::Constants::EDIT3D_SNAP_POSITION, - View3DActionType::Empty, - QCoreApplication::translate("SnapPositionAction", "Snap Position"), - QKeySequence(Qt::SHIFT | Qt::Key_W), - true, - Edit3DViewConfig::load(settingKeyForAction(QmlDesigner::Constants::EDIT3D_SNAP_POSITION), false).toBool(), - QIcon(), - this, - snapPositionTrigger, - QCoreApplication::translate("SnapPositionAction", "Toggle position snapping during node drag.")); - - SelectionContextOperation snapRotationTrigger = [this](const SelectionContext &) { - if (model()) - rootModelNode().setAuxiliaryData(edit3dSnapRotProperty, m_snapRotationAction->action()->isChecked()); - }; - - m_snapRotationAction = std::make_unique( - QmlDesigner::Constants::EDIT3D_SNAP_ROTATION, - View3DActionType::Empty, - QCoreApplication::translate("SnapRotationAction", "Snap Rotation"), - QKeySequence(Qt::SHIFT | Qt::Key_E), - true, - Edit3DViewConfig::load(settingKeyForAction(QmlDesigner::Constants::EDIT3D_SNAP_ROTATION), false).toBool(), - QIcon(), - this, - snapRotationTrigger, - QCoreApplication::translate("SnapRotationAction", "Toggle rotation snapping during node drag.")); - - SelectionContextOperation snapScaleTrigger = [this](const SelectionContext &) { - if (model()) - rootModelNode().setAuxiliaryData(edit3dSnapScaleProperty, m_snapScaleAction->action()->isChecked()); - }; - - m_snapScaleAction = std::make_unique( - QmlDesigner::Constants::EDIT3D_SNAP_SCALE, - View3DActionType::Empty, - QCoreApplication::translate("SnapScaleAction", "Snap Scale"), - QKeySequence(Qt::SHIFT | Qt::Key_R), - true, - Edit3DViewConfig::load(settingKeyForAction(QmlDesigner::Constants::EDIT3D_SNAP_SCALE), false).toBool(), - QIcon(), - this, - snapScaleTrigger, - QCoreApplication::translate("SnapScaleAction", "Toggle scale snapping during node drag.")); - - SelectionContextOperation snapAbsoluteTrigger = [this](const SelectionContext &) { - if (model()) - rootModelNode().setAuxiliaryData(edit3dSnapAbsProperty, m_snapAbsoluteAction->action()->isChecked()); - }; - - m_snapAbsoluteAction = std::make_unique( - QmlDesigner::Constants::EDIT3D_SNAP_ABSOLUTE, - View3DActionType::Empty, - QCoreApplication::translate("SnapAbsoluteAction", "Absolute Position Snap"), - QKeySequence(Qt::SHIFT | Qt::Key_A), - true, - Edit3DViewConfig::load(settingKeyForAction(QmlDesigner::Constants::EDIT3D_SNAP_ABSOLUTE), true).toBool(), - QIcon(), - this, - snapAbsoluteTrigger, - QCoreApplication::translate("SnapAbsoluteAction", "If enabled, position snapping uses scene origin as origin point.\nOtherwise snapping uses drag start point as origin point.")); + snapConfigTrigger); m_leftActions << m_selectionModeAction.get(); m_leftActions << nullptr; // Null indicates separator @@ -1016,12 +958,14 @@ void Edit3DView::createEdit3DActions() m_leftActions << m_orientationModeAction.get(); m_leftActions << m_editLightAction.get(); m_leftActions << nullptr; + m_leftActions << m_snapToggleAction.get(); + m_leftActions << m_snapConfigAction.get(); + m_leftActions << nullptr; m_leftActions << m_alignCamerasAction.get(); m_leftActions << m_alignViewAction.get(); m_leftActions << nullptr; m_leftActions << m_visibilityTogglesAction.get(); m_leftActions << m_backgrondColorMenuAction.get(); - m_leftActions << m_snapMenuAction.get(); m_rightActions << m_particleViewModeAction.get(); m_rightActions << m_particlesPlayAction.get(); @@ -1047,12 +991,6 @@ void Edit3DView::createEdit3DActions() m_backgroundColorActions << m_selectGridColorAction.get(); m_backgroundColorActions << m_syncBackgroundColorAction.get(); m_backgroundColorActions << m_resetColorAction.get(); - - m_snapActions << m_snapConfigAction.get(); - m_snapActions << m_snapPositionAction.get(); - m_snapActions << m_snapRotationAction.get(); - m_snapActions << m_snapScaleAction.get(); - m_snapActions << m_snapAbsoluteAction.get(); } QVector Edit3DView::leftActions() const @@ -1075,10 +1013,6 @@ QVector Edit3DView::backgroundColorActions() const return m_backgroundColorActions; } -QVector Edit3DView::snapActions() const -{ - return m_snapActions; -} Edit3DAction *Edit3DView::edit3DAction(View3DActionType type) const { @@ -1161,17 +1095,4 @@ bool Edit3DView::isBakingLightsSupported() const return m_isBakingLightsSupported; } -const char *Edit3DView::settingKeyForAction(const QByteArray &actionId) -{ - if (actionId == Constants::EDIT3D_SNAP_POSITION) - return DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION; - if (actionId == Constants::EDIT3D_SNAP_ROTATION) - return DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION; - if (actionId == Constants::EDIT3D_SNAP_SCALE) - return DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE; - if (actionId == Constants::EDIT3D_SNAP_ABSOLUTE) - return DesignerSettingsKey::EDIT3DVIEW_SNAP_ABSOLUTE; - return ""; -} - } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 65fcdf4b0ce..aa3f482dac5 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -62,7 +62,6 @@ public: QVector rightActions() const; QVector visibilityToggleActions() const; QVector backgroundColorActions() const; - QVector snapActions() const; Edit3DAction *edit3DAction(View3DActionType type) const; Edit3DBakeLightsAction *bakeLightsAction() const; @@ -77,7 +76,7 @@ public: bool isBakingLightsSupported() const; - const char *settingKeyForAction(const QByteArray &actionId); + void syncSnapAuxPropsToSettings(); private slots: void onEntriesChanged(); @@ -113,7 +112,6 @@ private: QVector m_rightActions; QVector m_visibilityToggleActions; QVector m_backgroundColorActions; - QVector m_snapActions; QMap m_edit3DActions; std::unique_ptr m_selectionModeAction; @@ -144,12 +142,8 @@ private: std::unique_ptr m_resetAction; std::unique_ptr m_visibilityTogglesAction; std::unique_ptr m_backgrondColorMenuAction; - std::unique_ptr m_snapMenuAction; + std::unique_ptr m_snapToggleAction; std::unique_ptr m_snapConfigAction; - std::unique_ptr m_snapPositionAction; - std::unique_ptr m_snapRotationAction; - std::unique_ptr m_snapScaleAction; - std::unique_ptr m_snapAbsoluteAction; std::unique_ptr m_bakeLightsAction; int particlemode; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index ee5800641d4..8c3d54bb4f2 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -166,19 +166,6 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) handleActions(view->backgroundColorActions(), m_backgroundColorMenu, false); - m_snapMenu = new Edit3DToolbarMenu(this); - handleActions(view->snapActions(), m_snapMenu, false); - connect(m_snapMenu, &QMenu::aboutToHide, this, [view]() { - // Persist the checkable settings of the menu - const auto actions = view->snapActions(); - for (auto &action : actions) { - if (action->action()->isCheckable()) { - Edit3DViewConfig::save(view->settingKeyForAction(action->menuId()), - action->action()->isChecked()); - } - } - }); - createContextMenu(); m_mcuLabel = new QLabel(this); @@ -467,21 +454,6 @@ void Edit3DWidget::showVisibilityTogglesMenu(bool show, const QPoint &pos) m_visibilityTogglesMenu->close(); } -QMenu *Edit3DWidget::snapMenu() const -{ - return m_snapMenu.data(); -} - -void Edit3DWidget::showSnapMenu(bool show, const QPoint &pos) -{ - if (m_snapMenu.isNull()) - return; - if (show) - m_snapMenu->popup(pos); - else - m_snapMenu->close(); -} - QMenu *Edit3DWidget::backgroundColorMenu() const { return m_backgroundColorMenu.data(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 1e60c75f88a..f764f068bf4 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -45,8 +45,6 @@ public: void showCanvas(bool show); QMenu *visibilityTogglesMenu() const; void showVisibilityTogglesMenu(bool show, const QPoint &pos); - QMenu *snapMenu() const; - void showSnapMenu(bool show, const QPoint &pos); QMenu *backgroundColorMenu() const; void showBackgroundColorMenu(bool show, const QPoint &pos); @@ -78,7 +76,6 @@ private: QPointer m_visibilityTogglesMenu; QPointer m_backgroundColorMenu; QPointer m_contextMenu; - QPointer m_snapMenu; QPointer m_bakeLightsAction; QPointer m_editComponentAction; QPointer m_editMaterialAction; diff --git a/src/plugins/qmldesigner/components/edit3d/snapconfiguration.cpp b/src/plugins/qmldesigner/components/edit3d/snapconfiguration.cpp index 0f524e88071..44fb7ef1322 100644 --- a/src/plugins/qmldesigner/components/edit3d/snapconfiguration.cpp +++ b/src/plugins/qmldesigner/components/edit3d/snapconfiguration.cpp @@ -3,10 +3,9 @@ #include "snapconfiguration.h" -#include "abstractview.h" #include "designersettings.h" +#include "edit3dview.h" #include "edit3dviewconfig.h" -#include "modelnode.h" #include @@ -39,7 +38,7 @@ static QString qmlSourcesPath() return Core::ICore::resourcePath("qmldesigner/edit3dQmlSource").toString(); } -SnapConfiguration::SnapConfiguration(AbstractView *view) +SnapConfiguration::SnapConfiguration(Edit3DView *view) : QObject(view) , m_view(view) { @@ -52,40 +51,70 @@ SnapConfiguration::~SnapConfiguration() void SnapConfiguration::apply() { - Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL, - m_positionInterval); - Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, - m_rotationInterval); - Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL, - m_scaleInterval); - m_view->rootModelNode().setAuxiliaryData(edit3dSnapPosIntProperty, m_positionInterval); - m_view->rootModelNode().setAuxiliaryData(edit3dSnapRotIntProperty, m_rotationInterval); - m_view->rootModelNode().setAuxiliaryData(edit3dSnapScaleIntProperty, m_scaleInterval); + if (m_changes) { + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION, + m_positionEnabled); + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION, + m_rotationEnabled); + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE, + m_scaleEnabled); + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_ABSOLUTE, + m_absolute); + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL, + m_positionInterval); + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, + m_rotationInterval); + Edit3DViewConfig::save(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL, + m_scaleInterval); + m_view->syncSnapAuxPropsToSettings(); + } + + cancel(); +} + +void SnapConfiguration::resetDefaults() +{ + setPosEnabled(true); + setRotEnabled(true); + setScaleEnabled(true); + setAbsolute(true); + setPosInt(defaultPosInt); + setRotInt(defaultRotInt); + setScaleInt(defaultScaleInt); } void SnapConfiguration::showConfigDialog(const QPoint &pos) { + bool posEnabled = Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION, true).toBool(); + bool rotEnabled = Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION, true).toBool(); + bool scaleEnabled = Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE, true).toBool(); + bool absolute = Edit3DViewConfig::load(DesignerSettingsKey::EDIT3DVIEW_SNAP_ABSOLUTE, true).toBool(); double posInt = Edit3DViewConfig::load( - DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL, 10.).toDouble(); + DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL, defaultPosInt).toDouble(); double rotInt = Edit3DViewConfig::load( - DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, 15.).toDouble(); + DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, defaultRotInt).toDouble(); double scaleInt = Edit3DViewConfig::load( - DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL, 10.).toDouble(); + DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL, defaultScaleInt).toDouble(); + + setPosEnabled(posEnabled); + setRotEnabled(rotEnabled); + setScaleEnabled(scaleEnabled); + setAbsolute(absolute); setPosInt(posInt); setRotInt(rotInt); setScaleInt(scaleInt); + m_changes = false; + if (!m_configDialog) { // Show non-modal progress dialog with cancel button QString path = qmlSourcesPath() + "/SnapConfigurationDialog.qml"; m_configDialog = new QQuickView; - m_configDialog->setTitle(tr("3D Snap Configuration")); - m_configDialog->setResizeMode(QQuickView::SizeRootObjectToView); - m_configDialog->setFlags(Qt::Dialog); - m_configDialog->setModality(Qt::ApplicationModal); + m_configDialog->setResizeMode(QQuickView::SizeViewToRootObject); + m_configDialog->setFlags(Qt::Dialog | Qt::FramelessWindowHint); + m_configDialog->setModality(Qt::NonModal); m_configDialog->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); - m_configDialog->setMinimumSize({280, 170}); m_configDialog->rootContext()->setContextProperties({ {"rootView", QVariant::fromValue(this)} @@ -95,17 +124,54 @@ void SnapConfiguration::showConfigDialog(const QPoint &pos) QPoint finalPos = pos; finalPos.setX(pos.x() - m_configDialog->size().width() / 2); - finalPos.setY(pos.y() - m_configDialog->size().height() / 2); + finalPos.setY(pos.y()); m_configDialog->setPosition(finalPos); } m_configDialog->show(); } +void SnapConfiguration::setPosEnabled(bool enabled) +{ + if (enabled != m_positionEnabled) { + m_positionEnabled = enabled; + m_changes = true; + emit posEnabledChanged(); + } +} + +void SnapConfiguration::setRotEnabled(bool enabled) +{ + if (enabled != m_rotationEnabled) { + m_rotationEnabled = enabled; + m_changes = true; + emit rotEnabledChanged(); + } +} + +void SnapConfiguration::setScaleEnabled(bool enabled) +{ + if (enabled != m_scaleEnabled) { + m_scaleEnabled = enabled; + m_changes = true; + emit scaleEnabledChanged(); + } +} + +void SnapConfiguration::setAbsolute(bool enabled) +{ + if (enabled != m_absolute) { + m_absolute = enabled; + m_changes = true; + emit absoluteChanged(); + } +} + void SnapConfiguration::setPosInt(double value) { if (value != m_positionInterval) { m_positionInterval = value; + m_changes = true; emit posIntChanged(); } } @@ -114,6 +180,7 @@ void SnapConfiguration::setRotInt(double value) { if (value != m_rotationInterval) { m_rotationInterval = value; + m_changes = true; emit rotIntChanged(); } } @@ -122,6 +189,7 @@ void SnapConfiguration::setScaleInt(double value) { if (value != m_scaleInterval) { m_scaleInterval = value; + m_changes = true; emit scaleIntChanged(); } } @@ -141,20 +209,17 @@ void SnapConfiguration::cancel() bool SnapConfiguration::eventFilter(QObject *obj, QEvent *event) { + // Closing dialog always applies the changes + if (obj == m_configDialog) { - if (event->type() == QEvent::KeyPress) { + if (event->type() == QEvent::FocusOut) { + apply(); + } else if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Escape) - cancel(); - if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { - // Apply asynchronously to allow the final value to be set by dialog before apply - QTimer::singleShot(0, this, [this]() { - apply(); - cancel(); - }); - } + apply(); } else if (event->type() == QEvent::Close) { - cancel(); + apply(); } } diff --git a/src/plugins/qmldesigner/components/edit3d/snapconfiguration.h b/src/plugins/qmldesigner/components/edit3d/snapconfiguration.h index e41dc7e75af..ae1a4a0d93b 100644 --- a/src/plugins/qmldesigner/components/edit3d/snapconfiguration.h +++ b/src/plugins/qmldesigner/components/edit3d/snapconfiguration.h @@ -14,7 +14,7 @@ QT_END_NAMESPACE namespace QmlDesigner { -class AbstractView; +class Edit3DView; inline constexpr AuxiliaryDataKeyView edit3dSnapPosProperty{AuxiliaryDataType::NodeInstanceAuxiliary, "snapPos3d"}; @@ -34,19 +34,34 @@ inline constexpr AuxiliaryDataKeyView edit3dSnapScaleIntProperty{AuxiliaryDataTy class SnapConfiguration : public QObject { Q_OBJECT + Q_PROPERTY(bool posEnabled READ posEnabled WRITE setPosEnabled NOTIFY posEnabledChanged) + Q_PROPERTY(bool rotEnabled READ rotEnabled WRITE setRotEnabled NOTIFY rotEnabledChanged) + Q_PROPERTY(bool scaleEnabled READ scaleEnabled WRITE setScaleEnabled NOTIFY scaleEnabledChanged) + Q_PROPERTY(bool absolute READ absolute WRITE setAbsolute NOTIFY absoluteChanged) Q_PROPERTY(double posInt READ posInt WRITE setPosInt NOTIFY posIntChanged) Q_PROPERTY(double rotInt READ rotInt WRITE setRotInt NOTIFY rotIntChanged) Q_PROPERTY(double scaleInt READ scaleInt WRITE setScaleInt NOTIFY scaleIntChanged) public: - SnapConfiguration(AbstractView *view); + SnapConfiguration(Edit3DView *view); ~SnapConfiguration(); - Q_INVOKABLE void cancel(); - Q_INVOKABLE void apply(); + Q_INVOKABLE void resetDefaults(); + + void cancel(); + void apply(); void showConfigDialog(const QPoint &pos); + void setPosEnabled(bool enabled); + bool posEnabled() const { return m_positionEnabled; } + void setRotEnabled(bool enabled); + bool rotEnabled() const { return m_rotationEnabled; } + void setScaleEnabled(bool enabled); + bool scaleEnabled() const { return m_scaleEnabled; } + void setAbsolute(bool enabled); + bool absolute() const { return m_absolute; } + void setPosInt(double value); double posInt() const { return m_positionInterval; } void setRotInt(double value); @@ -54,7 +69,15 @@ public: void setScaleInt(double value); double scaleInt() const { return m_scaleInterval; } + constexpr static double defaultPosInt = 50.; + constexpr static double defaultRotInt = 5.; + constexpr static double defaultScaleInt = 10.; + signals: + void posEnabledChanged(); + void rotEnabledChanged(); + void scaleEnabledChanged(); + void absoluteChanged(); void posIntChanged(); void rotIntChanged(); void scaleIntChanged(); @@ -66,10 +89,15 @@ private: void cleanup(); QPointer m_configDialog; - QPointer m_view; - double m_positionInterval = 10.; - double m_rotationInterval = 15.; - double m_scaleInterval = 10.; + QPointer m_view; + bool m_positionEnabled = true; + bool m_rotationEnabled = true; + bool m_scaleEnabled = true; + bool m_absolute = true; + double m_positionInterval = 0.; + double m_rotationInterval = 0.; + double m_scaleInterval = 0.; + bool m_changes = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 75938f1aa7c..3a2d591a1bf 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -64,12 +64,8 @@ const char EDIT3D_PARTICLES_RESTART[] = "QmlDesigner.Editor3D.ParticlesRestart"; const char EDIT3D_VISIBILITY_TOGGLES[] = "QmlDesigner.Editor3D.VisibilityToggles"; const char EDIT3D_BACKGROUND_COLOR_ACTIONS[] = "QmlDesigner.Editor3D.BackgroundColorActions"; const char EDIT3D_BAKE_LIGHTS[] = "QmlDesigner.Editor3D.BakeLights"; -const char EDIT3D_SNAP_MENU[] = "QmlDesigner.Editor3D.SnapMenu"; -const char EDIT3D_SNAP_POSITION[] = "QmlDesigner.Editor3D.SnapPosition"; -const char EDIT3D_SNAP_ROTATION[] = "QmlDesigner.Editor3D.SnapRotation"; -const char EDIT3D_SNAP_SCALE[] = "QmlDesigner.Editor3D.SnapScale"; +const char EDIT3D_SNAP_TOGGLE[] = "QmlDesigner.Editor3D.SnapToggle"; const char EDIT3D_SNAP_CONFIG[] = "QmlDesigner.Editor3D.SnapConfig"; -const char EDIT3D_SNAP_ABSOLUTE[] = "QmlDesigner.Editor3D.SnapToGrid"; const char QML_DESIGNER_SUBFOLDER[] = "/designer/"; const char COMPONENT_BUNDLES_FOLDER[] = "/ComponentBundles"; diff --git a/src/plugins/qmldesignerbase/utils/designersettings.cpp b/src/plugins/qmldesignerbase/utils/designersettings.cpp index a19bb310a6f..b75575c6236 100644 --- a/src/plugins/qmldesignerbase/utils/designersettings.cpp +++ b/src/plugins/qmldesignerbase/utils/designersettings.cpp @@ -84,11 +84,12 @@ void DesignerSettings::fromSettings(QSettings *settings) QStringList{"#222222", "#999999"}); restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_GRID_COLOR, "#aaaaaa"); restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ABSOLUTE, true); - restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION, false); - restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL, 10.); - restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION, false); - restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, 15.); - restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE, false); + restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ENABLED, false); + restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION, true); + restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_POSITION_INTERVAL, 50.); + restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION, true); + restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_ROTATION_INTERVAL, 5.); + restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE, true); restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_SNAP_SCALE_INTERVAL, 10.); restoreValue(settings, DesignerSettingsKey::SMOOTH_RENDERING, false); restoreValue(settings, DesignerSettingsKey::SHOW_DEBUG_SETTINGS, false); diff --git a/src/plugins/qmldesignerbase/utils/designersettings.h b/src/plugins/qmldesignerbase/utils/designersettings.h index aa0b8b4b138..850e2a43a06 100644 --- a/src/plugins/qmldesignerbase/utils/designersettings.h +++ b/src/plugins/qmldesignerbase/utils/designersettings.h @@ -33,6 +33,7 @@ inline constexpr char ENABLE_DEBUGVIEW[] = "EnableQtQuickDesignerDebugView"; inline constexpr char EDIT3DVIEW_BACKGROUND_COLOR[] = "Edit3DViewBackgroundColor"; inline constexpr char EDIT3DVIEW_GRID_COLOR[] = "Edit3DViewGridLineColor"; inline constexpr char EDIT3DVIEW_SNAP_ABSOLUTE[] = "Edit3DViewSnapAbsolute"; +inline constexpr char EDIT3DVIEW_SNAP_ENABLED[] = "Edit3DViewSnapEnabled"; inline constexpr char EDIT3DVIEW_SNAP_POSITION[] = "Edit3DViewSnapPosition"; inline constexpr char EDIT3DVIEW_SNAP_POSITION_INTERVAL[] = "Edit3DViewSnapPositionInterval"; inline constexpr char EDIT3DVIEW_SNAP_ROTATION[] = "Edit3DViewSnapRotation"; diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h index c9c960950cf..70605345c0c 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h @@ -156,8 +156,8 @@ private: bool m_snapPosition = false; bool m_snapRotation = false; bool m_snapScale = false; - double m_snapPositionInterval = 10.; - double m_snapRotationInterval = 15.; + double m_snapPositionInterval = 50.; + double m_snapRotationInterval = 5.; double m_snapScaleInterval = .1; };