internal ConnectorModel GetInfo() { var owner = new DesignerItemModel(); owner.Left = DesignerCanvas.GetLeft( ParentDesignerItem ); owner.Top = DesignerCanvas.GetTop( ParentDesignerItem ); owner.Size = new Size( ParentDesignerItem.ActualWidth, ParentDesignerItem.ActualHeight ); ConnectorModel info = new ConnectorModel( owner ); info.Orientation = Orientation; info.Position = Position; return info; }
private static Point GetOffsetPoint( ConnectorModel connector, Rect rect ) { Point offsetPoint = new Point(); switch ( connector.Orientation ) { case ConnectorOrientation.Left: offsetPoint = new Point( rect.Left, connector.Position.Y ); break; case ConnectorOrientation.Top: offsetPoint = new Point( connector.Position.X, rect.Top ); break; case ConnectorOrientation.Right: offsetPoint = new Point( rect.Right, connector.Position.Y ); break; case ConnectorOrientation.Bottom: offsetPoint = new Point( connector.Position.X, rect.Bottom ); break; default: break; } return offsetPoint; }
private static void CheckPathEnd( ConnectorModel source, ConnectorModel sink, bool showLastLine, List<Point> linePoints ) { if ( showLastLine ) { Point startPoint = new Point( 0, 0 ); switch ( source.Orientation ) { case ConnectorOrientation.Left: startPoint = new Point( source.Position.X - PathMargin, source.Position.Y ); break; case ConnectorOrientation.Top: startPoint = new Point( source.Position.X, source.Position.Y - PathMargin ); break; case ConnectorOrientation.Right: startPoint = new Point( source.Position.X + PathMargin, source.Position.Y ); break; case ConnectorOrientation.Bottom: startPoint = new Point( source.Position.X, source.Position.Y + PathMargin ); break; default: break; } Point endPoint = new Point( 0, 0 ); switch ( sink.Orientation ) { case ConnectorOrientation.Left: endPoint = new Point( sink.Position.X - PathMargin, sink.Position.Y ); break; case ConnectorOrientation.Top: endPoint = new Point( sink.Position.X, sink.Position.Y - PathMargin ); break; case ConnectorOrientation.Right: endPoint = new Point( sink.Position.X + PathMargin, sink.Position.Y ); break; case ConnectorOrientation.Bottom: endPoint = new Point( sink.Position.X, sink.Position.Y + PathMargin ); break; default: break; } linePoints.Insert( 0, startPoint ); linePoints.Add( endPoint ); } else { linePoints.Insert( 0, source.Position ); linePoints.Add( sink.Position ); } }
private static Rect GetRectWithMargin( ConnectorModel connectorThumb, double margin ) { var rect = connectorThumb.OwnerItem.GetBoundingRectangle(); rect.Inflate( margin, margin ); return rect; }
private static Point GetNearestVisibleNeighborSink( Point currentPoint, Point endPoint, ConnectorModel sink, Rect rectSource, Rect rectSink ) { Point s1, s2; // neighbors on sink side GetNeighborCorners( sink.Orientation, rectSink, out s1, out s2 ); bool flag1 = IsPointVisible( currentPoint, s1, new Rect[] { rectSource, rectSink } ); bool flag2 = IsPointVisible( currentPoint, s2, new Rect[] { rectSource, rectSink } ); if ( flag1 ) // s1 visible { if ( flag2 ) // s1 and s2 visible { if ( rectSink.Contains( s1 ) ) { return s2; } if ( rectSink.Contains( s2 ) ) { return s1; } if ( (Distance( s1, endPoint ) <= Distance( s2, endPoint )) ) { return s1; } else { return s2; } } else { return s1; } } else // s1 not visible { if ( flag2 ) // only s2 visible { return s2; } else // s1 and s2 not visible { return new Point( double.NaN, double.NaN ); } } }
private static Point GetNearestNeighborSource( ConnectorModel source, Point endPoint, Rect rectSource, out bool flag ) { Point n1, n2; // neighbors GetNeighborCorners( source.Orientation, rectSource, out n1, out n2 ); if ( (Distance( n1, endPoint ) <= Distance( n2, endPoint )) ) { flag = true; return n1; } else { flag = false; return n2; } }
internal static List<Point> GetConnectionLine( ConnectorModel source, Point sinkPoint, ConnectorOrientation preferredOrientation ) { List<Point> linePoints = new List<Point>(); Rect rectSource = GetRectWithMargin( source, ConnectorMargin / 2 ); Point startPoint = GetOffsetPoint( source, rectSource ); Point endPoint = sinkPoint; linePoints.Add( startPoint ); Point currentPoint = startPoint; if ( !rectSource.Contains( endPoint ) ) { while ( true ) { if ( IsPointVisible( currentPoint, endPoint, new Rect[] { rectSource } ) ) { linePoints.Add( endPoint ); break; } bool sideFlag; Point n = GetNearestNeighborSource( source, endPoint, rectSource, out sideFlag ); linePoints.Add( n ); currentPoint = n; if ( IsPointVisible( currentPoint, endPoint, new Rect[] { rectSource } ) ) { linePoints.Add( endPoint ); break; } else { Point n1, n2; GetOppositeCorners( source.Orientation, rectSource, out n1, out n2 ); if ( sideFlag ) linePoints.Add( n1 ); else linePoints.Add( n2 ); linePoints.Add( endPoint ); break; } } } else { linePoints.Add( endPoint ); } if ( preferredOrientation != ConnectorOrientation.None ) linePoints = OptimizeLinePoints( linePoints, new Rect[] { rectSource }, source.Orientation, preferredOrientation ); else linePoints = OptimizeLinePoints( linePoints, new Rect[] { rectSource }, source.Orientation, GetOpositeOrientation( source.Orientation ) ); return linePoints; }
internal static List<Point> GetConnectionLine( ConnectorModel source, ConnectorModel sink, bool showLastLine ) { List<Point> linePoints = new List<Point>(); Rect rectSource = GetRectWithMargin( source, ConnectorMargin ); Rect rectSink = GetRectWithMargin( sink, ConnectorMargin ); Point startPoint = GetOffsetPoint( source, rectSource ); Point endPoint = GetOffsetPoint( sink, rectSink ); linePoints.Add( startPoint ); Point currentPoint = startPoint; if ( !rectSink.Contains( currentPoint ) && !rectSource.Contains( endPoint ) ) { while ( true ) { if ( IsPointVisible( currentPoint, endPoint, new Rect[] { rectSource, rectSink } ) ) { linePoints.Add( endPoint ); currentPoint = endPoint; break; } Point neighbour = GetNearestVisibleNeighborSink( currentPoint, endPoint, sink, rectSource, rectSink ); if ( !double.IsNaN( neighbour.X ) ) { linePoints.Add( neighbour ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } if ( currentPoint == startPoint ) { bool flag; Point n = GetNearestNeighborSource( source, endPoint, rectSource, rectSink, out flag ); linePoints.Add( n ); currentPoint = n; if ( !IsRectVisible( currentPoint, rectSink, new Rect[] { rectSource } ) ) { Point n1, n2; GetOppositeCorners( source.Orientation, rectSource, out n1, out n2 ); if ( flag ) { linePoints.Add( n1 ); currentPoint = n1; } else { linePoints.Add( n2 ); currentPoint = n2; } if ( !IsRectVisible( currentPoint, rectSink, new Rect[] { rectSource } ) ) { if ( flag ) { linePoints.Add( n2 ); currentPoint = n2; } else { linePoints.Add( n1 ); currentPoint = n1; } } } } else // from here on we jump to the sink node { Point n1, n2; // neighbour corner Point s1, s2; // opposite corner GetNeighborCorners( sink.Orientation, rectSink, out s1, out s2 ); GetOppositeCorners( sink.Orientation, rectSink, out n1, out n2 ); bool n1Visible = IsPointVisible( currentPoint, n1, new Rect[] { rectSource, rectSink } ); bool n2Visible = IsPointVisible( currentPoint, n2, new Rect[] { rectSource, rectSink } ); if ( n1Visible && n2Visible ) { if ( rectSource.Contains( n1 ) ) { linePoints.Add( n2 ); if ( rectSource.Contains( s2 ) ) { linePoints.Add( n1 ); linePoints.Add( s1 ); } else linePoints.Add( s2 ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } if ( rectSource.Contains( n2 ) ) { linePoints.Add( n1 ); if ( rectSource.Contains( s1 ) ) { linePoints.Add( n2 ); linePoints.Add( s2 ); } else linePoints.Add( s1 ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } if ( (Distance( n1, endPoint ) <= Distance( n2, endPoint )) ) { linePoints.Add( n1 ); if ( rectSource.Contains( s1 ) ) { linePoints.Add( n2 ); linePoints.Add( s2 ); } else linePoints.Add( s1 ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } else { linePoints.Add( n2 ); if ( rectSource.Contains( s2 ) ) { linePoints.Add( n1 ); linePoints.Add( s1 ); } else linePoints.Add( s2 ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } } else if ( n1Visible ) { linePoints.Add( n1 ); if ( rectSource.Contains( s1 ) ) { linePoints.Add( n2 ); linePoints.Add( s2 ); } else linePoints.Add( s1 ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } else { linePoints.Add( n2 ); if ( rectSource.Contains( s2 ) ) { linePoints.Add( n1 ); linePoints.Add( s1 ); } else linePoints.Add( s2 ); linePoints.Add( endPoint ); currentPoint = endPoint; break; } } } } else { linePoints.Add( endPoint ); } linePoints = OptimizeLinePoints( linePoints, new Rect[] { rectSource, rectSink }, source.Orientation, sink.Orientation ); CheckPathEnd( source, sink, showLastLine, linePoints ); return linePoints; }