1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.Activities.Presentation.FreeFormEditing
7 using System.Collections.Generic;
8 using System.Diagnostics;
11 class ConnectionPoint : UIElement
13 public static readonly DependencyProperty LocationProperty = DependencyProperty.Register("Location", typeof(Point), typeof(ConnectionPoint));
15 private List<Connector> attachedConnectors;
16 private UIElement parentDesigner;
17 private ConnectionPointKind pointType;
19 // Size constants for the rectangle drawn
20 internal const double DrawingSmallSide = 4;
21 internal const double DrawingLargeSide = 10;
23 // Size constants for the hit test area.
24 internal const double HitTestSmallSide = 14;
25 internal const double HitTestLargeSide = 20;
27 public ConnectionPoint()
29 pointType = ConnectionPointKind.Default;
30 attachedConnectors = new List<Connector>();
31 this.parentDesigner = null;
34 public List<Connector> AttachedConnectors
38 return this.attachedConnectors;
44 get { return (Point)GetValue(ConnectionPoint.LocationProperty); }
45 set { SetValue(ConnectionPoint.LocationProperty, value); }
48 // This is the vector from the point on the Edge to the top left of the rectangle being drawn.
49 public Vector DrawingOffset
53 return GetOffset(DrawingSmallSide, DrawingLargeSide);
57 // This is the vector from the point on the Edge to the top left of the rectangle being used for hit test.
58 public Vector HitTestOffset
62 return GetOffset(HitTestSmallSide, HitTestLargeSide);
66 // This is the size for the rectangle drawn (size is independent of coordinate system)
67 public Size DrawingSize
71 return this.GetSize(ConnectionPoint.DrawingSmallSide, ConnectionPoint.DrawingLargeSide);
75 // This is the size for the hit test area (size is independent of coordinate system)
76 public Size HitTestSize
80 return this.GetSize(ConnectionPoint.HitTestSmallSide, ConnectionPoint.HitTestLargeSide);
84 public UIElement ParentDesigner
88 return this.parentDesigner;
92 this.parentDesigner = value;
96 public ConnectionPointKind PointType
100 return this.pointType;
104 this.pointType = value;
108 // The list of Points representing the edge of the parent designer where this ConnectionPoint locates with respect to (0,0) of the FreeFormPanel.
109 public List<Point> Edge
113 FrameworkElement parent = this.ParentDesigner as FrameworkElement;
114 Fx.Assert(parent != null, "shape should be a FrameworkElement");
115 Point topLeft = FreeFormPanel.GetLocation(parent);
116 topLeft.Offset(parent.Margin.Left, parent.Margin.Top);
117 double parentWidth = parent.DesiredSize.Width - parent.Margin.Left - parent.Margin.Right;
118 double parentHeight = parent.DesiredSize.Height - parent.Margin.Top - parent.Margin.Bottom;
119 if (this.Location.X == topLeft.X)
121 return new List<Point> { topLeft, new Point(topLeft.X, topLeft.Y + parentHeight) };
123 else if (this.Location.X == topLeft.X + parentWidth)
125 return new List<Point> { new Point(topLeft.X + parentWidth, topLeft.Y), new Point(topLeft.X + parentWidth, topLeft.Y + parentHeight) };
127 else if (this.Location.Y == topLeft.Y)
129 return new List<Point> { topLeft, new Point(topLeft.X + parentWidth, topLeft.Y) };
131 else if (this.Location.Y == topLeft.Y + parentHeight)
133 return new List<Point> { new Point(topLeft.X, topLeft.Y + parentHeight), new Point(topLeft.X + parentWidth, topLeft.Y + parentHeight) };
139 public EdgeLocation EdgeLocation
145 public static ConnectionPoint GetClosestConnectionPoint(List<ConnectionPoint> connectionPoints, Point refPoint, out double minDist)
147 minDist = double.PositiveInfinity;
148 if (connectionPoints == null || connectionPoints.Count == 0)
153 ConnectionPoint closestPoint = null;
154 foreach (ConnectionPoint point in connectionPoints)
156 dist = DesignerGeometryHelper.DistanceBetweenPoints(refPoint, point.Location);
160 closestPoint = point;
167 // This is the vector from the point on the Edge to the top left of a rectangle with a particular (small, large) pair.
168 Vector GetOffset(double small, double large)
170 return this.EdgeToDrawnMidPointOffset() + this.MidPointToTopLeftOffset(small, large);
173 // This is the vector from the point on the Edge to the midpoint of the "drawn" rectangle.
174 Vector EdgeToDrawnMidPointOffset()
176 double small = ConnectionPoint.DrawingSmallSide;
177 switch (this.EdgeLocation)
179 case EdgeLocation.Left: return new Vector(-small / 2, 0);
180 case EdgeLocation.Right: return new Vector(small / 2, 0);
181 case EdgeLocation.Top: return new Vector(0, -small / 2);
182 case EdgeLocation.Bottom: return new Vector(0, small / 2);
184 Fx.Assert("There is no other possibilities for EdgeDirections");
185 // To please compiler
189 // This is the vector from the midpoint of the rectangle to the top left of the rectangle with a particular (small, large) pair.
190 Vector MidPointToTopLeftOffset(double small, double large)
192 Size rectSize = GetSize(small, large);
193 return new Vector(-rectSize.Width / 2, -rectSize.Height / 2);
196 // This is the size for the rectangle with a particular (small, large) pair
197 Size GetSize(double small, double large)
199 if (this.EdgeLocation == EdgeLocation.Left || this.EdgeLocation == EdgeLocation.Right)
201 return new Size(small, large);
205 return new Size(large, small);