Skip to content

Commit 58c9ac5

Browse files
authored
Suppress context menu for common actions (#162)
1 parent 8a8630b commit 58c9ac5

16 files changed

+120
-92
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
> - Breaking Changes:
66
> - Made the setter of NodifyEditor.IsPanning private
77
> - Made SelectionHelper internal
8+
> - Renamed HandleRightClickAfterPanningThreshold to MouseActionSuppressionThreshold in NodifyEditor
89
> - Renamed StartCutting to BeginCutting in NodifyEditor
910
> - Renamed PushItems to UpdatePushedArea and StartPushingItems to BeginPushingItems in NodifyEditor
1011
> - Renamed UnselectAllConnection to UnselectAllConnections in NodifyEditor
@@ -15,8 +16,10 @@
1516
> - Added BeginSelecting, UpdateSelection, EndSelecting, CancelSelecting and AllowSelectionCancellation to NodifyEditor
1617
> - Added IsDragging, BeginDragging, UpdateDragging, EndDragging and CancelDragging to NodifyEditor
1718
> - Added Select, BeginDragging, UpdateDragging, EndDragging and CancelDragging to ItemContainer
19+
> - Added PreserveSelectionOnRightClick configuration field to ItemContainer
1820
> - Bugfixes:
19-
> - Fixed ItemContainer being selected by releasing the mouse button on it without having the mouse captured
21+
> - Fixed an issue where the ItemContainer was selected by releasing the mouse button on it, even when the mouse was not captured
22+
> - Fixed an issue where the Home button caused the editor to fail to display items when contained within a ScrollViewer
2023
2124
#### **Version 6.6.0**
2225

Examples/Nodify.Playground/EditorSettings.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,10 @@ private EditorSettings()
211211
_advancedSettings = new List<ISettingViewModel>()
212212
{
213213
new ProxySettingViewModel<double>(
214-
() => Instance.HandleRightClickAfterPanningThreshold,
215-
val => Instance.HandleRightClickAfterPanningThreshold = val,
216-
"Disable context menu after panning: ",
217-
"Disable after mouse moved this far"),
214+
() => Instance.MouseActionSuppressionThreshold,
215+
val => Instance.MouseActionSuppressionThreshold = val,
216+
"Context menu suppression threshold: ",
217+
"Disable context menu after mouse moved this far"),
218218
new ProxySettingViewModel<double>(
219219
() => Instance.AutoPanningTickRate,
220220
val => Instance.AutoPanningTickRate = val,
@@ -585,10 +585,10 @@ public GroupingMovementMode GroupingNodeMovement
585585

586586
#region Advanced settings
587587

588-
public double HandleRightClickAfterPanningThreshold
588+
public double MouseActionSuppressionThreshold
589589
{
590-
get => NodifyEditor.HandleRightClickAfterPanningThreshold;
591-
set => NodifyEditor.HandleRightClickAfterPanningThreshold = value;
590+
get => NodifyEditor.MouseActionSuppressionThreshold;
591+
set => NodifyEditor.MouseActionSuppressionThreshold = value;
592592
}
593593

594594
public double AutoPanningTickRate

Examples/Nodify.StateMachine/Helpers/BlackboardDescriptor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public static List<BlackboardItemReferenceViewModel> GetAvailableItems<T>()
128128
for (int i = 0; i < types.Length; i++)
129129
{
130130
var type = types[i];
131-
if (type.IsClass && !type.IsAbstract && ourType.IsAssignableFrom(type))
131+
if (type.IsClass && !type.IsAbstract && ourType.IsAssignableFrom(type) && type.GetCustomAttribute<BlackboardItemAttribute>() != null)
132132
{
133133
result.Add(GetReference(type));
134134
}

Examples/Nodify.StateMachine/MainWindow.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
</Grid.ColumnDefinitions>
3333

3434
<ScrollViewer CanContentScroll="True"
35-
PreviewMouseWheel="ScrollViewer_MouseWheel"
3635
PreviewKeyDown="ScrollViewer_PreviewKeyDown"
3736
Grid.Column="1">
3837
<nodify:NodifyEditor x:Name="Editor"

Examples/Nodify.StateMachine/MainWindow.xaml.cs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,7 @@ public MainWindow()
1515

1616
EditorGestures.Mappings.Connection.Disconnect.Value = MultiGesture.None;
1717
EditorGestures.Mappings.Editor.ZoomModifierKey = ModifierKeys.Control;
18-
}
19-
20-
private void ScrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
21-
{
22-
if (Keyboard.Modifiers != ModifierKeys.Shift)
23-
return;
24-
25-
var scrollViewer = (ScrollViewer)sender;
26-
27-
if (e.Delta < 0)
28-
{
29-
scrollViewer.LineRight();
30-
}
31-
else
32-
{
33-
scrollViewer.LineLeft();
34-
}
35-
36-
e.Handled = true;
18+
EditorGestures.Mappings.Editor.PanWithMouseWheel = true;
3719
}
3820

3921
private void ScrollViewer_PreviewKeyDown(object sender, KeyEventArgs e)

Nodify/EditorStates/ContainerDefaultState.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public override void HandleMouseDown(MouseButtonEventArgs e)
4444
/// <inheritdoc />
4545
public override void HandleMouseMove(MouseEventArgs e)
4646
{
47-
double dragThreshold = NodifyEditor.HandleRightClickAfterPanningThreshold * NodifyEditor.HandleRightClickAfterPanningThreshold;
47+
double dragThreshold = NodifyEditor.MouseActionSuppressionThreshold * NodifyEditor.MouseActionSuppressionThreshold;
4848
double dragDistance = (Editor.MouseLocation - _initialPosition).LengthSquared;
4949

5050
if (_isDragging && (dragDistance > dragThreshold))
@@ -64,7 +64,13 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
6464
{
6565
if (_selectionType.HasValue)
6666
{
67-
bool allowContextMenu = e.ChangedButton == MouseButton.Right && Container.IsSelected;
67+
// Determine whether the current selection should remain intact or be replaced by the clicked item.
68+
// If the right mouse button is pressed on an already selected item, and the item either has an
69+
// explicit context menu or is configured to preserve the selection on right-click, the selection
70+
// remains unchanged. This ensures that the context menu applies to the entire selection rather
71+
// than only the clicked item.
72+
bool hasContextMenu = Container.ContextMenu != null || ItemContainer.PreserveSelectionOnRightClick;
73+
bool allowContextMenu = e.ChangedButton == MouseButton.Right && Container.IsSelected && hasContextMenu;
6874
if (!(_selectionType == SelectionType.Replace && allowContextMenu))
6975
{
7076
Container.Select(_selectionType.Value);

Nodify/EditorStates/ContainerDraggingState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
5656
if (gestures.Drag.Matches(e.Source, e))
5757
{
5858
// Suppress the context menu if the mouse moved beyond the defined drag threshold
59-
if (e.ChangedButton == MouseButton.Right)
59+
if (e.ChangedButton == MouseButton.Right && Editor.ContextMenu != null)
6060
{
61-
double dragThreshold = NodifyEditor.HandleRightClickAfterPanningThreshold * NodifyEditor.HandleRightClickAfterPanningThreshold;
61+
double dragThreshold = NodifyEditor.MouseActionSuppressionThreshold * NodifyEditor.MouseActionSuppressionThreshold;
6262
double dragDistance = (Editor.MouseLocation - _initialMousePosition).LengthSquared;
6363

6464
if (dragDistance > dragThreshold)

Nodify/EditorStates/EditorCuttingState.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
using System.Windows.Input;
1+
using System.Windows;
2+
using System.Windows.Input;
23

34
namespace Nodify
45
{
56
public class EditorCuttingState : EditorState
67
{
8+
private Point _initialPosition;
79
private bool Canceled { get; set; } = CuttingLine.AllowCuttingCancellation;
810

911
public EditorCuttingState(NodifyEditor editor) : base(editor)
@@ -14,7 +16,8 @@ public override void Enter(EditorState? from)
1416
{
1517
Canceled = false;
1618

17-
Editor.BeginCutting(Editor.MouseLocation);
19+
_initialPosition = Editor.MouseLocation;
20+
Editor.BeginCutting(_initialPosition);
1821
}
1922

2023
public override void Exit()
@@ -35,6 +38,18 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
3538
EditorGestures.NodifyEditorGestures gestures = EditorGestures.Mappings.Editor;
3639
if (gestures.Cutting.Matches(e.Source, e))
3740
{
41+
// Suppress the context menu if the mouse moved beyond the defined drag threshold
42+
if (e.ChangedButton == MouseButton.Right && Editor.ContextMenu != null)
43+
{
44+
double dragThreshold = NodifyEditor.MouseActionSuppressionThreshold * NodifyEditor.MouseActionSuppressionThreshold;
45+
double dragDistance = (Editor.MouseLocation - _initialPosition).LengthSquared;
46+
47+
if (dragDistance > dragThreshold)
48+
{
49+
e.Handled = true;
50+
}
51+
}
52+
3853
PopState();
3954
}
4055
else if (CuttingLine.AllowCuttingCancellation && gestures.CancelAction.Matches(e.Source, e))

Nodify/EditorStates/EditorDefaultState.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Windows;
1+
using System;
2+
using System.Windows;
23
using System.Windows.Input;
34

45
namespace Nodify
@@ -53,18 +54,23 @@ public override void HandleMouseDown(MouseButtonEventArgs e)
5354
public override void HandleMouseWheel(MouseWheelEventArgs e)
5455
{
5556
EditorGestures.NodifyEditorGestures gestures = EditorGestures.Mappings.Editor;
56-
if (gestures.PanWithMouseWheel)
57+
if (gestures.PanWithMouseWheel && Keyboard.Modifiers == gestures.PanHorizontalModifierKey)
5758
{
58-
if (Keyboard.Modifiers == gestures.PanHorizontalModifierKey)
59-
{
60-
Editor.ViewportLocation = new Point(Editor.ViewportLocation.X - e.Delta / Editor.ViewportZoom, Editor.ViewportLocation.Y);
61-
e.Handled = true;
62-
}
63-
else if (Keyboard.Modifiers == gestures.PanVerticalModifierKey)
64-
{
65-
Editor.ViewportLocation = new Point(Editor.ViewportLocation.X, Editor.ViewportLocation.Y - e.Delta / Editor.ViewportZoom);
66-
e.Handled = true;
67-
}
59+
double offset = Math.Sign(e.Delta) * Mouse.MouseWheelDeltaForOneLine / 2 / Editor.ViewportZoom;
60+
Editor.UpdatePanning(new Vector(offset, 0d));
61+
e.Handled = true;
62+
}
63+
else if (gestures.PanWithMouseWheel && Keyboard.Modifiers == gestures.PanVerticalModifierKey)
64+
{
65+
double offset = Math.Sign(e.Delta) * Mouse.MouseWheelDeltaForOneLine / 2 / Editor.ViewportZoom;
66+
Editor.UpdatePanning(new Vector(0d, offset));
67+
e.Handled = true;
68+
}
69+
else if (gestures.ZoomModifierKey == Keyboard.Modifiers)
70+
{
71+
double zoom = Math.Pow(2.0, e.Delta / 3.0 / Mouse.MouseWheelDeltaForOneLine);
72+
Editor.ZoomAtPosition(zoom, Editor.MouseLocation);
73+
e.Handled = true;
6874
}
6975
}
7076
}

Nodify/EditorStates/EditorPanningState.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
5858
EditorGestures.NodifyEditorGestures gestures = EditorGestures.Mappings.Editor;
5959
if (gestures.Pan.Matches(e.Source, e))
6060
{
61-
// Handle right click if panning and moved the mouse more than threshold so context menu doesn't open
62-
if (e.ChangedButton == MouseButton.Right)
61+
// Suppress the context menu if the mouse moved beyond the defined drag threshold or the editor is selecting
62+
if (e.ChangedButton == MouseButton.Right && Editor.ContextMenu != null)
6363
{
64-
double contextMenuTreshold = NodifyEditor.HandleRightClickAfterPanningThreshold * NodifyEditor.HandleRightClickAfterPanningThreshold;
65-
if ((_currentMousePosition - _initialMousePosition).LengthSquared > contextMenuTreshold)
64+
double dragThreshold = NodifyEditor.MouseActionSuppressionThreshold * NodifyEditor.MouseActionSuppressionThreshold;
65+
double dragDistance = (_currentMousePosition - _initialMousePosition).LengthSquared;
66+
67+
if (dragDistance > dragThreshold || Editor.IsSelecting)
6668
{
6769
e.Handled = true;
6870
}

0 commit comments

Comments
 (0)