Skip to content

Commit 97ae0b1

Browse files
authored
Merge pull request #15 from WiseTechGlobal/RAL/WI00681235/Pointer_based_behaviors_should_support_pan_changed_new
Ral/wi00681235/pointer based behaviors should support pan changed new
2 parents 3ad39d9 + 965a28b commit 97ae0b1

28 files changed

+475
-354
lines changed

site/Site/Pages/Documentation/Controls/Overview.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Diagram.Controls.AddFor(SomeModel)
141141

142142
<p>
143143
The <code>ResizeControl</code> adds a resizer which is a box that when dragged, can resize the node. The resizer position and movement of the node is controlled using a Resizer Provider.<br />
144-
There are four <code>ResizerProvider</code>s, one for each corner. Custom resizing behavior can be created by implementing <code>IResizerProvider</code>.
144+
There are four <code>ResizerProvider</code>s, one for each corner. Custom resizing behavior can be created by inheriting and overriding <code>ResizerProvider</code>.
145145
</p>
146146

147147
<pre><code class="language-cs">

site/Site/Pages/Documentation/Diagram/Api.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
</tr>
149149
<tr>
150150
<td>PanChanged</td>
151-
<td>Action?</td>
151+
<td>Action&lt;double, double&gt;?</td>
152152
<td></td>
153153
</tr>
154154
<tr>

src/Blazor.Diagrams.Core/Behaviors/DebugEventsBehavior.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ private void Nodes_Added(NodeModel obj)
5252
Console.WriteLine($"Nodes.Added, Nodes=[{obj}]");
5353
}
5454

55-
private void Diagram_PanChanged()
55+
private void Diagram_PanChanged(double deltaX, double deltaY)
5656
{
5757
Console.WriteLine($"PanChanged, Pan={Diagram.Pan}");
5858
}

src/Blazor.Diagrams.Core/Behaviors/DragMovablesBehavior.cs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
using Blazor.Diagrams.Core.Geometry;
2-
using Blazor.Diagrams.Core.Models.Base;
1+
using Blazor.Diagrams.Core.Behaviors.Base;
32
using Blazor.Diagrams.Core.Events;
3+
using Blazor.Diagrams.Core.Geometry;
4+
using Blazor.Diagrams.Core.Models;
5+
using Blazor.Diagrams.Core.Models.Base;
46
using System;
57
using System.Collections.Generic;
6-
using Blazor.Diagrams.Core.Models;
7-
using Blazor.Diagrams.Core.Behaviors.Base;
88

99
namespace Blazor.Diagrams.Core.Behaviors;
1010

@@ -14,13 +14,16 @@ public class DragMovablesBehavior : Behavior
1414
private double? _lastClientX;
1515
private double? _lastClientY;
1616
private bool _moved;
17+
private double _totalMovedX = 0;
18+
private double _totalMovedY = 0;
1719

1820
public DragMovablesBehavior(Diagram diagram) : base(diagram)
1921
{
2022
_initialPositions = new Dictionary<MovableModel, Point>();
2123
Diagram.PointerDown += OnPointerDown;
2224
Diagram.PointerMove += OnPointerMove;
2325
Diagram.PointerUp += OnPointerUp;
26+
Diagram.PanChanged += OnPanChanged;
2427
}
2528

2629
private void OnPointerDown(Model? model, PointerEventArgs e)
@@ -62,6 +65,30 @@ private void OnPointerMove(Model? model, PointerEventArgs e)
6265
var deltaX = (e.ClientX - _lastClientX.Value) / Diagram.Zoom;
6366
var deltaY = (e.ClientY - _lastClientY.Value) / Diagram.Zoom;
6467

