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

Use Controls to implement node resizing #10

Merged
merged 21 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from 12 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
36 changes: 36 additions & 0 deletions src/Blazor.Diagrams.Core/Controls/Default/ResizeControl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models.Base;
using Blazor.Diagrams.Core.Positions.Resizing;
using System.Threading.Tasks;

namespace Blazor.Diagrams.Core.Controls.Default
{
public class ResizeControl : ExecutableControl
{
private readonly IResizeProvider _resizeProvider;

public ResizeControl(IResizeProvider resizeProvider)
{
_resizeProvider = resizeProvider;
}

public override Point? GetPosition(Model model) => _resizeProvider.GetPosition(model);

public override ValueTask OnPointerDown(Diagram diagram, Model model, PointerEventArgs e)
{
_resizeProvider.OnResizeStart(diagram, model, e);
diagram.PointerMove += _resizeProvider.OnPointerMove;
diagram.PointerUp += _resizeProvider.OnResizeEnd;
diagram.PointerUp += (_, _) => OnResizeEnd(diagram);

return ValueTask.CompletedTask;
}

void OnResizeEnd(Diagram diagram)
{
diagram.PointerMove -= _resizeProvider.OnPointerMove;
diagram.PointerUp -= _resizeProvider.OnResizeEnd;
}
}
}
1 change: 1 addition & 0 deletions src/Blazor.Diagrams.Core/Models/NodeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class NodeModel : MovableModel, IHasBounds, IHasShape, ILinkable
private readonly List<PortModel> _ports = new();
private readonly List<BaseLinkModel> _links = new();
private Size? _size;
public Size MinimumDimensions { get; set; } = new Size(0, 0);

public event Action<NodeModel>? SizeChanged;
public event Action<NodeModel>? Moving;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Base;

