[reflection] Coop handles icalls in System.Reflection and System.RuntimeTypeHandle...
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / FreeFormEditing / ConnectionPoint.cs
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4
5 namespace System.Activities.Presentation.FreeFormEditing
6 {
7     using System.Collections.Generic;
8     using System.Diagnostics;
9     using System.Windows;
10     using System.Runtime;
11     class ConnectionPoint : UIElement
12     {
13         public static readonly DependencyProperty LocationProperty = DependencyProperty.Register("Location", typeof(Point), typeof(ConnectionPoint));
14
15         private List<Connector> attachedConnectors;
16         private UIElement parentDesigner;
17         private ConnectionPointKind pointType;
18
19         // Size constants for the rectangle drawn
20         internal const double DrawingSmallSide = 4;
21         internal const double DrawingLargeSide = 10;
22
23         // Size constants for the hit test area.
24         internal const double HitTestSmallSide = 14;
25         internal const double HitTestLargeSide = 20;
26
27         public ConnectionPoint()
28         {
29             pointType = ConnectionPointKind.Default;
30             attachedConnectors = new List<Connector>();
31             this.parentDesigner = null;
32         }
33
34         public List<Connector> AttachedConnectors
35         {
36             get
37             {
38                 return this.attachedConnectors;
39             }
40         }
41
42         public Point Location
43         {
44             get { return (Point)GetValue(ConnectionPoint.LocationProperty); }
45             set { SetValue(ConnectionPoint.LocationProperty, value); }
46         }
47
48         // This is the vector from the point on the Edge to the top left of the rectangle being drawn.
49         public Vector DrawingOffset
50         {
51             get
52             {
53                 return GetOffset(DrawingSmallSide, DrawingLargeSide);
54             }
55         }
56
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
59         {
60             get
61             {
62                 return GetOffset(HitTestSmallSide, HitTestLargeSide);
63             }
64         }
65
66         // This is the size for the rectangle drawn (size is independent of coordinate system)
67         public Size DrawingSize
68         {
69             get
70             {
71                 return this.GetSize(ConnectionPoint.DrawingSmallSide, ConnectionPoint.DrawingLargeSide);
72             }
73         }
74
75         // This is the size for the hit test area (size is independent of coordinate system)
76         public Size HitTestSize
77         {
78             get
79             {
80                 return this.GetSize(ConnectionPoint.HitTestSmallSide, ConnectionPoint.HitTestLargeSide);
81             }
82         }
83
84         public UIElement ParentDesigner
85         {
86             get
87             {
88                 return this.parentDesigner;
89             }
90             set
91             {
92                 this.parentDesigner = value;
93             }
94         }
95
96         public ConnectionPointKind PointType
97         {
98             get
99             {
100                 return this.pointType;
101             }
102             set
103             {
104                 this.pointType = value;
105             }
106         }
107
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
110         {
111             get
112             {
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)
120                 { //Left Edge
121                     return new List<Point> { topLeft, new Point(topLeft.X, topLeft.Y + parentHeight) };
122                 }
123                 else if (this.Location.X == topLeft.X + parentWidth)
124                 { //Right edge
125                     return new List<Point> { new Point(topLeft.X + parentWidth, topLeft.Y), new Point(topLeft.X + parentWidth, topLeft.Y + parentHeight) };
126                 }
127                 else if (this.Location.Y == topLeft.Y)
128                 { //Top Edge
129                     return new List<Point> { topLeft, new Point(topLeft.X + parentWidth, topLeft.Y) };
130                 }
131                 else if (this.Location.Y == topLeft.Y + parentHeight)
132                 { //Bottom edge
133                     return new List<Point> { new Point(topLeft.X, topLeft.Y + parentHeight), new Point(topLeft.X + parentWidth, topLeft.Y + parentHeight) };
134                 }
135                 return null;
136             }
137         }
138
139         public EdgeLocation EdgeLocation
140         {
141             get;
142             set;
143         }
144
145         public static ConnectionPoint GetClosestConnectionPoint(List<ConnectionPoint> connectionPoints, Point refPoint, out double minDist)
146         {
147             minDist = double.PositiveInfinity;
148             if (connectionPoints == null || connectionPoints.Count == 0)
149             {
150                 return null;
151             }
152             double dist = 0;
153             ConnectionPoint closestPoint = null;
154             foreach (ConnectionPoint point in connectionPoints)
155             {
156                 dist = DesignerGeometryHelper.DistanceBetweenPoints(refPoint, point.Location);
157                 if (dist < minDist)
158                 {
159                     minDist = dist;
160                     closestPoint = point;
161                 }
162             }
163
164             return closestPoint;
165         }
166
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)
169         {
170             return this.EdgeToDrawnMidPointOffset() + this.MidPointToTopLeftOffset(small, large);
171         }
172
173         // This is the vector from the point on the Edge to the midpoint of the "drawn" rectangle.
174         Vector EdgeToDrawnMidPointOffset()
175         {
176             double small = ConnectionPoint.DrawingSmallSide;
177             switch (this.EdgeLocation)
178             {
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);
183             }
184             Fx.Assert("There is no other possibilities for EdgeDirections");
185             // To please compiler
186             return new Vector();
187         }
188
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)
191         {
192             Size rectSize = GetSize(small, large);
193             return new Vector(-rectSize.Width / 2, -rectSize.Height / 2);
194         }
195
196         // This is the size for the rectangle with a particular (small, large) pair
197         Size GetSize(double small, double large)
198         {
199             if (this.EdgeLocation == EdgeLocation.Left || this.EdgeLocation == EdgeLocation.Right)
200             {
201                 return new Size(small, large);
202             }
203             else
204             {
205                 return new Size(large, small);
206             }
207         }
208     }
209
210     enum EdgeLocation
211     {
212         Left,
213         Right,
214         Top,
215         Bottom
216     }
217 }