68+
_totalMovedX += deltaX;
69+
_totalMovedY += deltaY;
70+
71+
MoveNodes(model, _totalMovedX, _totalMovedY);
72+
73+
_lastClientX = e.ClientX;
74+
_lastClientY = e.ClientY;
75+
76+
}
77+
public void OnPanChanged(double deltaX, double deltaY)
78+
{
79+
if (_initialPositions.Count == 0 || _lastClientX == null || _lastClientY == null)
80+
return;
81+
82+
_moved = true;
83+
84+
_totalMovedX += deltaX;
85+
_totalMovedY += deltaY;
86+
87+
MoveNodes(null, _totalMovedX, _totalMovedY);
88+
}
89+
90+
private void MoveNodes(Model? model, double deltaX, double deltaY)
91+
{
6592
foreach (var (movable, initialPosition) in _initialPositions)
6693
{
6794
var ndx = ApplyGridSize(deltaX + initialPosition.X);
@@ -89,8 +116,9 @@ private void OnPointerUp(Model? model, PointerEventArgs e)
89116
movable.TriggerMoved();
90117
}
91118
}
92-
93119
_initialPositions.Clear();
120+
_totalMovedX = 0;
121+
_totalMovedY = 0;
94122
_lastClientX = null;
95123
_lastClientY = null;
96124
}
@@ -107,9 +135,9 @@ private double ApplyGridSize(double n)
107135
public override void Dispose()
108136
{
109137
_initialPositions.Clear();
110-
111138
Diagram.PointerDown -= OnPointerDown;
112139
Diagram.PointerMove -= OnPointerMove;
113140
Diagram.PointerUp -= OnPointerUp;
141+
Diagram.PanChanged -= OnPanChanged;
114142
}
115143
}

src/Blazor.Diagrams.Core/Behaviors/DragNewLinkBehavior.cs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
using Blazor.Diagrams.Core.Models;
2-
using Blazor.Diagrams.Core.Models.Base;
3-
using Blazor.Diagrams.Core.Events;
4-
using System.Linq;
5-
using Blazor.Diagrams.Core.Anchors;
1+
using Blazor.Diagrams.Core.Anchors;
62
using Blazor.Diagrams.Core.Behaviors.Base;
3+
using Blazor.Diagrams.Core.Events;
74
using Blazor.Diagrams.Core.Geometry;
5+
using Blazor.Diagrams.Core.Models;
6+
using Blazor.Diagrams.Core.Models.Base;
7+
using System.Linq;
88

99
namespace Blazor.Diagrams.Core.Behaviors;
1010

@@ -13,12 +13,15 @@ public class DragNewLinkBehavior : Behavior
1313
private PositionAnchor? _targetPositionAnchor;
1414

1515
public BaseLinkModel? OngoingLink { get; private set; }
16+
private double? _lastClientX;
17+
private double? _lastClientY;
1618

1719
public DragNewLinkBehavior(Diagram diagram) : base(diagram)
1820
{
1921
Diagram.PointerDown += OnPointerDown;
2022
Diagram.PointerMove += OnPointerMove;
2123
Diagram.PointerUp += OnPointerUp;
24+
Diagram.PanChanged += OnPanChanged;
2225
}
2326

2427
public void StartFrom(ILinkable source, double clientX, double clientY)
@@ -67,14 +70,35 @@ private void OnPointerDown(Model? model, MouseEventArgs e)
6770
OngoingLink.SetTarget(_targetPositionAnchor);
6871
Diagram.Links.Add(OngoingLink);
6972
}
73+
_lastClientX = e.ClientX;
74+
_lastClientY = e.ClientY;
7075
}
7176

7277
private void OnPointerMove(Model? model, MouseEventArgs e)
7378
{
74-
if (OngoingLink == null || model != null)
79+
if (OngoingLink == null || model != null || _lastClientX == null || _lastClientY == null)
80+
return;
81+
82+
_lastClientX = e.ClientX;
83+
_lastClientY = e.ClientY;
84+
85+
UpdateLinkPosition((double)_lastClientX, (double)_lastClientY);
86+
}
87+
88+
private void OnPanChanged(double deltaX, double deltaY)
89+
{
90+
if (OngoingLink == null || _lastClientX == null || _lastClientY == null)
91+
return;
92+
93+
UpdateLinkPosition((double)_lastClientX, (double)_lastClientY);
94+
}
95+
96+
private void UpdateLinkPosition(double clientX, double clientY)
97+
{
98+
if (OngoingLink == null)
7599
return;
76100

77-
_targetPositionAnchor!.SetPosition(CalculateTargetPosition(e.ClientX, e.ClientY));
101+
_targetPositionAnchor!.SetPosition(CalculateTargetPosition(clientX, clientY));
78102

79103
if (Diagram.Options.Links.EnableSnapping)
80104
{
@@ -119,6 +143,8 @@ private void OnPointerUp(Model? model, MouseEventArgs e)
119143
}
120144

121145
OngoingLink = null;
146+
_lastClientX = null;
147+
_lastClientY = null;
122148
}
123149

