public void SetTargetPort_ShouldChangePropertiesAndTriggerEvent() { // Arrange var link = new TestLink(sourcePort: new PortModel(null), targetPort: null); var parent = new NodeModel(); var tp = new PortModel(parent); var eventsTriggered = 0; PortModel oldTp = null; PortModel newTp = null; BaseLinkModel linkInstance = null; // Act link.TargetPortChanged += (l, o, n) => { eventsTriggered++; linkInstance = l; oldTp = o; newTp = n; }; link.SetTargetPort(tp); // Assert eventsTriggered.Should().Be(1); link.TargetPort.Should().BeSameAs(tp); oldTp.Should().BeNull(); newTp.Should().BeSameAs(tp); linkInstance.Should().BeSameAs(link); link.TargetNode.Should().BeSameAs(parent); }
public static PathGeneratorResult Smooth(Diagram _, BaseLinkModel link, Point[] route, Point source, Point target) { route = ConcatRouteAndSourceAndTarget(route, source, target); if (route.Length > 2) { return(CurveThroughPoints(route, link)); } route = GetRouteWithCurvePoints(link, route); double?sourceAngle = null; double?targetAngle = null; if (link.SourceMarker != null) { sourceAngle = SourceMarkerAdjustement(route, link.SourceMarker.Width); } if (link.TargetMarker != null) { targetAngle = TargetMarkerAdjustement(route, link.TargetMarker.Width); } var path = FormattableString.Invariant($"M {route[0].X} {route[0].Y} C {route[1].X} {route[1].Y}, {route[2].X} {route[2].Y}, {route[3].X} {route[3].Y}"); return(new PathGeneratorResult(new[] { path }, sourceAngle, route[0], targetAngle, route[^ 1]));
public LinkLabelModel(BaseLinkModel parent, string id, string content, double?distance = null, Point?offset = null) : base(id) { Parent = parent; Content = content; Distance = distance; Offset = offset; }
private void OnLinkTargetPortChanged(BaseLinkModel link, PortModel oldPort, PortModel newPort) { link.Labels.Add(new LinkLabelModel(link, "1..*", -40, new Point(0, -30))); link.Refresh(); ((newPort ?? oldPort) as ColumnPort).Column.Refresh(); }
public static string GenerateCurvedPath(this BaseLinkModel link) { var sX = link.GetMiddleSourceX(); var sY = link.GetMiddleSourceY(); double tX, tY; if (link.IsAttached) { tX = link.GetMiddleTargetX(); tY = link.GetMiddleTargetY(); } else { tX = link.OnGoingPosition !.X; tY = link.OnGoingPosition.Y; } var cX = (sX + tX) / 2; var cY = (sY + tY) / 2; var curvePointA = GetCurvePoint(sX, sY, cX, cY, link.SourcePort.Alignment); var curvePointB = GetCurvePoint(tX, tY, cX, cY, link.TargetPort?.Alignment); return(FormattableString.Invariant($"M {sX} {sY} C {curvePointA}, {curvePointB}, {tX} {tY}")); }
/// <summary> /// If the link is attached, returns the same output as GetMiddleTargetY(). /// Otherwise, returns the Y value of link's ongoing position. /// </summary> /// <param name="link">The BaseLinkModel entity</param> public static double GetTargetY(this BaseLinkModel link) { if (!link.IsAttached) { return(link.OnGoingPosition !.Y); } return(link.GetMiddleTargetY()); }
private void Diagram_LinkRemoved(BaseLinkModel link) { link.TargetPortChanged -= OnLinkTargetPortChanged; if (!link.IsAttached) { return; } var sourceCol = (link.SourcePort as ColumnPort).Column; var targetCol = (link.TargetPort as ColumnPort).Column; (sourceCol.Primary ? targetCol : sourceCol).Refresh(); }
public static PathGeneratorResult Straight(Diagram _, BaseLinkModel link, Point[] route, Point source, Point target) { route = ConcatRouteAndSourceAndTarget(route, source, target); double?sourceAngle = null; double?targetAngle = null; if (link.SourceMarker != null) { sourceAngle = SourceMarkerAdjustement(route, link.SourceMarker.Width); } if (link.TargetMarker != null) { targetAngle = TargetMarkerAdjustement(route, link.TargetMarker.Width); } var paths = new string[route.Length - 1]; for (var i = 0; i < route.Length - 1; i++) { paths[i] = FormattableString.Invariant($"M {route[i].X} {route[i].Y} L {route[i + 1].X} {route[i + 1].Y}"); } return(new PathGeneratorResult(paths, sourceAngle, route[0], targetAngle, route[^ 1]));
public static Point[] Normal(Diagram _, BaseLinkModel link) { return(link.Vertices.Select(v => v.Position).ToArray()); }
internal void RemoveLink(BaseLinkModel link) => _links.Remove(link);
internal void AddLink(BaseLinkModel link) => _links.Add(link);
public DiagramLinkLabel(BaseLinkModel parent, string id, string content, double?distance = null, Point?offset = null) : base(parent, id, content, distance, offset) { }
public LinkVertexModel(BaseLinkModel parent, Point?position = null) : base(position) { Parent = parent; }
private void OnLinkAdded(BaseLinkModel link) { link.TargetPortChanged += OnLinkTargetPortChanged; }
private void Links_Added(BaseLinkModel obj) { Console.WriteLine($"Links.Added, Links=[{obj}]"); }
public static Point[] Orthogonal(Diagram _, BaseLinkModel link) { if (link.IsPortless) { throw new Exception("Orthogonal router doesn't work with portless links yet"); } if (link.TargetPort == null || link.SourcePort !.Parent.Size == null || link.TargetPort.Parent.Size == null) { return(Normal(_, link)); } var shapeMargin = 10; var globalBoundsMargin = 50; var spots = new List <Point>(); var verticals = new List <double>(); var horizontals = new List <double>(); var sideA = link.SourcePort.Alignment; var sideAVertical = IsVerticalSide(sideA); var sideB = link.TargetPort.Alignment; var sideBVertical = IsVerticalSide(sideB); var originA = GetPortPositionBasedOnAlignment(link.SourcePort); var originB = GetPortPositionBasedOnAlignment(link.TargetPort); var shapeA = link.SourcePort.Parent.GetBounds(includePorts: true) !; var shapeB = link.TargetPort.Parent.GetBounds(includePorts: true) !; var inflatedA = shapeA.Inflate(shapeMargin, shapeMargin); var inflatedB = shapeB.Inflate(shapeMargin, shapeMargin); if (inflatedA.Intersects(inflatedB)) { shapeMargin = 0; inflatedA = shapeA; inflatedB = shapeB; } // Curated bounds to stick to var bounds = inflatedA.Union(inflatedB).Inflate(globalBoundsMargin, globalBoundsMargin); // Add edges to rulers verticals.Add(inflatedA.Left); verticals.Add(inflatedA.Right); horizontals.Add(inflatedA.Top); horizontals.Add(inflatedA.Bottom); verticals.Add(inflatedB.Left); verticals.Add(inflatedB.Right); horizontals.Add(inflatedB.Top); horizontals.Add(inflatedB.Bottom); // Rulers at origins of shapes (sideAVertical ? verticals : horizontals).Add(sideAVertical ? originA.X : originA.Y); (sideBVertical ? verticals : horizontals).Add(sideBVertical ? originB.X : originB.Y); // Points of shape antennas spots.Add(GetOriginSpot(originA, sideA, shapeMargin)); spots.Add(GetOriginSpot(originB, sideB, shapeMargin)); // Sort rulers verticals.Sort(); horizontals.Sort(); // Create grid var grid = RulersToGrid(verticals, horizontals, bounds); var gridPoints = GridToSpots(grid, new[] { inflatedA, inflatedB }); // Add to spots spots.AddRange(gridPoints); // Create graph var graph = CreateGraph(spots); // Origin and destination by extruding antennas var origin = ExtrudeCp(originA, shapeMargin, sideA); var destination = ExtrudeCp(originB, shapeMargin, sideB); var path = ShortestPath(graph, origin, destination); if (path.Length > 0) { return(SimplifyPath(path)); } else { return(Normal(_, link)); } }