Skip to content

Commit 0c8a4f9

Browse files
authored
End operation if cancellation is not supported (#171)
1 parent 4b98f15 commit 0c8a4f9

File tree

11 files changed

+111
-43
lines changed

11 files changed

+111
-43
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
> - Renamed UnselectAllConnection to UnselectAllConnections in NodifyEditor
1212
> - Removed DragStarted, DragDelta and DragCompleted routed events from ItemContainer
1313
> - Replaced the System.Windows.Input.MouseGesture with Nodify.MouseGesture
14+
> - Moved AllowCuttingCancellation from CuttingLine to NodifyEditor
15+
> - Moved AllowDraggingCancellation from ItemContainer to NodifyEditor
1416
> - Features:
1517
> - Added BeginPanning, UpdatePanning, EndPanning, CancelPanning and AllowPanningCancellation to NodifyEditor
1618
> - Added UpdateCuttingLine to NodifyEditor

Examples/Nodify.Playground/EditorSettings.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ private EditorSettings()
220220
val => Instance.MouseActionSuppressionThreshold = val,
221221
"Context menu suppression threshold: ",
222222
"Disable context menu after mouse moved this far"),
223+
new ProxySettingViewModel<bool>(
224+
() => Instance.PreserveSelectionOnRightClick,
225+
val => Instance.PreserveSelectionOnRightClick = val,
226+
"Preserve selection on right click: ",
227+
"Whether right-click on the container should preserve the current selection."),
223228
new ProxySettingViewModel<double>(
224229
() => Instance.AutoPanningTickRate,
225230
val => Instance.AutoPanningTickRate = val,
@@ -600,6 +605,12 @@ public GroupingMovementMode GroupingNodeMovement
600605

601606
#region Advanced settings
602607

608+
public bool PreserveSelectionOnRightClick
609+
{
610+
get => ItemContainer.PreserveSelectionOnRightClick;
611+
set => ItemContainer.PreserveSelectionOnRightClick = value;
612+
}
613+
603614
public double MouseActionSuppressionThreshold
604615
{
605616
get => NodifyEditor.MouseActionSuppressionThreshold;
@@ -614,8 +625,8 @@ public double AutoPanningTickRate
614625

615626
public bool AllowCuttingCancellation
616627
{
617-
get => CuttingLine.AllowCuttingCancellation;
618-
set => CuttingLine.AllowCuttingCancellation = value;
628+
get => NodifyEditor.AllowCuttingCancellation;
629+
set => NodifyEditor.AllowCuttingCancellation = value;
619630
}
620631

621632
public bool AllowPushItemsCancellation
@@ -638,8 +649,8 @@ public bool AllowSelectionCancellation
638649

639650
public bool AllowDraggingCancellation
640651
{
641-
get => ItemContainer.AllowDraggingCancellation;
642-
set => ItemContainer.AllowDraggingCancellation = value;
652+
get => NodifyEditor.AllowDraggingCancellation;
653+
set => NodifyEditor.AllowDraggingCancellation = value;
643654
}
644655

645656
public bool AllowPendingConnectionCancellation

Nodify/Connections/CuttingLine.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ public static bool GetIsOverElement(UIElement elem)
2020
public static void SetIsOverElement(UIElement elem, bool value)
2121
=> elem.SetValue(IsOverElementProperty, value);
2222

23-
/// <summary>
24-
/// Gets or sets whether cancelling a cutting operation is allowed (see <see cref="EditorGestures.NodifyEditorGestures.CancelAction"/>).
25-
/// </summary>
26-
public static bool AllowCuttingCancellation { get; set; } = true;
27-
2823
/// <summary>
2924
/// Gets or sets the start point.
3025
/// </summary>

Nodify/EditorStates/ContainerDraggingState.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class ContainerDraggingState : ContainerState
99
private Point _initialMousePosition;
1010
private Point _previousMousePosition;
1111

12-
private bool Canceled { get; set; } = ItemContainer.AllowDraggingCancellation;
12+
private bool Canceled { get; set; } = NodifyEditor.AllowDraggingCancellation;
1313

1414
/// <summary>Constructs an instance of the <see cref="ContainerDraggingState"/> state.</summary>
1515
/// <param name="container">The owner of the state.</param>
@@ -69,7 +69,7 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
6969

7070
PopState();
7171
}
72-
else if (ItemContainer.AllowDraggingCancellation && gestures.CancelAction.Matches(e.Source, e))
72+
else if (NodifyEditor.AllowDraggingCancellation && gestures.CancelAction.Matches(e.Source, e))
7373
{
7474
Canceled = true;
7575
e.Handled = true;
@@ -82,7 +82,7 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
8282
public override void HandleKeyUp(KeyEventArgs e)
8383
{
8484
EditorGestures.ItemContainerGestures gestures = EditorGestures.Mappings.ItemContainer;
85-
if (ItemContainer.AllowDraggingCancellation && gestures.CancelAction.Matches(e.Source, e))
85+
if (NodifyEditor.AllowDraggingCancellation && gestures.CancelAction.Matches(e.Source, e))
8686
{
8787
Canceled = true;
8888
PopState();

Nodify/EditorStates/EditorCuttingState.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Nodify
66
public class EditorCuttingState : EditorState
77
{
88
private Point _initialPosition;
9-
private bool Canceled { get; set; } = CuttingLine.AllowCuttingCancellation;
9+
private bool Canceled { get; set; } = NodifyEditor.AllowCuttingCancellation;
1010

1111
public EditorCuttingState(NodifyEditor editor) : base(editor)
1212
{
@@ -52,7 +52,7 @@ public override void HandleMouseUp(MouseButtonEventArgs e)
5252

5353
PopState();
5454
}
55-
else if (CuttingLine.AllowCuttingCancellation && gestures.CancelAction.Matches(e.Source, e))
55+
else if (NodifyEditor.AllowCuttingCancellation && gestures.CancelAction.Matches(e.Source, e))
5656
{
5757
Canceled = true;
5858
e.Handled = true; // prevents opening context menu
@@ -69,7 +69,7 @@ public override void HandleMouseMove(MouseEventArgs e)
6969
public override void HandleKeyUp(KeyEventArgs e)
7070
{
7171
EditorGestures.NodifyEditorGestures gestures = EditorGestures.Mappings.Editor;
72-
if (CuttingLine.AllowCuttingCancellation && gestures.CancelAction.Matches(e.Source, e))
72+
if (NodifyEditor.AllowCuttingCancellation && gestures.CancelAction.Matches(e.Source, e))
7373
{
7474
Canceled = true;
7575
PopState();

Nodify/ItemContainer.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,6 @@ private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyCh
232232

233233
#region Fields
234234

235-
/// <summary>
236-
/// Gets or sets whether cancelling a dragging operation is allowed.
237-
/// </summary>
238-
public static bool AllowDraggingCancellation { get; set; } = true;
239-
240235
/// <summary>
241236
/// Indicates whether right-click on the container should preserve the current selection.
242237
/// </summary>

Nodify/NodifyEditor.Cutting.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace Nodify
1010
[StyleTypedProperty(Property = nameof(CuttingLineStyle), StyleTargetType = typeof(CuttingLine))]
1111
public partial class NodifyEditor
1212
{
13+
#region Dependency properties
14+
1315
protected static readonly DependencyPropertyKey CuttingLineStartPropertyKey = DependencyProperty.RegisterReadOnly(nameof(CuttingLineStart), typeof(Point), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Point));
1416
public static readonly DependencyProperty CuttingLineStartProperty = CuttingLineStartPropertyKey.DependencyProperty;
1517

@@ -95,6 +97,13 @@ public ICommand? CuttingCompletedCommand
9597
set => SetValue(CuttingCompletedCommandProperty, value);
9698
}
9799

100+
#endregion
101+
102+
/// <summary>
103+
/// Gets or sets whether cancelling a cutting operation is allowed (see <see cref="EditorGestures.NodifyEditorGestures.CancelAction"/>).
104+
/// </summary>
105+
public static bool AllowCuttingCancellation { get; set; } = true;
106+
98107
/// <summary>
99108
/// Gets or sets whether the cutting line should apply the preview style to the interesected elements.
100109
/// </summary>
@@ -111,6 +120,13 @@ public ICommand? CuttingCompletedCommand
111120
private List<FrameworkElement>? _cuttingLinePreviousConnections;
112121
private readonly LineGeometry _cuttingLineGeometry = new LineGeometry();
113122

123+
/// <summary>
124+
/// Starts the cutting operation at the current <see cref="MouseLocation"/>. Call <see cref="EndCutting"/> to complete the operation or <see cref="CancelCutting"/> to abort it.
125+
/// </summary>
126+
/// <remarks>This method has no effect if a cutting operation is already in progress.</remarks>
127+
public void BeginCutting()
128+
=> BeginCutting(MouseLocation);
129+
114130
/// <summary>
115131
/// Starts the cutting operation at the specified location. Call <see cref="EndCutting"/> to complete the operation or <see cref="CancelCutting"/> to abort it.
116132
/// </summary>
@@ -161,18 +177,23 @@ public void UpdateCuttingLine(Point location)
161177
}
162178

163179
/// <summary>
164-
/// Cancels the current cutting operation without applying any changes.
180+
/// Cancels the current cutting operation without applying any changes if <see cref="AllowCuttingCancellation"/> is true.
181+
/// Otherwise, it ends the cutting operation by calling <see cref="EndCutting"/>.
165182
/// </summary>
166183
/// <remarks>This method has no effect if there's no cutting operation in progress.</remarks>
167184
public void CancelCutting()
168185
{
169-
if (!CuttingLine.AllowCuttingCancellation || !IsCutting)
186+
if (!AllowCuttingCancellation)
170187
{
188+
EndCutting();
171189
return;
172190
}
173191

174-
ResetConnectionStyle();
175-
IsCutting = false;
192+
if (IsCutting)
193+
{
194+
ResetConnectionStyle();
195+
IsCutting = false;
196+
}
176197
}
177198

178199
/// <summary>

Nodify/NodifyEditor.Dragging.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace Nodify
77
{
88
public partial class NodifyEditor
99
{
10+
#region Dependency properties
11+
1012
public static readonly DependencyProperty ItemsDragStartedCommandProperty = DependencyProperty.Register(nameof(ItemsDragStartedCommand), typeof(ICommand), typeof(NodifyEditor));
1113
public static readonly DependencyProperty ItemsDragCompletedCommandProperty = DependencyProperty.Register(nameof(ItemsDragCompletedCommand), typeof(ICommand), typeof(NodifyEditor));
1214

@@ -66,6 +68,13 @@ public bool IsDragging
6668
private set => SetValue(IsDraggingPropertyKey, value);
6769
}
6870

71+
#endregion
72+
73+
/// <summary>
74+
/// Gets or sets whether cancelling a dragging operation is allowed.
75+
/// </summary>
76+
public static bool AllowDraggingCancellation { get; set; } = true;
77+
6978
/// <summary>
7079
/// Gets or sets if the current position of containers that are being dragged should not be committed until the end of the dragging operation.
7180
/// </summary>
@@ -77,7 +86,7 @@ public bool IsDragging
7786
/// Initiates the dragging operation using the currently selected <see cref="ItemContainer" />s.
7887
/// </summary>
7988
/// <remarks>This method has no effect if a dragging operation is already in progress.</remarks>
80-
public void BeginDragging()
89+
public void BeginDragging()
8190
=> BeginDragging(SelectedContainers);
8291

8392
/// <summary>
@@ -87,7 +96,7 @@ public void BeginDragging()
8796
/// <remarks>This method has no effect if a dragging operation is already in progress.</remarks>
8897
public void BeginDragging(IEnumerable<ItemContainer> containers)
8998
{
90-
if(IsDragging)
99+
if (IsDragging)
91100
{
92101
return;
93102
}
@@ -132,18 +141,23 @@ public void EndDragging()
132141
}
133142

134143
/// <summary>
135-
/// Cancels the ongoing dragging operation, reverting any changes made to the positions of the dragged items.
144+
/// Cancels the ongoing dragging operation, reverting any changes made to the positions of the dragged items if <see cref="AllowDraggingCancellation"/> is true.
145+
/// Otherwise, it ends the dragging operation by calling <see cref="EndDragging"/>.
136146
/// </summary>
137147
/// <remarks>This method has no effect if there's no dragging operation in progress.</remarks>
138148
public void CancelDragging()
139149
{
140-
if (!ItemContainer.AllowDraggingCancellation || !IsDragging)
150+
if (!AllowDraggingCancellation)
141151
{
152+
EndDragging();
142153
return;
143154
}
144155

145-
_draggingStrategy!.Abort();
146-
IsDragging = false;
156+
if (IsDragging)
157+
{
158+
_draggingStrategy!.Abort();
159+
IsDragging = false;
160+
}
147161
}
148162

149163
private IDraggingStrategy CreateDraggingStrategy(IEnumerable<ItemContainer> containers)

Nodify/NodifyEditor.Panning.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Diagnostics;
32
using System.Windows;
43
using System.Windows.Input;
54
using System.Windows.Threading;
@@ -8,6 +7,8 @@ namespace Nodify
87
{
98
public partial class NodifyEditor
109
{
10+
#region Dependency properties
11+
1112
public static readonly DependencyProperty AutoPanSpeedProperty = DependencyProperty.Register(nameof(AutoPanSpeed), typeof(double), typeof(NodifyEditor), new FrameworkPropertyMetadata(15d));
1213
public static readonly DependencyProperty AutoPanEdgeDistanceProperty = DependencyProperty.Register(nameof(AutoPanEdgeDistance), typeof(double), typeof(NodifyEditor), new FrameworkPropertyMetadata(15d));
1314
public static readonly DependencyProperty DisableAutoPanningProperty = DependencyProperty.Register(nameof(DisableAutoPanning), typeof(bool), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.False, OnDisableAutoPanningChanged));
@@ -70,6 +71,8 @@ public bool IsPanning
7071
private set => SetValue(IsPanningPropertyKey, value);
7172
}
7273

74+
#endregion
75+
7376
/// <summary>
7477
/// Gets or sets whether panning cancellation is allowed (see <see cref="EditorGestures.NodifyEditorGestures.CancelAction"/>).
7578
/// </summary>
@@ -122,17 +125,22 @@ public void UpdatePanning(Vector amount)
122125

123126
/// <summary>
124127
/// Cancels the current panning operation and reverts the viewport to its initial location if <see cref="AllowPanningCancellation"/> is true.
128+
/// Otherwise, it ends the panning operation by calling <see cref="EndPanning"/>.
125129
/// </summary>
126130
/// <remarks>This method has no effect if there's no panning operation in progress.</remarks>
127131
public void CancelPanning()
128132
{
129-
if (!AllowPanningCancellation || !IsPanning)
133+
if (!AllowPanningCancellation)
130134
{
135+
EndPanning();
131136
return;
132137
}
133138

134-
ViewportLocation = _initialPanningLocation;
135-
IsPanning = false;
139+
if (IsPanning)
140+
{
141+
ViewportLocation = _initialPanningLocation;
142+
IsPanning = false;
143+
}
136144
}
137145

138146
/// <summary>
@@ -146,6 +154,11 @@ public void EndPanning()
146154

147155
#region Auto panning
148156

157+
private readonly MouseEventArgs _autoPanningEventArgs = new MouseEventArgs(Mouse.PrimaryDevice, 0, Stylus.CurrentStylusDevice)
158+
{
159+
RoutedEvent = MouseMoveEvent
160+
};
161+
149162
private void HandleAutoPanning(object? sender, EventArgs e)
150163
{
151164
if (!IsPanning && IsMouseCaptureWithin)
@@ -177,7 +190,9 @@ private void HandleAutoPanning(object? sender, EventArgs e)
177190
ViewportLocation = new Point(x, y);
178191
MouseLocation = Mouse.GetPosition(ItemsHost);
179192

180-
State.HandleAutoPanning(new MouseEventArgs(Mouse.PrimaryDevice, 0));
193+
_autoPanningEventArgs.Handled = false;
194+
_autoPanningEventArgs.Source = this;
195+
State.HandleAutoPanning(_autoPanningEventArgs);
181196
}
182197
}
183198

Nodify/NodifyEditor.PushingItems.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public Style PushedAreaStyle
5858
/// <summary>
5959
/// Gets or sets whether push items cancellation is allowed (see <see cref="EditorGestures.NodifyEditorGestures.CancelAction"/>).
6060
/// </summary>
61+
/// <remarks>Has no effect if <see cref="AllowDraggingCancellation"/> is false.</remarks>
6162
public static bool AllowPushItemsCancellation { get; set; } = true;
6263

6364
private IPushStrategy? _pushStrategy;
@@ -70,7 +71,7 @@ public Style PushedAreaStyle
7071
/// <param name="orientation">The orientation of the <see cref="PushedArea"/>.</param>
7172
public void BeginPushingItems(Point location, Orientation orientation)
7273
{
73-
if(IsPushingItems)
74+
if (IsPushingItems)
7475
{
7576
return;
7677
}
@@ -114,17 +115,22 @@ public void EndPushingItems()
114115

115116
/// <summary>
116117
/// Cancels the current pushing operation and reverts the <see cref="PushedArea"/> to its initial state if <see cref="AllowPushItemsCancellation"/> is true.
118+
/// Otherwise, it ends the pushing operation by calling <see cref="EndPushingItems"/>.
117119
/// </summary>
118120
/// <remarks>This method has no effect if there's no pushing operation in progress.</remarks>
119121
public void CancelPushingItems()
120122
{
121-
if (!AllowPushItemsCancellation || !IsPushingItems)
123+
if (!AllowPushItemsCancellation)
122124
{
125+
EndPushingItems();
123126
return;
124127
}
125128

126-
PushedArea = _pushStrategy!.Cancel();
127-
IsPushingItems = false;
129+
if (IsPushingItems)
130+
{
131+
PushedArea = _pushStrategy!.Cancel();
132+
IsPushingItems = false;
133+
}
128134
}
129135

130136
private void UpdatePushedArea()

0 commit comments

Comments
 (0)