Skip to content

Commit

Permalink
Add NodeRenderer and a way to register node components by model type
Browse files Browse the repository at this point in the history
  • Loading branch information
zHaytam committed Jun 2, 2020
1 parent b8f9426 commit afd2729
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 59 deletions.
4 changes: 2 additions & 2 deletions Blazor.Diagrams.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm", "samples\Wasm\Wasm.c
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor.Diagrams", "src\Blazor.Diagrams\Blazor.Diagrams.csproj", "{A1A4F8A5-7C97-41A8-9ADD-54E9D1725B56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestComponents", "samples\TestComponents\TestComponents.csproj", "{1CBCC8E6-111C-4364-9882-50881E4CC8B4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestComponents", "samples\TestComponents\TestComponents.csproj", "{1CBCC8E6-111C-4364-9882-50881E4CC8B4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerSide", "samples\ServerSide\ServerSide.csproj", "{B9EE910B-8FE7-490C-B20C-CEC27A2890D6}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerSide", "samples\ServerSide\ServerSide.csproj", "{B9EE910B-8FE7-490C-B20C-CEC27A2890D6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
4 changes: 2 additions & 2 deletions samples/TestComponents/Simple.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ protected override void OnInitialized()
diagramManager.AddNode(node2);
}

private Node NewNode(double x, double y)
private NodeModel NewNode(double x, double y)
{
var node = new Node(new Point(x, y));
var node = new NodeModel(new Point(x, y));
node.AddPort(PortAlignment.BOTTOM);
node.AddPort(PortAlignment.TOP);
node.AddPort(PortAlignment.LEFT);
Expand Down
4 changes: 2 additions & 2 deletions src/Blazor.Diagrams.Core/Default/DragNodeSubManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Blazor.Diagrams.Core.Default
{
public class DragNodeSubManager : DiagramSubManager
{
private Node _draggedNode;
private NodeModel _draggedNode;

public DragNodeSubManager(DiagramManager diagramManager) : base(diagramManager)
{
Expand All @@ -16,7 +16,7 @@ public DragNodeSubManager(DiagramManager diagramManager) : base(diagramManager)

private void DiagramManager_MouseDown(Model model, MouseEventArgs e)
{
if (!(model is Node node))
if (!(model is NodeModel node))
return;

_draggedNode = node;
Expand Down
2 changes: 1 addition & 1 deletion src/Blazor.Diagrams.Core/Default/SelectionSubManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private void DiagramManager_MouseDown(Model model, MouseEventArgs e)
{
DiagramManager.UnselectNode();
}
else if (model is Node node)
else if (model is NodeModel node)
{
DiagramManager.SelectNode(node);
}
Expand Down
46 changes: 32 additions & 14 deletions src/Blazor.Diagrams.Core/DiagramManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Blazor.Diagrams.Core.Default;
using Blazor.Diagrams.Core.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using System;
using System.Collections.Generic;
Expand All @@ -12,55 +13,57 @@ namespace Blazor.Diagrams.Core
{
public class DiagramManager
{
private readonly List<Node> _nodes;
private readonly List<NodeModel> _nodes;
private readonly List<DiagramSubManager> _subManagers;
private readonly Dictionary<Type, Type> _componentByModelMapping;

public event Action<Model, MouseEventArgs> MouseDown;
public event Action<Model, MouseEventArgs> MouseMove;
public event Action<Model, MouseEventArgs> MouseUp;

public event Action<Node> NodeAdded;
public event Action<Node> NodeRemoved;
public event Action<Node, bool> NodeSelectionChanged;
public event Action<Link> LinkAdded;
public event Action<NodeModel> NodeAdded;
public event Action<NodeModel> NodeRemoved;
public event Action<NodeModel, bool> NodeSelectionChanged;
public event Action<LinkModel> LinkAdded;

public DiagramManager()
{
_nodes = new List<Node>();
_nodes = new List<NodeModel>();
_subManagers = new List<DiagramSubManager>();
_componentByModelMapping = new Dictionary<Type, Type>();

RegisterSubManager<DragNodeSubManager>();
RegisterSubManager<SelectionSubManager>();
}

public ReadOnlyCollection<Node> Nodes => _nodes.AsReadOnly();
public IEnumerable<Link> AllLinks => _nodes.SelectMany(n => n.Ports.SelectMany(p => p.Links)).Distinct();
public Node SelectedNode { get; private set; }
public ReadOnlyCollection<NodeModel> Nodes => _nodes.AsReadOnly();
public IEnumerable<LinkModel> AllLinks => _nodes.SelectMany(n => n.Ports.SelectMany(p => p.Links)).Distinct();
public NodeModel SelectedNode { get; private set; }

public void AddNode(Node node)
public void AddNode(NodeModel node)
{
_nodes.Add(node);
NodeAdded?.Invoke(node);
}

public void RemoveNode(Node node)
public void RemoveNode(NodeModel node)
{
if (_nodes.Remove(node))
{
NodeRemoved?.Invoke(node);
}
}

public Link AddLink(Port source, Port target)
public LinkModel AddLink(PortModel source, PortModel target)
{
var link = new Link(source, target);
var link = new LinkModel(source, target);
source.AddLink(link);
target.AddLink(link);
LinkAdded?.Invoke(link);
return link;
}

public void SelectNode(Node node)
public void SelectNode(NodeModel node)
{
if (SelectedNode == node)
return;
Expand Down Expand Up @@ -103,6 +106,21 @@ public void UnregisterSubManager<T>() where T : DiagramSubManager
_subManagers.Remove(subManager);
}

public void RegisterModelComponent<M, C>() where M : Model where C : ComponentBase
{
var modelType = typeof(M);
if (_componentByModelMapping.ContainsKey(modelType))
throw new Exception($"Component already registered for model '{modelType.Name}'.");

_componentByModelMapping.Add(modelType, typeof(C));
}

public Type GetComponentForModel<M>(M model) where M : Model
{
var modelType = model.GetType();
return _componentByModelMapping.ContainsKey(modelType) ? _componentByModelMapping[modelType] : null;
}

internal void OnMouseDown(Model model, MouseEventArgs e) => MouseDown?.Invoke(model, e);

internal void OnMouseMove(Model model, MouseEventArgs e) => MouseMove?.Invoke(model, e);
Expand Down
20 changes: 0 additions & 20 deletions src/Blazor.Diagrams.Core/Models/Link.cs

This file was deleted.

20 changes: 20 additions & 0 deletions src/Blazor.Diagrams.Core/Models/LinkModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Blazor.Diagrams.Core.Models
{
public class LinkModel : Model
{
public LinkModel(PortModel sourcePort, PortModel targetPort)
{
SourcePort = sourcePort;
TargetPort = targetPort;
}

public LinkModel(string id, PortModel sourcePort, PortModel targetPort) : base(id)
{
SourcePort = sourcePort;
TargetPort = targetPort;
}

public PortModel SourcePort { get; }
public PortModel TargetPort { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@

namespace Blazor.Diagrams.Core.Models
{
public class Node : Model
public class NodeModel : Model
{
private List<Port> _ports = new List<Port>();
private List<PortModel> _ports = new List<PortModel>();

public Node(Point position = null)
public NodeModel(Point position = null)
{
Position = position ?? Point.Zero;
}

public Node(string id, Point position = null) : base(id)
public NodeModel(string id, Point position = null) : base(id)
{
Position = position ?? Point.Zero;
}

public Point LastOffset { get; set; }
public Point Position { get; set; }
public ReadOnlyCollection<Port> Ports => _ports.AsReadOnly();
public ReadOnlyCollection<PortModel> Ports => _ports.AsReadOnly();
public bool Selected { get; set; }

public Port AddPort(PortAlignment alignment = PortAlignment.BOTTOM)
public PortModel AddPort(PortAlignment alignment = PortAlignment.BOTTOM)
{
var port = new Port(alignment, Position);
var port = new PortModel(alignment, Position);
_ports.Add(port);
return port;
}

public Port GetPort(PortAlignment alignment) => Ports.FirstOrDefault(p => p.Alignment == alignment);
public PortModel GetPort(PortAlignment alignment) => Ports.FirstOrDefault(p => p.Alignment == alignment);

public void UpdatePosition(double clientX, double clientY)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@

namespace Blazor.Diagrams.Core.Models
{
public class Port : Model
public class PortModel : Model
{
private List<Link> _links = new List<Link>(4);
private List<LinkModel> _links = new List<LinkModel>(4);

public Port(PortAlignment alignment = PortAlignment.BOTTOM, Point position = null, Size size = null)
public PortModel(PortAlignment alignment = PortAlignment.BOTTOM, Point position = null, Size size = null)
{
Alignment = alignment;
Position = position ?? Point.Zero;
Size = size ?? Size.Zero;
}

public Port(string id, PortAlignment alignment = PortAlignment.BOTTOM, Point position = null,
public PortModel(string id, PortAlignment alignment = PortAlignment.BOTTOM, Point position = null,
Size size = null) : base(id)
{
Alignment = alignment;
Expand All @@ -26,14 +26,14 @@ public Port(string id, PortAlignment alignment = PortAlignment.BOTTOM, Point pos
public Point Offset { get; set; }
public Point Position { get; set; }
public Size Size { get; set; }
public ReadOnlyCollection<Link> Links => _links.AsReadOnly();
public ReadOnlyCollection<LinkModel> Links => _links.AsReadOnly();

public void RefreshAll()
{
Refresh();
_links.ForEach(l => l.Refresh());
}

internal void AddLink(Link link) => _links.Add(link);
internal void AddLink(LinkModel link) => _links.Add(link);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Blazor.Diagrams.Components.Base
public class LinkWidgetBaseComponent : ComponentBase, IDisposable
{
[Parameter]
public Link Link { get; set; }
public LinkModel Link { get; set; }

protected override void OnInitialized()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class NodeWidgetBaseComponent : ComponentBase, IDisposable
public DiagramManager DiagramManager { get; set; }

[Parameter]
public Node Node { get; set; }
public NodeModel Node { get; set; }

[Inject]
private IJSRuntime JSRuntime { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class PortWidgetBaseComponent : ComponentBase, IDisposable
private IJSRuntime JSRuntime { get; set; }

[Parameter]
public Port Port { get; set; }
public PortModel Port { get; set; }

protected ElementReference element;

Expand Down
2 changes: 1 addition & 1 deletion src/Blazor.Diagrams/Components/DiagramCanvas.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@onmouseup="OnMouseUp">
@foreach (var node in DiagramManager.Nodes)
{
<NodeWidget Node="node" />
<NodeRenderer Node="node" />
}
</div>
</div>
24 changes: 24 additions & 0 deletions src/Blazor.Diagrams/Components/NodeRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Blazor.Diagrams.Core;
using Blazor.Diagrams.Core.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace Blazor.Diagrams.Components
{
public class NodeRenderer : ComponentBase
{
[CascadingParameter(Name = "DiagramManager")]
public DiagramManager DiagramManager { get; set; }

[Parameter]
public NodeModel Node { get; set; }

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
var component = DiagramManager.GetComponentForModel(Node) ?? typeof(NodeWidget);
builder.OpenComponent(0, component);
builder.AddAttribute(1, "Node", Node);
builder.CloseComponent();
}
}
}

0 comments on commit afd2729

Please sign in to comment.