namespace Blazor.Diagrams.Core.Positions.Resizing
{
public class BottomLeftResizerProvider : IResizeProvider
{
private Size _originalSize = null!;
private Point _originalPosition = null!;
private Point _originalMousePosition = null!;
private NodeModel _nodeModel = null!;

public Point? GetPosition(Model model)
{
if (model is NodeModel nodeModel && nodeModel.Size is not null)
{
return new Point(nodeModel.Position.X - 5, nodeModel.Position.Y + nodeModel.Size.Height + 5);
}
return null;
}

public void OnResizeStart(Diagram diagram, Model model, PointerEventArgs eventArgs)
{
if (model is NodeModel nodeModel)
{
_originalPosition = new Point(nodeModel.Position.X, nodeModel.Position.Y);
_originalMousePosition = new Point(eventArgs.ClientX, eventArgs.ClientY);
_originalSize = nodeModel.Size!;
_nodeModel = nodeModel;
}
}
Heathermcx marked this conversation as resolved.
Show resolved Hide resolved

public void OnPointerMove(Model? model, PointerEventArgs args)
{
if (_nodeModel is null)
{
return;
}

var height = _originalSize.Height + (args.ClientY - _originalMousePosition.Y);
var width = _originalSize.Width - (args.ClientX - _originalMousePosition.X);

var positionX = _originalPosition.X + (args.ClientX - _originalMousePosition.X);
var positionY = _originalPosition.Y;

if (width < _nodeModel.MinimumDimensions.Width)
{
width = _nodeModel.MinimumDimensions.Width;
positionX = _nodeModel.Position.X;
}
if (height < _nodeModel.MinimumDimensions.Height)
{
height = _nodeModel.MinimumDimensions.Height;
positionY = _nodeModel.Position.Y;
}

_nodeModel.SetPosition(positionX, positionY);
_nodeModel.Size = new Size(width, height);
}

public void OnResizeEnd(Model? model, PointerEventArgs args)
{
_originalSize = null!;
_originalPosition = null!;
_originalMousePosition = null!;
_nodeModel = null!;
}
Heathermcx marked this conversation as resolved.
Show resolved Hide resolved

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Base;

namespace Blazor.Diagrams.Core.Positions.Resizing
{
public class BottomRightResizerProvider : IResizeProvider
{
private Size _originalSize = null!;
private Point _originalMousePosition = null!;
private NodeModel _nodeModel = null!;

public Point? GetPosition(Model model)
{
if (model is NodeModel nodeModel && nodeModel.Size is not null)
{
return new Point(nodeModel.Position.X + nodeModel.Size.Width + 5, nodeModel.Position.Y + nodeModel.Size.Height + 5);
}
return null;
}

public void OnResizeStart(Diagram diagram, Model model, PointerEventArgs eventArgs)
{
if (model is NodeModel nodeModel)
{
_originalMousePosition = new Point(eventArgs.ClientX, eventArgs.ClientY);
_originalSize = nodeModel.Size!;
_nodeModel = nodeModel;
}
}

public void OnPointerMove(Model? model, PointerEventArgs args)
{
if (_nodeModel is null)
{
return;
}
var positionX = _nodeModel.Position.X;
var positionY = _nodeModel.Position.Y;

var height = _originalSize.Height + (args.ClientY - _originalMousePosition.Y);
var width = _originalSize.Width + (args.ClientX - _originalMousePosition.X);

if (width < _nodeModel.MinimumDimensions.Width)
{
width = _nodeModel.MinimumDimensions.Width;
positionX = _nodeModel.Position.X;
}
if (height < _nodeModel.MinimumDimensions.Height)
{
height = _nodeModel.MinimumDimensions.Height;
positionY = _nodeModel.Position.Y;
}

_nodeModel.SetPosition(positionX, positionY);
_nodeModel.Size = new Size(width, height);
}

public void OnResizeEnd(Model? model, PointerEventArgs args)
{
_originalSize = null!;
_originalMousePosition = null!;
_nodeModel = null!;
}

}
}
13 changes: 13 additions & 0 deletions src/Blazor.Diagrams.Core/Positions/Resizing/IResizeProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Base;

namespace Blazor.Diagrams.Core.Positions.Resizing
{
public interface IResizeProvider : IPositionProvider
{
public void OnResizeStart(Diagram diagram, Model model, PointerEventArgs eventArgs);
public void OnPointerMove(Model? model, PointerEventArgs args);
public void OnResizeEnd(Model? model, PointerEventArgs args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Base;

namespace Blazor.Diagrams.Core.Positions.Resizing
{
public class TopLeftResizerProvider : IResizeProvider
{
private Size _originalSize = null!;
private Point _originalPosition = null!;
private Point _originalMousePosition = null!;
private NodeModel _nodeModel = null!;

public Point? GetPosition(Model model)
{
if (model is NodeModel nodeModel && nodeModel.Size is not null)
{
return new Point(nodeModel.Position.X - 5, nodeModel.Position.Y - 5);
}
return null;
}

public void OnResizeStart(Diagram diagram, Model model, PointerEventArgs eventArgs)
{
if (model is NodeModel nodeModel)
{
_originalPosition = new Point(nodeModel.Position.X, nodeModel.Position.Y);
_originalMousePosition = new Point(eventArgs.ClientX, eventArgs.ClientY);
_originalSize = nodeModel.Size!;
_nodeModel = nodeModel;
}
}

public void OnPointerMove(Model? model, PointerEventArgs args)
{
if (_nodeModel is null)
{
return;
}

var height = _originalSize.Height - (args.ClientY - _originalMousePosition.Y);
var width = _originalSize.Width - (args.ClientX - _originalMousePosition.X);

var positionX = _originalPosition.X + (args.ClientX - _originalMousePosition.X);
var positionY = _originalPosition.Y + (args.ClientY - _originalMousePosition.Y);

if (width < _nodeModel.MinimumDimensions.Width)
{
width = _nodeModel.MinimumDimensions.Width;
positionX = _nodeModel.Position.X;
}
if (height < _nodeModel.MinimumDimensions.Height)
{
height = _nodeModel.MinimumDimensions.Height;
positionY = _nodeModel.Position.Y;
}

_nodeModel.SetPosition(positionX, positionY);
_nodeModel.Size = new Size(width, height);
}

public void OnResizeEnd(Model? model, PointerEventArgs args)
{
_originalSize = null!;
_originalPosition = null!;
_originalMousePosition = null!;
_nodeModel = null!;
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using Blazor.Diagrams.Core.Events;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Base;

namespace Blazor.Diagrams.Core.Positions.Resizing
{
public class TopRightResizerProvider : IResizeProvider
{
private Size _originalSize = null!;
private Point _originalPosition = null!;
private Point _originalMousePosition = null!;
private NodeModel _nodeModel = null!;

public Point? GetPosition(Model model)
{
if (model is NodeModel nodeModel && nodeModel.Size is not null)
{
return new Point(nodeModel.Position.X + nodeModel.Size.Width + 5, nodeModel.Position.Y - 5);
}
return null;
}

public void OnResizeStart(Diagram diagram, Model model, PointerEventArgs eventArgs)
{
if (model is NodeModel nodeModel)
{
_originalPosition = new Point(nodeModel.Position.X, nodeModel.Position.Y);
_originalMousePosition = new Point(eventArgs.ClientX, eventArgs.ClientY);
_originalSize = nodeModel.Size!;
_nodeModel = nodeModel;
}
}

public void OnPointerMove(Model? model, PointerEventArgs args)
{
if (_nodeModel is null)
{
return;
}
var height = _originalSize.Height - (args.ClientY - _originalMousePosition.Y);
var width = _originalSize.Width + (args.ClientX - _originalMousePosition.X);

var positionX = _originalPosition.X;
var positionY = _originalPosition.Y + (args.ClientY - _originalMousePosition.Y);

if (width < _nodeModel.MinimumDimensions.Width)
{
width = _nodeModel.MinimumDimensions.Width;
positionX = _nodeModel.Position.X;
}
if (height < _nodeModel.MinimumDimensions.Height)
{
height = _nodeModel.MinimumDimensions.Height;
positionY = _nodeModel.Position.Y;
}

_nodeModel.SetPosition(positionX, positionY);
_nodeModel.Size = new Size(width, height);
Heathermcx marked this conversation as resolved.
Show resolved Hide resolved
}

public void OnResizeEnd(Model? model, PointerEventArgs args)
{
_originalSize = null!;
_originalPosition = null!;
_originalMousePosition = null!;
_nodeModel = null!;
}

}
}
3 changes: 2 additions & 1 deletion src/Blazor.Diagrams/BlazorDiagram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public BlazorDiagram(BlazorDiagramOptions? options = null)
[typeof(RemoveControl)] = typeof(RemoveControlWidget),
[typeof(BoundaryControl)] = typeof(BoundaryControlWidget),
[typeof(DragNewLinkControl)] = typeof(DragNewLinkControlWidget),
[typeof(ArrowHeadControl)] = typeof(ArrowHeadControlWidget)
[typeof(ArrowHeadControl)] = typeof(ArrowHeadControlWidget),
[typeof(ResizeControl)] = typeof(ResizeControlWidget)
};

Options = options ?? new BlazorDiagramOptions();
Expand Down
10 changes: 10 additions & 0 deletions src/Blazor.Diagrams/Components/Controls/ResizeControlWidget.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="default-node-resizer" />

@code
{
[Parameter]
public ResizeControl Control { get; set; } = null!;

[Parameter]
public Model Model { get; set; } = null!;
}
10 changes: 9 additions & 1 deletion src/Blazor.Diagrams/Components/NodeWidget.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="default-node @(Node.Group != null ? "grouped" : "") @(Node.Selected ? "selected" : "")">
<div class="default-node @(Node.Group != null ? "grouped" : "") @(Node.Selected ? "selected" : "")" style=@GenerateStyle()>
@(Node.Title ?? "Title")
@foreach (var port in Node.Ports)
{
Expand All @@ -11,4 +11,12 @@
[Parameter]
public NodeModel Node { get; set; } = null!;

private string GenerateStyle()
{
if (Node.Size is not null)
{
return $"width: {Node.Size.Width}px; height: {Node.Size.Height}px";
}
return string.Empty;
}
}
8 changes: 8 additions & 0 deletions src/Blazor.Diagrams/wwwroot/default.styles.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading