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

Enable toggled interactions for various editor operations #178

Merged
merged 7 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Add flags to EditorState to control panning behavior
  • Loading branch information
miroiu committed Dec 13, 2024
commit 064f86f020f576ddd4ea02d5471380c553c29110
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
> - Added InputProcessor.Shared to enable the addition of global input handlers
> - Move the viewport to the mouse position when zooming on the Minimap if ResizeToViewport is false
> - Added SplitAtLocation and Remove methods to BaseConnection
> - Added AllowPanningWhileSelecting, AllowPanningWhileCutting and AllowPanningWhilePushingItems to EditorState
> - Added AllowZoomingWhileSelecting, AllowZoomingWhileCutting and AllowZoomingWhilePushingItems to EditorState
> - Bugfixes:
> - Fixed an issue where the ItemContainer was selected by releasing the mouse button on it, even when the mouse was not captured
> - Fixed an issue where the ItemContainer could open its context menu even when it was not selected
Expand Down
4 changes: 4 additions & 0 deletions Nodify/Editor/NodifyEditor.PushingItems.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Nodify
[StyleTypedProperty(Property = nameof(PushedAreaStyle), StyleTargetType = typeof(Rectangle))]
public partial class NodifyEditor
{
#region Dependency properties

public static readonly DependencyProperty PushedAreaStyleProperty = DependencyProperty.Register(nameof(PushedAreaStyle), typeof(Style), typeof(NodifyEditor));

protected static readonly DependencyPropertyKey PushedAreaPropertyKey = DependencyProperty.RegisterReadOnly(nameof(PushedArea), typeof(Rect), typeof(NodifyEditor), new FrameworkPropertyMetadata(BoxValue.Rect));
Expand Down Expand Up @@ -56,6 +58,8 @@ public Style PushedAreaStyle
set => SetValue(PushedAreaStyleProperty, value);
}

#endregion