124150
private Point CalculateTargetPosition(double clientX, double clientY)
@@ -168,5 +194,6 @@ public override void Dispose()
168194
Diagram.PointerDown -= OnPointerDown;
169195
Diagram.PointerMove -= OnPointerMove;
170196
Diagram.PointerUp -= OnPointerUp;
197+
Diagram.PanChanged -= OnPanChanged;
171198
}
172199
}

src/Blazor.Diagrams.Core/Behaviors/PanBehavior.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
using Blazor.Diagrams.Core.Geometry;
2-
using Blazor.Diagrams.Core.Models.Base;
1+
using Blazor.Diagrams.Core.Behaviors.Base;
32
using Blazor.Diagrams.Core.Events;
4-
using Blazor.Diagrams.Core.Behaviors.Base;
3+
using Blazor.Diagrams.Core.Geometry;
4+
using Blazor.Diagrams.Core.Models.Base;
55

66
namespace Blazor.Diagrams.Core.Behaviors;
77

src/Blazor.Diagrams.Core/Behaviors/ScrollBehavior.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using Blazor.Diagrams.Core.Behaviors.Base;
22
using Blazor.Diagrams.Core.Events;
3-
using Blazor.Diagrams.Core.Options;
43

54
namespace Blazor.Diagrams.Core.Behaviors
65
{
@@ -16,10 +15,7 @@ protected override void OnDiagramWheel(WheelEventArgs e)
1615
if (Diagram.Container == null || !IsBehaviorEnabled(e))
1716
return;
1817

19-
var x = Diagram.Pan.X - (e.DeltaX / Diagram.Options.Zoom.ScaleFactor);
20-
var y = Diagram.Pan.Y - (e.DeltaY / Diagram.Options.Zoom.ScaleFactor);
21-
22-
Diagram.SetPan(x, y);
18+
Diagram.UpdatePan(-e.DeltaX / Diagram.Zoom, -e.DeltaY / Diagram.Zoom);
2319
}
2420
}
2521
}

src/Blazor.Diagrams.Core/Behaviors/VirtualizationBehavior.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ public VirtualizationBehavior(Diagram diagram) : base(diagram)
1212
Diagram.ContainerChanged += CheckVisibility;
1313
}
1414

