Merge pull request #24751 from tetektoza/fix/24009_clarify_selection_LMB_activated_by_accident

Gui: Add additional handling for Clarify Selection's long press
This commit is contained in:
Kacper Donat
2025-10-20 23:22:17 +02:00
committed by GitHub
5 changed files with 175 additions and 6 deletions

View File

@@ -42,6 +42,7 @@ public:
GestureNavigationStyle();
~GestureNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
ClarifySelectionMode clarifySelectionMode() const override { return ClarifySelectionMode::Ctrl; }
protected:
SbBool processSoEvent(const SoEvent* const ev) override;

View File

@@ -105,6 +105,11 @@ public:
Clip = 4, /**< Clip objects using a lasso. */
};
enum class ClarifySelectionMode {
Default, /**< Long press with LMB to trigger clarify selection */
Ctrl /**< Long press with Ctrl+LMB to trigger clarify selection */
};
enum OrbitStyle {
Turntable,
Trackball,
@@ -192,6 +197,8 @@ public:
bool isDraggerUnderCursor(const SbVec2s pos) const;
virtual ClarifySelectionMode clarifySelectionMode() const { return ClarifySelectionMode::Default; }
void setOrbitStyle(OrbitStyle style);
OrbitStyle getOrbitStyle() const;
@@ -353,6 +360,7 @@ public:
~InventorNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
std::string userFriendlyName() const override;
ClarifySelectionMode clarifySelectionMode() const override { return ClarifySelectionMode::Ctrl; }
protected:
SbBool processSoEvent(const SoEvent * const ev) override;
@@ -492,6 +500,7 @@ public:
OpenSCADNavigationStyle();
~OpenSCADNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
ClarifySelectionMode clarifySelectionMode() const override { return ClarifySelectionMode::Ctrl; }
protected:
SbBool processSoEvent(const SoEvent * const ev) override;

View File

@@ -94,6 +94,8 @@ void DlgSettingsNavigation::saveSettings()
ui->spinBoxZoomStep->onSave();
ui->spinBoxAnimationDuration->onSave();
ui->checkBoxSpinningAnimations->onSave();
ui->checkBoxEnableLongPressClarifySelection->onSave();
ui->spinBoxLongPressTimeout->onSave();
ui->qspinNewDocScale->onSave();
ui->prefStepByTurn->onSave();
ui->naviCubeCorner->onSave();
@@ -144,6 +146,8 @@ void DlgSettingsNavigation::loadSettings()
ui->spinBoxZoomStep->onRestore();
ui->spinBoxAnimationDuration->onRestore();
ui->checkBoxSpinningAnimations->onRestore();
ui->checkBoxEnableLongPressClarifySelection->onRestore();
ui->spinBoxLongPressTimeout->onRestore();
ui->qspinNewDocScale->onRestore();
ui->prefStepByTurn->onRestore();
ui->naviCubeCorner->onRestore();

View File

@@ -850,6 +850,99 @@ Mouse tilting is not disabled by this setting.</string>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxClarifySelection">
<property name="title">
<string>Clarify Selection</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkBoxEnableLongPressClarifySelection">
<property name="toolTip">
<string>Enable Clarify Selection on long press of left mouse button.
When enabled, holding left mouse button shows a menu to select overlapping objects.
Some navigation styles (OpenInventor, Gesture, OpenSCAD) require Ctrl+LMB instead of just LMB.</string>
</property>
<property name="text">
<string>Enable long press clarify selection</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>EnableLongPressClarifySelection</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelLongPressTimeout">
<property name="toolTip">
<string>Time in seconds to hold left mouse button before showing clarify selection menu</string>
</property>
<property name="text">
<string>Long press timeout</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefDoubleSpinBox" name="spinBoxLongPressTimeout">
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Duration in seconds to hold left mouse button before clarify selection is triggered</string>
</property>
<property name="suffix">
<string notr="true"> s</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.300000000000000</double>
</property>
<property name="maximum">
<double>3.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
<property name="prefEntry" stdset="0">
<cstring>LongPressTimeout</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
@@ -908,5 +1001,38 @@ Mouse tilting is not disabled by this setting.</string>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<connections>
<connection>
<sender>checkBoxEnableLongPressClarifySelection</sender>
<signal>toggled(bool)</signal>
<receiver>spinBoxLongPressTimeout</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>274</x>
<y>867</y>
</hint>
<hint type="destinationlabel">
<x>274</x>
<y>897</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBoxEnableLongPressClarifySelection</sender>
<signal>toggled(bool)</signal>
<receiver>labelLongPressTimeout</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>274</x>
<y>867</y>
</hint>
<hint type="destinationlabel">
<x>100</x>
<y>897</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -115,6 +115,8 @@
#include "Multisample.h"
#include "NaviCube.h"
#include "Navigation/NavigationStyle.h"
#include "Navigation/GestureNavigationStyle.h"
#include "Navigation/SiemensNXNavigationStyle.h"
#include "Selection.h"
#include "SoDevicePixelRatioElement.h"
#include "SoFCDB.h"
@@ -171,6 +173,30 @@ private:
Gui::Command::runCommand(Gui::Command::Gui, "Gui.runCommand('Std_ClarifySelection')");
}
bool shouldEnableLongPress(View3DInventorViewer* viewer, const QPoint& pos, bool ctrlPressed) const {
bool enabled = App::GetApplication()
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/View")
->GetBool("EnableLongPressClarifySelection", true);
if (!enabled) {
return false;
}
// check edit mode and view provider editing (for example transform manipulator)
if (viewer->isEditing() || viewer->isEditingViewProvider()) {
return false;
}
if (auto* navStyle = viewer->navigationStyle()) {
// reject if navigation style requires ctrl and it's not pressed or we're under a dragger
if ((navStyle->clarifySelectionMode() == NavigationStyle::ClarifySelectionMode::Ctrl && !ctrlPressed) ||
navStyle->isDraggerUnderCursor(SbVec2s(pos.x(), pos.y()))) {
return false;
}
}
return true;
}
QTimer* longPressTimer;
QPoint pressPosition;
View3DInventorViewer* currentViewer = nullptr;
@@ -223,12 +249,15 @@ public:
if (mouseEvent->button() == Qt::LeftButton) {
currentViewer = static_cast<View3DInventorViewer*>(obj);
pressPosition = mouseEvent->pos();
bool ctrlPressed = (mouseEvent->modifiers() & Qt::ControlModifier) != 0;
int longPressTimeout = App::GetApplication()
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/View")
->GetInt("LongPressTimeout", 1000);
longPressTimer->setInterval(longPressTimeout);
longPressTimer->start();
if (shouldEnableLongPress(currentViewer, pressPosition, ctrlPressed)) {
double longPressTimeout = App::GetApplication()
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/View")
->GetFloat("LongPressTimeout", 1.0);
longPressTimer->setInterval(static_cast<int>(longPressTimeout * 1000));
longPressTimer->start();
}
}
}
else if (event->type() == QEvent::MouseButtonRelease) {