/// <summary>
/// Gets or sets whether push items cancellation is allowed (see <see cref="EditorGestures.NodifyEditorGestures.CancelAction"/>).
/// </summary>
Expand Down
30 changes: 30 additions & 0 deletions Nodify/Editor/States/EditorState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@
{
public static partial class EditorState
{
/// <summary>
/// Gets or sets a value indicating whether panning is allowed while selecting items in the editor.
/// </summary>
public static bool AllowPanningWhileSelecting { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether panning is allowed while cutting connections in the editor.
/// </summary>
public static bool AllowPanningWhileCutting { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether panning is allowed while pushing items in the editor.
/// </summary>
public static bool AllowPanningWhilePushingItems { get; set; }

/// <summary>
/// Gets or sets a value indicating whether zooming is allowed while selecting items in the editor.
/// </summary>
public static bool AllowZoomingWhileSelecting { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether zooming is allowed while cutting connections in the editor.
/// </summary>
public static bool AllowZoomingWhileCutting { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether zooming is allowed while pushing items in the editor.
/// </summary>
public static bool AllowZoomingWhilePushingItems { get; set; } = true;

internal static void RegisterDefaultHandlers()
{
InputProcessor.Shared<NodifyEditor>.RegisterHandlerFactory(elem => new Panning(elem));
Expand Down
11 changes: 10 additions & 1 deletion Nodify/Editor/States/Panning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public static partial class EditorState
public class Panning : DragState<NodifyEditor>
{
protected override bool HasContextMenu => Element.HasContextMenu;
protected override bool CanBegin => !Element.DisablePanning;
protected override bool CanBegin => IsPanningAllowed();

protected override bool CanCancel => NodifyEditor.AllowPanningCancellation;

private Point _prevPosition;
Expand Down Expand Up @@ -44,6 +45,14 @@ protected override void OnEnd(InputEventArgs e)

protected override void OnCancel(InputEventArgs e)
=> Element.CancelPanning();

private bool IsPanningAllowed()
{
return !Element.DisablePanning
&& (AllowPanningWhileSelecting || !Element.IsSelecting)
&& (AllowPanningWhileCutting || !Element.IsCutting)
&& (AllowPanningWhilePushingItems || !Element.IsPushingItems);
}
}

/// <summary>
Expand Down
10 changes: 9 additions & 1 deletion Nodify/Editor/States/Zooming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,21 @@ public Zooming(NodifyEditor editor) : base(editor)
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
EditorGestures.NodifyEditorGestures gestures = EditorGestures.Mappings.Editor;
if (gestures.ZoomModifierKey == Keyboard.Modifiers)
if (gestures.ZoomModifierKey == Keyboard.Modifiers && IsZoomingAllowed())
{
double zoom = Math.Pow(2.0, e.Delta / 3.0 / Mouse.MouseWheelDeltaForOneLine);
Element.ZoomAtPosition(zoom, Element.MouseLocation);
e.Handled = true;
}
}

private bool IsZoomingAllowed()
{
return !Element.DisableZooming
&& (AllowZoomingWhileSelecting || !Element.IsSelecting)
&& (AllowZoomingWhileCutting || !Element.IsCutting)
&& (AllowZoomingWhilePushingItems || !Element.IsPushingItems);
}
}
}
}
22 changes: 9 additions & 13 deletions Nodify/Interactivity/InputProcessor.Shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@

namespace Nodify.Interactivity
{
public sealed partial class InputProcessor
public partial class InputProcessor
{
/// <summary>
/// A shared input processor that allows registering and managing global input handlers for a specific type of UI element.
/// </summary>
/// <typeparam name="TElement">The type of the UI element that the input handlers will be associated with.</typeparam>
public sealed class Shared<TElement> : IInputHandler
public sealed class Shared<TElement> : InputProcessor, IInputHandler
where TElement : FrameworkElement
{
private static readonly List<KeyValuePair<Type, Func<TElement, IInputHandler>>> _handlerFactories = new List<KeyValuePair<Type, Func<TElement, IInputHandler>>>();

private readonly List<IInputHandler> _handlers = new List<IInputHandler>();

/// <summary>
/// Initializes a new instance of the <see cref="Shared{TElement}"/> class for the specified UI element.
/// </summary>
Expand All @@ -27,7 +25,7 @@ public Shared(TElement element)
{
foreach (var kvp in _handlerFactories)
{
_handlers.Add(kvp.Value(element));
AddHandler(kvp.Value(element));
}
}

Expand All @@ -53,19 +51,14 @@ static Shared()
{
MinimapState.RegisterDefaultHandlers();
}
else if(typeof(TElement) == typeof(BaseConnection))
else if (typeof(TElement) == typeof(BaseConnection))
{
ConnectionState.RegisterDefaultHandlers();
}
}

public void HandleEvent(InputEventArgs e)
{
foreach (var handler in _handlers)
{
handler.HandleEvent(e);
}
}
=> Process(e);

/// <summary>
/// Registers a factory method for creating an input handler of the specified type.
Expand Down Expand Up @@ -115,7 +108,10 @@ public static class InputProcessorExtensions
public static void AddSharedHandlers<TElement>(this InputProcessor inputProcessor, TElement instance)
where TElement : FrameworkElement
{
inputProcessor.AddHandler(new InputProcessor.Shared<TElement>(instance));
inputProcessor.AddHandler(new InputProcessor.Shared<TElement>(instance)
{
ProcessHandledEvents = inputProcessor.ProcessHandledEvents
});
}
}
}
2 changes: 1 addition & 1 deletion Nodify/Interactivity/InputProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Nodify.Interactivity
/// <summary>
/// Processes input events and delegates them to registered handlers.
/// </summary>
public sealed partial class InputProcessor
public partial class InputProcessor
{
private readonly HashSet<IInputHandler> _handlers = new HashSet<IInputHandler>();

Expand Down