Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct selection behavior for nodes and connections #189

Merged
merged 3 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading