示例#1
0
        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]));
示例#3
0
 public LinkLabelModel(BaseLinkModel parent, string id, string content, double?distance = null, Point?offset = null) : base(id)
 {
     Parent   = parent;
     Content  = content;
     Distance = distance;
     Offset   = offset;
 }
示例#4
0
        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());
        }
示例#7
0
        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());
 }
示例#10
0
 internal void RemoveLink(BaseLinkModel link) => _links.Remove(link);
示例#11
0
 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)
 {
 }
示例#13
0
 public LinkVertexModel(BaseLinkModel parent, Point?position = null) : base(position)
 {
     Parent = parent;
 }
示例#14
0
 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));
            }
        }