Skip to content
Open
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
14 changes: 14 additions & 0 deletions site/Site/Pages/Documentation/Diagram/Behaviors.razor
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ Diagram.UnregisterBehavior<SelectionBehavior>();
Diagram.RegisterBehavior(new MySelectionBehavior(Diagram));
</code></pre>

<h2>Configure behaviors for different actions on input</h2>

You can configure a behavior to perform different actions for an input. Such as scrolling a diagram on mouse wheel instead of zooming in and out.
This can be done using the <code>BehaviorOptions</code>. See the below example.

<h3>Scrolling a diagram on mouse wheel</h3>

<p>To scroll a diagram using the mouse wheel set the <code>DiagramWheelBehavior</code> property of <code>BehaviorOptions</code> to use <code>ScrollBehavior</code>.</p>

<pre><code class="language-cs">
_diagram.BehaviorOptions.DiagramWheelBehavior = _diagram.GetBehavior&lt;ScrollBehavior&gt;();
</code></pre>


<NavigationButtons PreviousLink="/documentation/diagram"
PreviousTitle="Overview"
NextTitle="Ordering"
Expand Down
15 changes: 0 additions & 15 deletions src/Blazor.Diagrams.Core/Behavior.cs

This file was deleted.

16 changes: 16 additions & 0 deletions src/Blazor.Diagrams.Core/Behaviors/Base/Behavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace Blazor.Diagrams.Core.Behaviors.Base
{
public abstract class Behavior : IDisposable
{
public Behavior(Diagram diagram)
{
Diagram = diagram;
}

protected Diagram Diagram { get; }

public abstract void Dispose();
}
}
49 changes: 49 additions & 0 deletions src/Blazor.Diagrams.Core/Behaviors/Base/DragBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Models.Base;

namespace Blazor.Diagrams.Core.Behaviors.Base
{
public abstract class DragBehavior : Behavior
{
public DragBehavior(Diagram diagram)
: base(diagram)
{
Diagram.PointerDown += OnPointerDown;
Diagram.PointerMove += OnPointerMove;
Diagram.PointerUp += OnPointerUp;
}

protected abstract void OnPointerDown(Model? model, PointerEventArgs e);

protected abstract void OnPointerMove(Model? model, PointerEventArgs e);

protected abstract void OnPointerUp(Model? model, PointerEventArgs e);

public virtual bool IsBehaviorEnabled(PointerEventArgs e)
{
if (e.AltKey && !e.CtrlKey && !e.ShiftKey
&& Diagram.BehaviorOptions.DiagramAltDragBehavior is not null)
{
return this == Diagram.BehaviorOptions.DiagramAltDragBehavior;
}
else if (!e.AltKey && e.CtrlKey && !e.ShiftKey
&& Diagram.BehaviorOptions.DiagramCtrlDragBehavior is not null)
{
return this == Diagram.BehaviorOptions.DiagramCtrlDragBehavior;
}
else if (!e.AltKey && !e.CtrlKey && e.ShiftKey
&& Diagram.BehaviorOptions.DiagramShiftDragBehavior is not null)
{
return this == Diagram.BehaviorOptions.DiagramShiftDragBehavior;
}
return this == Diagram.BehaviorOptions.DiagramDragBehavior;
}

public override void Dispose()
{
Diagram.PointerDown -= OnPointerDown;
Diagram.PointerMove -= OnPointerMove;
Diagram.PointerUp -= OnPointerUp;
}
}
}
42 changes: 42 additions & 0 deletions src/Blazor.Diagrams.Core/Behaviors/Base/WheelBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Blazor.Diagrams.Core.Events;

