From 17c04f5f90a3be776644e3da2d69b01ce24c9b96 Mon Sep 17 00:00:00 2001 From: Heather <30523814+Heathermcx@users.noreply.github.com> Date: Wed, 17 May 2023 10:41:08 +1000 Subject: [PATCH 1/2] Nodes can be made resizable (#2) Resizers can be added to a node. Dragging a resizer resizes the node. --------- Co-authored-by: Matt Swain --- .../Behaviors/ResizeBehavior.cs | 127 ++++++++++++ src/Blazor.Diagrams.Core/Diagram.cs | 1 + src/Blazor.Diagrams.Core/Models/GroupModel.cs | 4 + src/Blazor.Diagrams.Core/Models/NodeModel.cs | 15 ++ .../Models/ResizerModel.cs | 17 ++ .../Models/ResizerPosition.cs | 13 ++ .../Components/DefaultGroupWidget.razor | 5 +- .../Components/NodeWidget.razor | 17 +- .../Components/Renderers/ResizerRenderer.cs | 39 ++++ .../wwwroot/default.styles.css | 65 ++++++ .../wwwroot/default.styles.min.css | 2 +- .../wwwroot/default.styles.min.css.gz | Bin 683 -> 789 bytes src/Blazor.Diagrams/wwwroot/style.css | 1 + src/Blazor.Diagrams/wwwroot/style.min.css | 2 +- src/Blazor.Diagrams/wwwroot/style.min.css.gz | Bin 409 -> 414 bytes .../Behaviors/ResizeBehaviorTest.cs | 195 ++++++++++++++++++ .../Renderers/ResizersRendererTest.cs | 28 +++ 17 files changed, 527 insertions(+), 4 deletions(-) create mode 100644 src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs create mode 100644 src/Blazor.Diagrams.Core/Models/ResizerModel.cs create mode 100644 src/Blazor.Diagrams.Core/Models/ResizerPosition.cs create mode 100644 src/Blazor.Diagrams/Components/Renderers/ResizerRenderer.cs create mode 100644 tests/Blazor.Diagrams.Core.Tests/Behaviors/ResizeBehaviorTest.cs create mode 100644 tests/Blazor.Diagrams.Tests/Components/Renderers/ResizersRendererTest.cs diff --git a/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs b/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs new file mode 100644 index 000000000..e9b837a61 --- /dev/null +++ b/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs @@ -0,0 +1,127 @@ +using Blazor.Diagrams.Core.Geometry; +using Blazor.Diagrams.Core.Models.Base; +using Blazor.Diagrams.Core.Events; +using Blazor.Diagrams.Core.Routers; +using Blazor.Diagrams.Core.Models; + +namespace Blazor.Diagrams.Core.Behaviors +{ + public class ResizeBehavior : Behavior + { + private Size _originalSize = null!; + private Point _originalPosition = null!; + private Point _originalMousePosition = null!; + private ResizerModel? _resizer = null; + + public ResizeBehavior(Diagram diagram) : base(diagram) + { + Diagram.PointerDown += OnPointerDown; + Diagram.PointerMove += OnPointerMove; + Diagram.PointerUp += OnPointerUp; + } + + private void OnPointerDown(Model? model, PointerEventArgs e) + { + if (model is not ResizerModel) + return; + + _resizer = (ResizerModel)model; + _originalPosition = new Point(_resizer.Parent.Position.X, _resizer.Parent.Position.Y); + _originalMousePosition = new Point(e.ClientX, e.ClientY); + _originalSize = _resizer.Parent.Size!; + } + + private void OnPointerMove(Model? model, PointerEventArgs args) + { + if (_resizer == null) + return; + Resize(_resizer.Alignment, _resizer.Parent, args); + } + + private void OnPointerUp(Model? model, PointerEventArgs args) + { + _resizer = null; + } + + void Resize(ResizerPosition resizerAlignment, NodeModel model, PointerEventArgs args) + { + var width = _originalSize.Width; + var height = _originalSize.Height; + var positionX = model.Position.X; + var positionY = model.Position.Y; + + if (resizerAlignment == ResizerPosition.TopLeft) + { + height = _originalSize.Height - (args.ClientY - _originalMousePosition.Y); + width = _originalSize.Width - (args.ClientX - _originalMousePosition.X); + + positionX = _originalPosition.X + (args.ClientX - _originalMousePosition.X); + positionY = _originalPosition.Y + (args.ClientY - _originalMousePosition.Y); + } + else if (resizerAlignment == ResizerPosition.TopRight) + { + height = _originalSize.Height - (args.ClientY - _originalMousePosition.Y); + width = _originalSize.Width + (args.ClientX - _originalMousePosition.X); + + positionX = _originalPosition.X; + positionY = _originalPosition.Y + (args.ClientY - _originalMousePosition.Y); + } + else if (resizerAlignment == ResizerPosition.BottomLeft) + { + height = _originalSize.Height + (args.ClientY - _originalMousePosition.Y); + width = _originalSize.Width - (args.ClientX - _originalMousePosition.X); + + positionX = _originalPosition.X + (args.ClientX - _originalMousePosition.X); + positionY = _originalPosition.Y; + } + else if (resizerAlignment == ResizerPosition.BottomRight) + { + height = _originalSize.Height + (args.ClientY - _originalMousePosition.Y); + width = _originalSize.Width + (args.ClientX - _originalMousePosition.X); + } + else if (resizerAlignment == ResizerPosition.Top) + { + height = _originalSize.Height - (args.ClientY - _originalMousePosition.Y); + + positionY = _originalPosition.Y + (args.ClientY - _originalMousePosition.Y); + } + else if (resizerAlignment == ResizerPosition.Right) + { + width = _originalSize.Width + (args.ClientX - _originalMousePosition.X); + } + else if (resizerAlignment == ResizerPosition.Left) + { + width = _originalSize.Width - (args.ClientX - _originalMousePosition.X); + + positionX = _originalPosition.X + (args.ClientX - _originalMousePosition.X); + } + else if (resizerAlignment == ResizerPosition.Bottom) + { + height = _originalSize.Height + (args.ClientY - _originalMousePosition.Y); + } + + if (width < model.MinimumDimensions.Width) + { + width = model.MinimumDimensions.Width; + positionX = model.Position.X; + } + if (height < model.MinimumDimensions.Height) + { + height = model.MinimumDimensions.Height; + positionY = model.Position.Y; + } + + model.SetPosition(positionX, positionY); + model.Size = new Size(width, height); + + model.Refresh(); + } + + public override void Dispose() + { + Diagram.PointerDown -= OnPointerDown; + Diagram.PointerMove -= OnPointerMove; + Diagram.PointerUp -= OnPointerUp; + } + } +} diff --git a/src/Blazor.Diagrams.Core/Diagram.cs b/src/Blazor.Diagrams.Core/Diagram.cs index 3284429ba..4e9edd896 100644 --- a/src/Blazor.Diagrams.Core/Diagram.cs +++ b/src/Blazor.Diagrams.Core/Diagram.cs @@ -65,6 +65,7 @@ protected Diagram() RegisterBehavior(new KeyboardShortcutsBehavior(this)); RegisterBehavior(new ControlsBehavior(this)); RegisterBehavior(new VirtualizationBehavior(this)); + RegisterBehavior(new ResizeBehavior(this)); } public abstract DiagramOptions Options { get; } diff --git a/src/Blazor.Diagrams.Core/Models/GroupModel.cs b/src/Blazor.Diagrams.Core/Models/GroupModel.cs index 88a9636fc..7116a982b 100644 --- a/src/Blazor.Diagrams.Core/Models/GroupModel.cs +++ b/src/Blazor.Diagrams.Core/Models/GroupModel.cs @@ -93,6 +93,10 @@ public void Ungroup() _children.Clear(); } + public override ResizerModel AddResizer(ResizerModel model) => throw new NotImplementedException(); + + public override bool RemoveResizer(ResizerModel model) => throw new NotImplementedException(); + private void Initialize(IEnumerable children) { foreach (var child in children) diff --git a/src/Blazor.Diagrams.Core/Models/NodeModel.cs b/src/Blazor.Diagrams.Core/Models/NodeModel.cs index be5430a45..4599c12ba 100644 --- a/src/Blazor.Diagrams.Core/Models/NodeModel.cs +++ b/src/Blazor.Diagrams.Core/Models/NodeModel.cs @@ -10,6 +10,7 @@ public class NodeModel : MovableModel, IHasBounds, IHasShape, ILinkable { private readonly List _ports = new(); private readonly List _links = new(); + private readonly List _resizers = new(); private Size? _size; public event Action? SizeChanged; @@ -42,6 +43,7 @@ public Size? Size public IReadOnlyList Ports => _ports; public IReadOnlyList Links => _links; public IEnumerable PortLinks => Ports.SelectMany(p => p.Links); + public IReadOnlyList Resizers => _resizers; #region Ports @@ -140,6 +142,19 @@ public virtual void UpdatePositionSilently(double deltaX, double deltaY) public virtual bool CanAttachTo(ILinkable other) => other is not PortModel && other is not BaseLinkModel; + public Size MinimumDimensions { get; set; } = new Size(0, 0); + + public ResizerModel AddResizer(ResizerPosition alignment) + => AddResizer(new ResizerModel(this, alignment)); + + public virtual ResizerModel AddResizer(ResizerModel model) + { + _resizers.Add(model); + return model; + } + + public virtual bool RemoveResizer(ResizerModel model) => _resizers.Remove(model); + private void UpdatePortPositions(double deltaX, double deltaY) { // Save some JS calls and update ports directly here diff --git a/src/Blazor.Diagrams.Core/Models/ResizerModel.cs b/src/Blazor.Diagrams.Core/Models/ResizerModel.cs new file mode 100644 index 000000000..3b171cdfa --- /dev/null +++ b/src/Blazor.Diagrams.Core/Models/ResizerModel.cs @@ -0,0 +1,17 @@ +using Blazor.Diagrams.Core.Geometry; +using Blazor.Diagrams.Core.Models.Base; +using System; + +namespace Blazor.Diagrams.Core.Models; + +public class ResizerModel : Model +{ + public ResizerModel(NodeModel parent, ResizerPosition alignment) + { + Parent = parent; + Alignment = alignment; + } + + public NodeModel Parent { get; } + public ResizerPosition Alignment { get; } +} \ No newline at end of file diff --git a/src/Blazor.Diagrams.Core/Models/ResizerPosition.cs b/src/Blazor.Diagrams.Core/Models/ResizerPosition.cs new file mode 100644 index 000000000..b8a6d1842 --- /dev/null +++ b/src/Blazor.Diagrams.Core/Models/ResizerPosition.cs @@ -0,0 +1,13 @@ +namespace Blazor.Diagrams.Core.Models; + +public enum ResizerPosition +{ + TopRight, + TopLeft, + BottomRight, + BottomLeft, + Top, + Bottom, + Left, + Right +} diff --git a/src/Blazor.Diagrams/Components/DefaultGroupWidget.razor b/src/Blazor.Diagrams/Components/DefaultGroupWidget.razor index 3e40af066..9ad54f3de 100644 --- a/src/Blazor.Diagrams/Components/DefaultGroupWidget.razor +++ b/src/Blazor.Diagrams/Components/DefaultGroupWidget.razor @@ -2,7 +2,6 @@ [Parameter] public GroupModel Group { get; set; } = null!; - } @@ -10,4 +9,8 @@ @foreach (var port in Group.Ports) { +} +@foreach (var resizer in Group.Resizers) +{ + } \ No newline at end of file diff --git a/src/Blazor.Diagrams/Components/NodeWidget.razor b/src/Blazor.Diagrams/Components/NodeWidget.razor index 37ff3da8d..33ac57b86 100644 --- a/src/Blazor.Diagrams/Components/NodeWidget.razor +++ b/src/Blazor.Diagrams/Components/NodeWidget.razor @@ -1,9 +1,16 @@ -
+
@(Node.Title ?? "Title") @foreach (var port in Node.Ports) { } + @foreach (var resizer in Node.Resizers) + { + + }
@code { @@ -11,4 +18,12 @@ [Parameter] public NodeModel Node { get; set; } = null!; + private string GenerateStyle() + { + if (Node.Size is not null) + { + return FormattableString.Invariant($"width: {Node.Size.Width}px; height: {Node.Size.Height}px"); + } + return string.Empty; + } } \ No newline at end of file diff --git a/src/Blazor.Diagrams/Components/Renderers/ResizerRenderer.cs b/src/Blazor.Diagrams/Components/Renderers/ResizerRenderer.cs new file mode 100644 index 000000000..ebd498708 --- /dev/null +++ b/src/Blazor.Diagrams/Components/Renderers/ResizerRenderer.cs @@ -0,0 +1,39 @@ +using Blazor.Diagrams.Core.Models; +using Blazor.Diagrams.Extensions; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.AspNetCore.Components.Web; +using System; +using PointerEventArgs = Microsoft.AspNetCore.Components.Web.PointerEventArgs; + +namespace Blazor.Diagrams.Components.Renderers; + +public class ResizerRenderer : ComponentBase, IDisposable +{ + [CascadingParameter] public BlazorDiagram BlazorDiagram { get; set; } = null!; + [Parameter] public ResizerModel Resizer { get; set; } = null!; + [Parameter] public string ResizerClass { get; set; } = "resizer"; + + public void Dispose() + { + } + + protected override bool ShouldRender() + { + return false; + } + + protected override void BuildRenderTree(RenderTreeBuilder builder) + { + builder.OpenElement(1, "div"); + builder.AddAttribute(2, "class", $"{ResizerClass} {Resizer.Alignment.ToString().ToLower()}"); + builder.AddAttribute(3, "onpointerdown", EventCallback.Factory.Create(this, OnPointerDown)); + builder.AddEventStopPropagationAttribute(4, "onpointerdown", true); + builder.CloseElement(); + } + + private void OnPointerDown(PointerEventArgs e) + { + BlazorDiagram.TriggerPointerDown(Resizer, e.ToCore()); + } +} diff --git a/src/Blazor.Diagrams/wwwroot/default.styles.css b/src/Blazor.Diagrams/wwwroot/default.styles.css index b095bbe4e..2b42aeb4c 100644 --- a/src/Blazor.Diagrams/wwwroot/default.styles.css +++ b/src/Blazor.Diagrams/wwwroot/default.styles.css @@ -127,4 +127,69 @@ g.diagram-group.default.selected > rect { transform: translate(-50%, -50%); } +.resizer { + width: 5px; + height: 5px; + background-color: #f5f5f5; + border: 1px solid #6e9fd4; + position: absolute; + visibility: hidden; +} + +.resizer.topleft { + left: -5px; + top: -5px; + cursor: nwse-resize; +} + +.resizer.topright { + right: -5px; + top: -5px; + cursor: nesw-resize; +} + +.resizer.bottomleft { + left: -5px; + bottom: -5px; + cursor: nesw-resize; +} + +.resizer.bottomright { + right: -5px; + bottom: -5px; + cursor: nwse-resize; +} + +.resizer.left { + left: -5px; + top: 50%; + cursor: w-resize; +} + +.resizer.right { + right: -5px; + top: 50%; + cursor: w-resize; +} + +.resizer.bottom { + left: 50%; + bottom: -5px; + cursor: n-resize; +} + +.resizer.top { + left: 50%; + top: -5px; + cursor: n-resize; +} + +.default-node.selected .resizer { + visibility: visible; +} + +.group.selected > .resizer { + visibility: visible; +} + /*# sourceMappingURL=wwwroot\default.styles.css.map */ diff --git a/src/Blazor.Diagrams/wwwroot/default.styles.min.css b/src/Blazor.Diagrams/wwwroot/default.styles.min.css index c44adedc3..a576db5cd 100644 --- a/src/Blazor.Diagrams/wwwroot/default.styles.min.css +++ b/src/Blazor.Diagrams/wwwroot/default.styles.min.css @@ -1 +1 @@ -.default-node{width:100px;height:80px;border-radius:10px;background-color:#f5f5f5;border:1px solid #e8e8e8;-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;}.default-node.selected{border:1px solid #6e9fd4;}.default-node.selected .diagram-port{border:1px solid #6e9fd4;}.default-node .diagram-port,.default.diagram-group .diagram-port{width:20px;height:20px;margin:-10px;border-radius:50%;background-color:#f5f5f5;border:1px solid #d4d4d4;cursor:pointer;position:absolute;}.default-node .diagram-port:hover,.default-node .diagram-port.has-links,.default.diagram-group .diagram-port.has-links{background-color:#000;}.default-node .diagram-port.bottom,.default.diagram-group .diagram-port.bottom{bottom:0;left:50%;}.default-node .diagram-port.bottomleft,.default.diagram-group .diagram-port.bottomleft{bottom:0;left:0;}.default-node .diagram-port.bottomright,.default.diagram-group .diagram-port.bottomright{bottom:0;right:0;}.default-node .diagram-port.top,.default.diagram-group .diagram-port.top{top:0;left:50%;}.default-node .diagram-port.topleft,.default.diagram-group .diagram-port.topleft{top:0;left:0;}.default-node .diagram-port.topright,.default.diagram-group .diagram-port.topright{top:0;right:0;}.default-node .diagram-port.left,.default.diagram-group .diagram-port.left{left:0;top:50%;}.default-node .diagram-port.right,.default.diagram-group .diagram-port.right{right:0;top:50%;}.diagram-navigator.default{position:absolute;bottom:10px;right:10px;border:3px solid #9ba8b0;border-radius:15px;padding:20px;background-color:#fff;}div.diagram-group.default{outline:2px solid #000;background:#c6c6c6;}div.diagram-group.default.selected{outline:2px solid #6e9fd4;}g.diagram-group.default rect{outline:2px solid #000;fill:#c6c632;}g.diagram-group.default.selected>rect{outline:2px solid #008000;}.diagram-link div.default-link-label{display:inline-block;color:#fff;background-color:#6e9fd4;border-radius:.25rem;padding:.25rem;text-align:center;font-size:.875rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-width:3rem;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);} \ No newline at end of file +.default-node{width:100px;height:80px;border-radius:10px;background-color:#f5f5f5;border:1px solid #e8e8e8;-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;}.default-node.selected{border:1px solid #6e9fd4;}.default-node.selected .port{border:1px solid #6e9fd4;}.default-node .port,.default.group .port{width:20px;height:20px;margin:-10px;border-radius:50%;background-color:#f5f5f5;border:1px solid #d4d4d4;cursor:pointer;position:absolute;}.default-node .port:hover,.default-node .port.has-links,.default.group .port.has-links{background-color:#000;}.default-node .port.bottom,.default.group .port.bottom{bottom:0;left:50%;}.default-node .port.bottomleft,.default.group .port.bottomleft{bottom:0;left:0;}.default-node .port.bottomright,.default.group .port.bottomright{bottom:0;right:0;}.default-node .port.top,.default.group .port.top{top:0;left:50%;}.default-node .port.topleft,.default.group .port.topleft{top:0;left:0;}.default-node .port.topright,.default.group .port.topright{top:0;right:0;}.default-node .port.left,.default.group .port.left{left:0;top:50%;}.default-node .port.right,.default.group .port.right{right:0;top:50%;}.diagram-navigator.default{position:absolute;bottom:10px;right:10px;border:3px solid #9ba8b0;border-radius:15px;padding:20px;background-color:#fff;}div.group.default{outline:2px solid #000;background:#c6c6c6;}div.group.default.selected{outline:2px solid #6e9fd4;}g.group.default rect{outline:2px solid #000;fill:#c6c632;}g.group.default.selected>rect{outline:2px solid #008000;}.link div.link-label{display:inline-block;color:#fff;background-color:#6e9fd4;border-radius:.25rem;padding:.25rem;text-align:center;font-size:.875rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-width:3rem;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);}.resizer{width:5px;height:5px;background-color:#f5f5f5;border:1px solid #6e9fd4;position:absolute;visibility:hidden;}.resizer.topleft{left:-5px;top:-5px;cursor:nwse-resize;}.resizer.topright{right:-5px;top:-5px;cursor:nesw-resize;}.resizer.bottomleft{left:-5px;bottom:-5px;cursor:nesw-resize;}.resizer.bottomright{right:-5px;bottom:-5px;cursor:nwse-resize;}.resizer.left{left:-5px;top:50%;cursor:w-resize;}.resizer.right{right:-5px;top:50%;cursor:w-resize;}.resizer.bottom{left:50%;bottom:-5px;cursor:n-resize;}.resizer.top{left:50%;top:-5px;cursor:n-resize;}.default-node.selected .resizer{visibility:visible;}.group.selected>.resizer{visibility:visible;} \ No newline at end of file diff --git a/src/Blazor.Diagrams/wwwroot/default.styles.min.css.gz b/src/Blazor.Diagrams/wwwroot/default.styles.min.css.gz index 905f20cd3084e4807fd8feb323b3f30ca017d835..a4b0e0b99d8c8256568ab3d85c261f9e424f7a28 100644 GIT binary patch literal 789 zcmV+w1M2)AiwFP!000003bj^iZsQ;jzDlHOrB(`-lQz34mi8_0)E%nZGWs#5}3y~4`!JB{rxARkdcZTBqW8~g;8_Fn>a47$q`t7GUImkQryJGUBHyeY3MEjgpBJJ`FGpbMlYW>6}xNFNE67aXs) zR?LYa_oecb+{bITqV2;v_8j+#N36|L%X^&iwhz{W|7@U?ni(bqR=|m2XGkd1B_}U< z5Mxg(G|D(!hctH{C4_L63w!`!KqallnCcIR87OooI6x@vg-ig3#9x&*EPJunWskzN zf384A9&39>2qLMxW*sR#7RH`K($ky>4ldE2Xl5sH<>0C_=w4h{~D3Xfv(I zUHt7U1xcUWN)DCMR<4xHC!)Jml3KaSK+t7;lxI-u04F*UjW`o09So~y-=?m{aU8T3 zrP3H#gaK=w&A9u)al#=pJ{1c{PG$+s@!ugXdZyg{ECG6f9?>7?AdM`;P?mACpATcS zGV=j8%puUc9}97{+y-bdqIqw;D~%HlXf~z=Pii+>2L>pN4Zl z8Q)Yj(xAWaW8XB-DcPs-`%$p7vL&IEiM;O8KpSRR@pP%;B9ZhbwRI> z?+)MH3MlulQ~;%YZ}PFuN?DCLs~O|Gw)eQ5Xm-|q&O_|$4tD*$a_+hf;v@xrYu|h( zoEl2GJe-n2Zl)P)A{eJS+U^t-U9y{_fvXvhiOfFlNV8YK(f)^*X{SV`Em|E57E*v6 z6Y@1g)l=exP%we&hx&17!zdzjCRKs`&W=a8N46^0?(4y0e<1P!`z=!7qEpS7*!5Gw zZND%Dnk-LS;>~ebrWq&Vq5;+7W4&RwhBZN7rkaCy zxi{K$?Ps+orbGHczXQR#H>S}E7z{?atkTS}?r9G>7tCm{GD&4GKl5j$t)jtY`z?1m Tb^CX1zbO0|zDlHOrACSoAx)baY42k2K)f+FvQ3gU>dE%U z9%-+zwt)a85AtJWCBfrw=9?Ge{QdnWppcP@8zdx!(}7X5#mg`(kMR~*zBPE`o)f7k zD5MBwmA2$aA=GD~RTc(4V+ZI5=9qv}ddFSv0pE{AYqvYG#-eSOF)7?IEU2mz;dy zUW}cr&?w_@?91GKkPyOIE^rFMfQnmGf?O=uxFvP1sNIW3x8GGu~E#^u?_>t(3O7QZk>YbJa;=ag~9aq2R6DgIe4`1Y4pJXJV%(h26nV z<50pdyy;DlNMmF%ji|=j3c4R0#vC%^Q#gUaVIN^}_-{;;B2ljHj}Uo&KDQ5jiI zqp-k}{Y=i4#ZFID1MU;t_xpkTwCILlQf8)m?_F=4b_92G^ML2I+pWVr>kUYdJdgW0F5LN-bG{VH5rY)L3(BCn^=g)x(5@fT(LVJK&pWM%AI z4LItk+}qsQ!B6R{TQ`h!Q~QFocJAhvb!Wa00|h0{qn8kxV!V1EF1|6CQyBGt@<2B5ur1w3hbZk-wAj|wu=|;Ywm5| Rf!sO%`Ul{II$Grk008_RO;G>< diff --git a/src/Blazor.Diagrams/wwwroot/style.css b/src/Blazor.Diagrams/wwwroot/style.css index 35c0aaa30..54ddf490a 100644 --- a/src/Blazor.Diagrams/wwwroot/style.css +++ b/src/Blazor.Diagrams/wwwroot/style.css @@ -43,6 +43,7 @@ user-select: none; cursor: move; pointer-events: all; + box-sizing: border-box; } .diagram-node.locked { diff --git a/src/Blazor.Diagrams/wwwroot/style.min.css b/src/Blazor.Diagrams/wwwroot/style.min.css index 4abcd9d42..877edb17d 100644 --- a/src/Blazor.Diagrams/wwwroot/style.min.css +++ b/src/Blazor.Diagrams/wwwroot/style.min.css @@ -1 +1 @@ -.diagram-canvas{width:100%;height:100%;position:relative;outline:none;overflow:hidden;cursor:-webkit-grab;cursor:grab;touch-action:none;}.diagram-svg-layer,.diagram-html-layer{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.html-layer,.svg-layer{position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.diagram-node{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;}.diagram-node.locked{cursor:pointer;}.diagram-link{pointer-events:visiblePainted;cursor:pointer;}.diagram-navigator{z-index:10;}.diagram-navigator .current-view{position:absolute;border:2px solid #000;}.diagram-group{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;}.diagram-group .children{position:absolute;overflow:visible;pointer-events:none;}.diagram-link foreignObject.diagram-link-label{overflow:visible;pointer-events:none;}div.diagram-control{position:absolute;}.executable.diagram-control{pointer-events:all;cursor:pointer;} \ No newline at end of file +.diagram-canvas{width:100%;height:100%;position:relative;outline:0;overflow:hidden;cursor:-webkit-grab;cursor:grab;touch-action:none;}.diagram-svg-layer,.diagram-html-layer{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.html-layer,.svg-layer{position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.node{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;box-sizing:border-box;}.node.locked{cursor:pointer;}.link{pointer-events:visiblePainted;cursor:pointer;}.diagram-navigator{z-index:10;}.diagram-navigator .current-view{position:absolute;border:2px solid #000;}.group{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;}.group .children{position:absolute;overflow:visible;pointer-events:none;}.link foreignObject.link-label{overflow:visible;pointer-events:none;}div.control{position:absolute;}.executable.control{pointer-events:all;cursor:pointer;} \ No newline at end of file diff --git a/src/Blazor.Diagrams/wwwroot/style.min.css.gz b/src/Blazor.Diagrams/wwwroot/style.min.css.gz index e72cb7d8af23d7af571c773a260d0f0ccfe835f3..5906b3b1eb512291df63559103566d7667b9999a 100644 GIT binary patch literal 414 zcmV;P0b%|hiwFP!000003eA#1PQx$|MXwSGv8$uNGC2fX!HK8IP{&i*6Sp+tWGpxm zS76$t0X0Tq$tt5i@%NkY|9t<*4eHkGUNzc99mWG1?#hRvxUV|Ew&SVZQ$R*?r3b4S zBUCi7MF(Y3Q3SuWbSOJC23*w)K9Dcf0qPyH68HM5U23MG>6C6RevTYeZwp0;t+M(R z{AQ6l?(L+FOnbS{!j|RZFLXs!6EpQvER4DiWCsRO&@p%g5gdoYIb18*s#Cjy>4~$XgCaXa?4D{>N{tp>Ch{3pM3M ICg=nJ0Cii!KmY&$ literal 409 zcmV;K0cQRmiwFP!000003eA*JQiCuMhOfem<6Fa^k8lXRLLggM8?v2b3020E`QVYf zg4>p&ZPOVaeIoox{(S$kg{$d(~(cb(lsp+?5YSabIqM*s{isH9Z>uK2jyZW|!D#_NNHIgpDchxbe#y$TQ znKYyHoO`NYgy?Kaeuo(parameters => parameters + .Add(n => n.Resizer, resizer) + .Add(n => n.ResizerClass, "my-resizer") + .Add(n => n.BlazorDiagram, new BlazorDiagram())); + + component.MarkupMatches("
"); + } + } +} From c63d90435e67cddefd997626696ca13cf50fbfc5 Mon Sep 17 00:00:00 2001 From: Heather <30523814+Heathermcx@users.noreply.github.com> Date: Wed, 24 May 2023 15:03:51 +1000 Subject: [PATCH 2/2] remove unnecessary border-box and model.refresh() (#4) --- .../Behaviors/ResizeBehavior.cs | 2 -- src/Blazor.Diagrams/wwwroot/style.css | 1 - src/Blazor.Diagrams/wwwroot/style.min.css | 2 +- src/Blazor.Diagrams/wwwroot/style.min.css.gz | Bin 414 -> 408 bytes 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs b/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs index e9b837a61..c748fd54c 100644 --- a/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs +++ b/src/Blazor.Diagrams.Core/Behaviors/ResizeBehavior.cs @@ -113,8 +113,6 @@ void Resize(ResizerPosition resizerAlignment, NodeModel model, PointerEventArgs model.SetPosition(positionX, positionY); model.Size = new Size(width, height); - - model.Refresh(); } public override void Dispose() diff --git a/src/Blazor.Diagrams/wwwroot/style.css b/src/Blazor.Diagrams/wwwroot/style.css index 54ddf490a..35c0aaa30 100644 --- a/src/Blazor.Diagrams/wwwroot/style.css +++ b/src/Blazor.Diagrams/wwwroot/style.css @@ -43,7 +43,6 @@ user-select: none; cursor: move; pointer-events: all; - box-sizing: border-box; } .diagram-node.locked { diff --git a/src/Blazor.Diagrams/wwwroot/style.min.css b/src/Blazor.Diagrams/wwwroot/style.min.css index 877edb17d..9d874fe5b 100644 --- a/src/Blazor.Diagrams/wwwroot/style.min.css +++ b/src/Blazor.Diagrams/wwwroot/style.min.css @@ -1 +1 @@ -.diagram-canvas{width:100%;height:100%;position:relative;outline:0;overflow:hidden;cursor:-webkit-grab;cursor:grab;touch-action:none;}.diagram-svg-layer,.diagram-html-layer{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.html-layer,.svg-layer{position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.node{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;box-sizing:border-box;}.node.locked{cursor:pointer;}.link{pointer-events:visiblePainted;cursor:pointer;}.diagram-navigator{z-index:10;}.diagram-navigator .current-view{position:absolute;border:2px solid #000;}.group{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;}.group .children{position:absolute;overflow:visible;pointer-events:none;}.link foreignObject.link-label{overflow:visible;pointer-events:none;}div.control{position:absolute;}.executable.control{pointer-events:all;cursor:pointer;} \ No newline at end of file +.diagram-canvas{width:100%;height:100%;position:relative;outline:0;overflow:hidden;cursor:-webkit-grab;cursor:grab;touch-action:none;}.diagram-svg-layer,.diagram-html-layer{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.html-layer,.svg-layer{position:absolute;pointer-events:none;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%;overflow:visible;}.diagram-node{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;}.diagram-node.locked{cursor:pointer;}.diagram-link{pointer-events:visiblePainted;cursor:pointer;}.diagram-navigator{z-index:10;}.diagram-navigator .current-view{position:absolute;border:2px solid #000;}.diagram-group{position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:move;pointer-events:all;}.diagram-group .children{position:absolute;overflow:visible;pointer-events:none;}.diagram-link foreignObject.diagram-link-label{overflow:visible;pointer-events:none;}div.diagram-control{position:absolute;}.executable.diagram-control{pointer-events:all;cursor:pointer;} \ No newline at end of file diff --git a/src/Blazor.Diagrams/wwwroot/style.min.css.gz b/src/Blazor.Diagrams/wwwroot/style.min.css.gz index 5906b3b1eb512291df63559103566d7667b9999a..154c4be0ef761cf8726929fb3ea826394fa225c3 100644 GIT binary patch literal 408 zcmV;J0cZXniwFP!000003eA*3Zi6roMX!QXbr&PrB^;u?g25A*#&{xoaMGZhtcxD0 zSLh@mBu!kY%dW8g*xzqH179DXxk24}-K$2ssKdBH!(I7Q6pvL0*mitcuPGoSxzdBx zj1ejt*rJ27s3?M8TH2Hy8UwCs1|P_mY6JBOS&4gn){bkYq3M)vj((0DRQs7C#8z4T z4t_C99ryO6jZAB~&%%=B;g57hRTDGyvX~il9moz0qM&2&3L-cTr@PKr?6nI^^1UK) zLRS`9QK>$p3rX>ptmZr-2CVI&y-N>^d~R|4$H3?C9T`Y)o|%RqumLPIJi+#~OR3>r zyc4Dw=>_LD2yN{RRBowRff=Vm)BdYXGMuaN#%Aj8RUcGS{d(5vh^=Pw<4&P7u$7!r z6C6RevTYeZwp0;t+M(R z{AQ6l?(L+FOnbS{!j|RZFLXs!6EpQvER4DiWCsRO&@p%g5gdoYIb18*s#Cjy>4~$XgCaXa?4D{>N{tp>Ch{3pM3M ICg=nJ0Cii!KmY&$