Skip to content

Commit

Permalink
Merge pull request #189 from miroiu/fix/selection-behavior
Browse files Browse the repository at this point in the history
Correct selection behavior for nodes and connections
  • Loading branch information
miroiu authored Jan 8, 2025
2 parents 10cea9d + 472fa82 commit 13f75c2
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
> - Features:
> - Bugfixes:
> - Fixed an issue where connections would not gain focus when selected, which could prevent editor keybindings from functioning in certain scenarios
> - Resolved an issue where selecting a node did not deselect connections and vice versa
#### **Version 7.0.0**

Expand Down
14 changes: 14 additions & 0 deletions Nodify/Connections/ConnectionsMultiSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ private bool CanSelectMultipleItemsBase
set => base.CanSelectMultipleItems = value;
}

/// <summary>
/// Gets the <see cref="NodifyEditor"/> that owns this <see cref="ConnectionsMultiSelector"/>.
/// </summary>
public NodifyEditor? Editor { get; private set; }

protected override DependencyObject GetContainerForItemOverride()
=> new ConnectionContainer(this);

Expand All @@ -66,6 +71,15 @@ public void Select(ConnectionContainer container)
#endif

EndUpdateSelectedItems();

Editor?.UnselectAll();
}

public override void OnApplyTemplate()
{
base.OnApplyTemplate();

Editor = this.GetParentOfType<NodifyEditor>();
}

#region Selection Handlers
Expand Down
20 changes: 8 additions & 12 deletions Nodify/Editor/NodifyEditor.Selecting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ public void Select(ItemContainer container)
selected.Clear();
selected.Add(container.DataContext);
EndUpdateSelectedItems();

UnselectAllConnections();
}

/// <summary>
Expand Down Expand Up @@ -360,7 +362,6 @@ public void BeginSelecting(Point location, SelectionType type = SelectionType.Re
return;
}

UnselectAllConnections();
SelectedArea = _selection.Start(ItemContainers, location, type, EnableRealtimeSelection);
IsSelecting = true;
}
Expand Down Expand Up @@ -396,6 +397,11 @@ public void EndSelecting()
return;
}

if (_selection.Type == SelectionType.Replace)
{
UnselectAllConnections();
}

SelectedArea = _selection.End();
ApplyPreviewingSelection();
IsSelecting = false;
Expand All @@ -416,7 +422,7 @@ public void CancelSelecting()

if (IsSelecting)
{
ClearPreviewingSelection();
_selection.Cancel();
IsSelecting = false;
}
}
Expand All @@ -443,16 +449,6 @@ private void ApplyPreviewingSelection()
EndUpdateSelectedItems();
}

private void ClearPreviewingSelection()
{
ItemCollection items = Items;
for (var i = 0; i < items.Count; i++)
{
var container = (ItemContainer)ItemContainerGenerator.ContainerFromIndex(i);
container.IsPreviewingSelection = null;
}
}

#endregion

#region Selection Handlers
Expand Down
43 changes: 33 additions & 10 deletions Nodify/Utilities/SelectionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ internal sealed class SelectionHelper
{
private Point _startLocation;
private Point _endLocation;
private SelectionType _selectionType;
private bool _isRealtime;
private IReadOnlyCollection<ItemContainer> _items = Array.Empty<ItemContainer>();
private IReadOnlyList<ItemContainer> _items = Array.Empty<ItemContainer>();
private IReadOnlyList<ItemContainer> _initialSelection = Array.Empty<ItemContainer>();
private Rect _selectedArea;

public SelectionType Type { get; private set; }

/// <summary>Attempts to start a new selection.</summary>
/// <param name="containers">The containers that can be part of the selection.</param>
/// <param name="location">The location inside the graph.</param>
Expand All @@ -30,7 +31,7 @@ public Rect Start(IEnumerable<ItemContainer> containers, Point location, Selecti
_items = containers.Where(x => x.IsSelectable).ToList();
_initialSelection = containers.Where(x => x.IsSelected).ToList();

_selectionType = selectionType;
Type = selectionType;

_isRealtime = realtime;
_startLocation = location;
Expand Down Expand Up @@ -79,9 +80,18 @@ public Rect End()
return _selectedArea;
}

public void Cancel()
{
ClearPreviewingSelection();
_items = Array.Empty<ItemContainer>();
_initialSelection = Array.Empty<ItemContainer>();
}

#region Selection preview

private void PreviewSelection(Rect area)
{
switch (_selectionType)
switch (Type)
{
case SelectionType.Replace:
PreviewSelectArea(area);
Expand Down Expand Up @@ -114,9 +124,9 @@ private void PreviewSelection(Rect area)

private void PreviewUnselectAll()
{
foreach (var container in _items)
for (int i = 0; i < _items.Count; i++)
{
container.IsPreviewingSelection = false;
_items[i].IsPreviewingSelection = false;
}
}

Expand All @@ -129,8 +139,9 @@ private void PreviewSelectArea(Rect area, bool append = false, bool fit = false)

if (area.X != 0 || area.Y != 0 || area.Width > 0 || area.Height > 0)
{
foreach (var container in _items)
for (int i = 0; i < _items.Count; i++)
{
ItemContainer? container = _items[i];
if (container.IsSelectableInArea(area, fit))
{
container.IsPreviewingSelection = true;
Expand All @@ -141,8 +152,9 @@ private void PreviewSelectArea(Rect area, bool append = false, bool fit = false)

private void PreviewUnselectArea(Rect area, bool fit = false)
{
foreach (var container in _items)
for (int i = 0; i < _items.Count; i++)
{
ItemContainer? container = _items[i];
if (container.IsSelectableInArea(area, fit))
{
container.IsPreviewingSelection = false;
Expand All @@ -152,22 +164,33 @@ private void PreviewUnselectArea(Rect area, bool fit = false)

private static void PreviewSelectContainers(IReadOnlyList<ItemContainer> containers)
{
for (var i = 0; i < containers.Count; i++)
for (int i = 0; i < containers.Count; i++)
{
containers[i].IsPreviewingSelection = true;
}
}

private void PreviewInvertSelection(Rect area, bool fit = false)
{
foreach (var container in _items)
for (int i = 0; i < _items.Count; i++)
{
ItemContainer? container = _items[i];
if (container.IsSelectableInArea(area, fit))
{
container.IsPreviewingSelection = !container.IsPreviewingSelection;
}
}
}

private void ClearPreviewingSelection()
{
for (int i = 0; i < _items.Count; i++)
{
_items[i].IsPreviewingSelection = null;
}
}

#endregion
}

internal static class SelectionGesturesExtensions
Expand Down

0 comments on commit 13f75c2

Please sign in to comment.