namespace Blazor.Diagrams.Core.Behaviors.Base
{
public abstract class WheelBehavior : Behavior
{
protected WheelBehavior(Diagram diagram)
: base(diagram)
{

Diagram.Wheel += OnDiagramWheel;
}

protected abstract void OnDiagramWheel(WheelEventArgs e);

public virtual bool IsBehaviorEnabled(WheelEventArgs e)
{
if (e.AltKey && !e.CtrlKey && !e.ShiftKey
&& Diagram.BehaviorOptions.DiagramAltWheelBehavior is not null)
{
return this == Diagram.BehaviorOptions.DiagramAltWheelBehavior;
}
else if (!e.AltKey && e.CtrlKey && !e.ShiftKey
&& Diagram.BehaviorOptions.DiagramCtrlWheelBehavior is not null)
{
return this == Diagram.BehaviorOptions.DiagramCtrlWheelBehavior;
}
else if (!e.AltKey && !e.CtrlKey && e.ShiftKey
&& Diagram.BehaviorOptions.DiagramShiftWheelBehavior is not null)
{
return this == Diagram.BehaviorOptions.DiagramShiftWheelBehavior;
}

return this == Diagram.BehaviorOptions.DiagramWheelBehavior;
}

public override void Dispose()
{
Diagram.Wheel -= OnDiagramWheel;
}
}
}
3 changes: 2 additions & 1 deletion src/Blazor.Diagrams.Core/Behaviors/DebugEventsBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Behaviors.Base;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Base;
using System;

Expand Down
1 change: 1 addition & 0 deletions src/Blazor.Diagrams.Core/Behaviors/DragMovablesBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Behaviors.Base;

namespace Blazor.Diagrams.Core.Behaviors;

Expand Down
1 change: 1 addition & 0 deletions src/Blazor.Diagrams.Core/Behaviors/DragNewLinkBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using Blazor.Diagrams.Core.Anchors;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Behaviors.Base;

namespace Blazor.Diagrams.Core.Behaviors;

Expand Down
1 change: 1 addition & 0 deletions src/Blazor.Diagrams.Core/Behaviors/EventsBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Blazor.Diagrams.Core.Models.Base;
using Blazor.Diagrams.Core.Events;
using System.Diagnostics;
using Blazor.Diagrams.Core.Behaviors.Base;

namespace Blazor.Diagrams.Core.Behaviors;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Behaviors.Base;
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Utils;
using System;
using System.Collections.Generic;
Expand Down
93 changes: 35 additions & 58 deletions src/Blazor.Diagrams.Core/Behaviors/PanBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,43 @@
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models.Base;
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Behaviors.Base;

namespace Blazor.Diagrams.Core.Behaviors;

public class PanBehavior : Behavior
namespace Blazor.Diagrams.Core.Behaviors
{
private Point? _initialPan;
private double _lastClientX;
private double _lastClientY;

public PanBehavior(Diagram diagram) : base(diagram)
{
Diagram.PointerDown += OnPointerDown;
Diagram.PointerMove += OnPointerMove;
Diagram.PointerUp += OnPointerUp;
}

private void OnPointerDown(Model? model, PointerEventArgs e)
{
if (e.Button != (int)MouseEventButton.Left)
return;

Start(model, e.ClientX, e.ClientY, e.ShiftKey);
}

private void OnPointerMove(Model? model, PointerEventArgs e) => Move(e.ClientX, e.ClientY);

private void OnPointerUp(Model? model, PointerEventArgs e) => End();

private void Start(Model? model, double clientX, double clientY, bool shiftKey)
{
if (!Diagram.Options.AllowPanning || model != null || shiftKey)
return;

_initialPan = Diagram.Pan;
_lastClientX = clientX;
_lastClientY = clientY;
}

private void Move(double clientX, double clientY)
{
if (!Diagram.Options.AllowPanning || _initialPan == null)
return;

var deltaX = clientX - _lastClientX - (Diagram.Pan.X - _initialPan.X);
var deltaY = clientY - _lastClientY - (Diagram.Pan.Y - _initialPan.Y);
Diagram.UpdatePan(deltaX, deltaY);
}

private void End()
{
if (!Diagram.Options.AllowPanning)
return;

_initialPan = null;
}

public override void Dispose()
public class PanBehavior : DragBehavior
{
Diagram.PointerDown -= OnPointerDown;
Diagram.PointerMove -= OnPointerMove;
Diagram.PointerUp -= OnPointerUp;
private Point? _initialPan;
private double _lastClientX;
private double _lastClientY;

public PanBehavior(Diagram diagram) : base(diagram)
{
}

protected override void OnPointerDown(Model? model, PointerEventArgs e)
{
if (e.Button != (int)MouseEventButton.Left || model != null || !Diagram.Options.AllowPanning || !IsBehaviorEnabled(e))
return;

_initialPan = Diagram.Pan;
_lastClientX = e.ClientX;
_lastClientY = e.ClientY;
}

protected override void OnPointerMove(Model? model, PointerEventArgs e)
{
if (_initialPan == null)
return;

var deltaX = e.ClientX - _lastClientX - (Diagram.Pan.X - _initialPan.X);
var deltaY = e.ClientY - _lastClientY - (Diagram.Pan.Y - _initialPan.Y);
Diagram.UpdatePan(deltaX, deltaY);
}

protected override void OnPointerUp(Model? model, PointerEventArgs e)
{
_initialPan = null;
}
}
}
25 changes: 25 additions & 0 deletions src/Blazor.Diagrams.Core/Behaviors/ScrollBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Blazor.Diagrams.Core.Behaviors.Base;
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Options;