15+
private void CheckVisibility(double deltaX, double deltaY)
16+
{
17+
CheckVisibility();
18+
}
19+
1520
private void CheckVisibility()
1621
{
1722
if (!Diagram.Options.Virtualization.Enabled)
1823
return;
19-
24+
2025
if (Diagram.Container == null)
2126
return;
2227

@@ -49,11 +54,11 @@ private void CheckVisibility(Model model)
4954
{
5055
if (model is not IHasBounds ihb)
5156
return;
52-
57+
5358
var bounds = ihb.GetBounds();
5459
if (bounds == null)
5560
return;
56-
61+
5762
var left = bounds.Left * Diagram.Zoom + Diagram.Pan.X;
5863
var top = bounds.Top * Diagram.Zoom + Diagram.Pan.Y;
5964
var right = left + bounds.Width * Diagram.Zoom;

src/Blazor.Diagrams.Core/Behaviors/ZoomBehavior.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,27 @@ protected override void OnDiagramWheel(WheelEventArgs e)
1515
if (Diagram.Container == null || e.DeltaY == 0 || !Diagram.Options.Zoom.Enabled || !IsBehaviorEnabled(e))
1616
return;
1717

18-
var scale = Diagram.Options.Zoom.ScaleFactor;
19-
var oldZoom = Diagram.Zoom;
20-
var deltaY = Diagram.Options.Zoom.Inverse ? e.DeltaY * -1 : e.DeltaY;
21-
var newZoom = deltaY > 0 ? oldZoom * scale : oldZoom / scale;
22-
newZoom = Math.Clamp(newZoom, Diagram.Options.Zoom.Minimum, Diagram.Options.Zoom.Maximum);
18+
var scale = Diagram.Options.Zoom.ScaleFactor;
19+
var oldZoom = Diagram.Zoom;
20+
var deltaY = Diagram.Options.Zoom.Inverse ? e.DeltaY * -1 : e.DeltaY;
21+
var newZoom = deltaY > 0 ? oldZoom * scale : oldZoom / scale;
22+
newZoom = Math.Clamp(newZoom, Diagram.Options.Zoom.Minimum, Diagram.Options.Zoom.Maximum);
2323

24-
if (newZoom < 0 || newZoom == Diagram.Zoom)
25-
return;
24+
if (newZoom < 0 || newZoom == Diagram.Zoom)
25+
return;
2626

27-
// Other algorithms (based only on the changes in the zoom) don't work for our case
28-
// This solution is taken as is from react-diagrams (ZoomCanvasAction)
29-
var clientWidth = Diagram.Container.Width;
30-
var clientHeight = Diagram.Container.Height;
31-
var widthDiff = clientWidth * newZoom - clientWidth * oldZoom;
32-
var heightDiff = clientHeight * newZoom - clientHeight * oldZoom;
33-
var clientX = e.ClientX - Diagram.Container.Left;
34-
var clientY = e.ClientY - Diagram.Container.Top;
35-
var xFactor = (clientX - Diagram.Pan.X) / oldZoom / clientWidth;
36-
var yFactor = (clientY - Diagram.Pan.Y) / oldZoom / clientHeight;
37-
var newPanX = Diagram.Pan.X - widthDiff * xFactor;
38-
var newPanY = Diagram.Pan.Y - heightDiff * yFactor;
27+
// Other algorithms (based only on the changes in the zoom) don't work for our case
28+
// This solution is taken as is from react-diagrams (ZoomCanvasAction)
29+
var clientWidth = Diagram.Container.Width;
30+
var clientHeight = Diagram.Container.Height;
31+
var widthDiff = clientWidth * newZoom - clientWidth * oldZoom;
32+
var heightDiff = clientHeight * newZoom - clientHeight * oldZoom;
33+
var clientX = e.ClientX - Diagram.Container.Left;
34+
var clientY = e.ClientY - Diagram.Container.Top;
35+
var xFactor = (clientX - Diagram.Pan.X) / oldZoom / clientWidth;
36+
var yFactor = (clientY - Diagram.Pan.Y) / oldZoom / clientHeight;
37+
var newPanX = Diagram.Pan.X - widthDiff * xFactor;
38+
var newPanY = Diagram.Pan.Y - heightDiff * yFactor;
3939

4040
Diagram.Batch(() =>
4141
{

src/Blazor.Diagrams.Core/Controls/Default/ResizeControl.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ namespace Blazor.Diagrams.Core.Controls.Default
88
{
99
public class ResizeControl : ExecutableControl
1010
{
11-
private readonly IResizerProvider _resizeProvider;
11+
private readonly ResizerProvider _resizeProvider;
1212

13-
public ResizeControl(IResizerProvider resizeProvider)
13+
public ResizeControl(ResizerProvider resizeProvider)
1414
{
1515
_resizeProvider = resizeProvider;
1616
}
@@ -23,6 +23,7 @@ public override ValueTask OnPointerDown(Diagram diagram, Model model, PointerEve
2323
{
2424
_resizeProvider.OnResizeStart(diagram, model, e);
2525
diagram.PointerMove += _resizeProvider.OnPointerMove;
26+
diagram.PanChanged += _resizeProvider.OnPanChanged;
2627
diagram.PointerUp += _resizeProvider.OnResizeEnd;
2728
diagram.PointerUp += (_, _) => OnResizeEnd(diagram);
2829

@@ -32,6 +33,7 @@ public override ValueTask OnPointerDown(Diagram diagram, Model model, PointerEve
3233
void OnResizeEnd(Diagram diagram)
3334
{
3435
diagram.PointerMove -= _resizeProvider.OnPointerMove;
36+
diagram.PanChanged -= _resizeProvider.OnPanChanged;
3537
diagram.PointerUp -= _resizeProvider.OnResizeEnd;
3638
}
3739
}

0 commit comments

Comments
 (0)