namespace Blazor.Diagrams.Core.Behaviors
{
public class ScrollBehavior : WheelBehavior
{
public ScrollBehavior(Diagram diagram)
: base(diagram)
{
}

protected override void OnDiagramWheel(WheelEventArgs e)
{
if (Diagram.Container == null || !IsBehaviorEnabled(e))
return;

var x = Diagram.Pan.X - (e.DeltaX / Diagram.Options.Zoom.ScaleFactor);
var y = Diagram.Pan.Y - (e.DeltaY / Diagram.Options.Zoom.ScaleFactor);

Diagram.SetPan(x, y);
}
}
}
1 change: 1 addition & 0 deletions src/Blazor.Diagrams.Core/Behaviors/SelectionBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Blazor.Diagrams.Core.Models.Base;
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Behaviors.Base;

namespace Blazor.Diagrams.Core.Behaviors;

Expand Down
79 changes: 79 additions & 0 deletions src/Blazor.Diagrams.Core/Behaviors/SelectionBoxBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Blazor.Diagrams.Core.Behaviors.Base;
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models.Base;
using System;
using System.Linq;

namespace Blazor.Diagrams.Core.Behaviors
{
public class SelectionBoxBehavior : DragBehavior
{
private Point? _initialClientPoint;

public event EventHandler<Rectangle?>? SelectionBoundsChanged;

public SelectionBoxBehavior(Diagram diagram)
: base(diagram)
{
Diagram.PointerDown += OnPointerDown;
Diagram.PointerMove += OnPointerMove;
Diagram.PointerUp += OnPointerUp;
}

public override void Dispose()
{
Diagram.PointerDown -= OnPointerDown;
Diagram.PointerMove -= OnPointerMove;
Diagram.PointerUp -= OnPointerUp;
}

protected override void OnPointerDown(Model? model, PointerEventArgs e)
{
if (SelectionBoundsChanged is null || model != null || !IsBehaviorEnabled(e))
return;

_initialClientPoint = new Point(e.ClientX, e.ClientY);
}

protected override void OnPointerMove(Model? model, PointerEventArgs e)
{
if (_initialClientPoint == null)
return;

UpdateSelectionBox(e);

var start = Diagram.GetRelativeMousePoint(_initialClientPoint.X, _initialClientPoint.Y);
var end = Diagram.GetRelativeMousePoint(e.ClientX, e.ClientY);
var (sX, sY) = (Math.Min(start.X, end.X), Math.Min(start.Y, end.Y));
var (eX, eY) = (Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));
var bounds = new Rectangle(sX, sY, eX, eY);

foreach (var node in Diagram.Nodes)
{
var nodeBounds = node.GetBounds();
if (nodeBounds == null)
continue;

if (bounds.Overlap(nodeBounds))
Diagram.SelectModel(node, false);
else if (node.Selected) Diagram.UnselectModel(node);
}
}

void UpdateSelectionBox(MouseEventArgs e)
{
var start = Diagram.GetRelativePoint(_initialClientPoint!.X, _initialClientPoint.Y);
var end = Diagram.GetRelativePoint(e.ClientX, e.ClientY);
var (sX, sY) = (Math.Min(start.X, end.X), Math.Min(start.Y, end.Y));
var (eX, eY) = (Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));
SelectionBoundsChanged?.Invoke(this, new Rectangle(sX, sY, eX, eY));
}

protected override void OnPointerUp(Model? model, PointerEventArgs e)
{
_initialClientPoint = null;
SelectionBoundsChanged?.Invoke(this, null);
}
}
}
Loading