PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/DataArtistConnections/DataArtistConnections/MyConnections.cs

#
C# | 311 lines | 256 code | 47 blank | 8 comment | 29 complexity | f2efbd119ba3c7aaf61602f957670c3d MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Media;
  7. using System.Windows.Media.Effects;
  8. using Microsoft.Expression.Controls;
  9. using Microsoft.Expression.Media;
  10. namespace DataArtistConnections
  11. {
  12. public static class Connections
  13. {
  14. private static List<TrackConnection> TrackMyConnections { get; set; }
  15. private static UserControl FromElement { get; set; }
  16. private static UserControl ToElement { get; set; }
  17. static Connections()
  18. {
  19. TrackMyConnections = new List<TrackConnection>();
  20. }
  21. public static void Adjust(UserControl connectFromElement, UserControl connectToElement)
  22. {
  23. Add(connectFromElement, connectToElement, adjustOnly: true);
  24. foreach (var connect in TrackMyConnections.Where(connect => connectFromElement == connect.ToElement))
  25. {
  26. Add(connect.FromElement, connect.ToElement, adjustOnly: true);
  27. }
  28. }
  29. //handle objects that are only connected to (they own no MyConnections to other objects)
  30. public static void Adjust(UserControl connectToElement)
  31. {
  32. foreach (var connect in TrackMyConnections.Where(connect => connectToElement == connect.ToElement))
  33. {
  34. Add(connect.FromElement, connect.ToElement, adjustOnly: true);
  35. }
  36. }
  37. public static void Add(UserControl connectFromElement, UserControl connectToElement, SolidColorBrush color = null, int strokeThickness = 2, double bendAmount = .1, double arrowSize = 5, DoubleCollection strokeDashArray = null, string arrowType = null, bool shadow = false, bool adjustOnly = false)
  38. {
  39. var parent = connectFromElement.Parent as Panel;
  40. FromElement = connectFromElement;
  41. ToElement = connectToElement;
  42. var connectFromX = connectFromElement.Left();
  43. var connectFromY = connectFromElement.Top();
  44. var connectToX = connectToElement.Left();
  45. var connectToY = connectToElement.Top();
  46. switch (PositionKey(connectFromElement, connectToX - connectFromX, connectToY - connectFromY))
  47. {
  48. case "RA": //right & above
  49. case "LA": //left & above
  50. case "SA": //same horizontal & above
  51. AboveOrBelow(connectToElement, connectFromElement, ref connectFromX, ref connectFromY, ref connectToX);
  52. break;
  53. case "LB": //left & below
  54. case "RB": //right & below
  55. AboveOrBelow(connectFromElement, connectToElement, ref connectToX, ref connectToY, ref connectFromX);
  56. break;
  57. case "SB": //same vertical & below
  58. AboveOrBelow(connectToElement, connectFromElement, ref connectFromX, ref connectFromY, ref connectToX);
  59. break;
  60. case "RS": //right & same vertical
  61. RightOrLeft(connectFromElement, connectToElement, ref connectToY, ref connectToX, ref connectFromY);
  62. break;
  63. case "LS": //left & same vertical
  64. RightOrLeft(connectToElement, connectFromElement, ref connectFromY, ref connectFromX, ref connectToY);
  65. break;
  66. case "SS":
  67. //do nothing if same horizontal and vertical
  68. break;
  69. }
  70. Canvas.SetZIndex(connectFromElement, 1);
  71. Canvas.SetZIndex(connectToElement, 1);
  72. if (adjustOnly == false)
  73. {
  74. AddConnection(parent, connectFromX, connectFromY, connectToX, connectToY, color, strokeThickness, bendAmount, arrowSize, strokeDashArray, arrowType, shadow);
  75. }
  76. else
  77. {
  78. //AdjustConnection(parent, connectFromX -320 -100, connectFromY -166, connectToX-320-100, connectToY-100);
  79. AdjustConnection(parent, connectFromX, connectFromY , connectToX, connectToY);
  80. }
  81. }
  82. private static void AddConnection(Panel parent, double x1, double y1, double x2, double y2, SolidColorBrush color, int strokeThickness, double bendAmount, double arrowSize, DoubleCollection strokeDashArray, string arrowType, bool shadow)
  83. {
  84. if (color == null)
  85. {
  86. color = new SolidColorBrush(Colors.Black);
  87. }
  88. double height = Math.Abs(y2 - y1);
  89. double width = Math.Abs(x2 - x1);
  90. double adjY = 0;
  91. double adjX = 0;
  92. var cornerType = CalcCornerType(x1, y1, x2, y2, width, height, ref adjX, ref adjY);
  93. var line = new LineArrow
  94. {
  95. //Name = Guid.NewGuid().ToString(),
  96. StartCorner = cornerType,
  97. Stroke = color,
  98. BendAmount = bendAmount,
  99. ArrowSize = arrowSize,
  100. StrokeDashArray = strokeDashArray,
  101. EndArrow = arrowType.ArrowTypeFromString(),
  102. Height = height,
  103. Width = width,
  104. StrokeThickness = strokeThickness
  105. };
  106. if (shadow == true)
  107. {
  108. line.Effect = new DropShadowEffect { Color = Colors.Gray, BlurRadius = 5 };
  109. }
  110. parent.Children.Add(line);
  111. line.SetValue(Canvas.LeftProperty, x1 + adjX);
  112. line.SetValue(Canvas.TopProperty, y1 + adjY);
  113. TrackMyConnections.Add(new TrackConnection { FromElement = FromElement, ToElement = ToElement, Line = line });
  114. Canvas.SetZIndex(line, 0);
  115. }
  116. private static void AdjustConnection(Panel parent, double x1, double y1, double x2, double y2)
  117. {
  118. foreach (var connectionObject in TrackMyConnections)
  119. {
  120. if (connectionObject.FromElement == FromElement && connectionObject.ToElement == ToElement)
  121. {
  122. double height = Math.Abs((y2 - parent.Top()) - (y1 - parent.Top()));
  123. double width = Math.Abs((x2 - parent.Left()) - (x1 - parent.Left()));
  124. double adjY = 0;
  125. double adjX = 0;
  126. var cornerType = CalcCornerType(x1, y1, x2, y2, width, height, ref adjX, ref adjY);
  127. connectionObject.Line.SetValue(Canvas.TopProperty, (y1 - parent.Top()) + adjY);
  128. connectionObject.Line.SetValue(Canvas.LeftProperty, (x1 - parent.Left()) + adjX);
  129. connectionObject.Line.StartCorner = cornerType;
  130. connectionObject.Line.Height = Math.Abs(height);
  131. connectionObject.Line.Width = Math.Abs(width);
  132. }
  133. }
  134. }
  135. private static string PositionKey(UserControl connectFromElement, double diffX, double diffY)
  136. {
  137. string verticalPosition;
  138. string horizontalPosition;
  139. if (Math.Abs(diffY) < ((node)connectFromElement).nHeight)
  140. {
  141. diffY = 0;
  142. }
  143. if (diffX == 0)
  144. {
  145. horizontalPosition = "S"; //same horizontal
  146. }
  147. else
  148. {
  149. if (diffX > 0)
  150. {
  151. horizontalPosition = "L"; //left
  152. }
  153. else
  154. {
  155. horizontalPosition = "R"; //right
  156. }
  157. }
  158. if (diffY == 0)
  159. {
  160. verticalPosition = "S"; //same vertical
  161. }
  162. else
  163. {
  164. if (diffY > 0)
  165. {
  166. verticalPosition = "A"; //above
  167. }
  168. else
  169. {
  170. verticalPosition = "B"; //below
  171. }
  172. }
  173. return horizontalPosition + verticalPosition;
  174. }
  175. private static void AboveOrBelow(UserControl element1, UserControl element2, ref double p1, ref double p2, ref double p3)
  176. {
  177. //p1 += 163 / 2;
  178. //p2 += 81 / 2;
  179. //p3 += 163 / 2;
  180. p1 += ((node)element2).nWidth / 2;
  181. p2 += ((node)element2).nHeight;
  182. p3 += ((node)element1).nWidth / 2;
  183. }
  184. private static void RightOrLeft(UserControl element1, UserControl element2, ref double p1, ref double p2, ref double p3)
  185. {
  186. p1 += ((node)element2).nHeight / 2;
  187. p2 += ((node)element2).nWidth;
  188. p3 += ((node)element1).nHeight / 2;
  189. }
  190. private static CornerType CalcCornerType(double x1, double y1, double x2, double y2, double width, double height, ref double adjX, ref double adjY)
  191. {
  192. var cornerType = CornerType.TopLeft;
  193. if (y2 < y1 && x2 < x1)
  194. {
  195. cornerType = CornerType.BottomRight;
  196. adjY = -height;
  197. adjX = -width;
  198. }
  199. else
  200. {
  201. if (y2 < y1)
  202. {
  203. cornerType = CornerType.BottomLeft;
  204. adjY = -height;
  205. }
  206. if (x2 < x1)
  207. {
  208. cornerType = CornerType.TopRight;
  209. adjX = -width;
  210. }
  211. }
  212. return cornerType;
  213. }
  214. public static double Left(this Object value)
  215. {
  216. if (value.GetType() == typeof(Canvas))
  217. {
  218. //return -100;
  219. var g = ((UIElement)value).TransformToVisual(Application.Current.RootVisual);
  220. var offset = g.Transform(new Point(0, 0));
  221. return offset.X;
  222. }
  223. else
  224. {
  225. var g = ((UserControl)value).TransformToVisual(Application.Current.RootVisual);
  226. var offset = g.Transform(new Point(0, 0));
  227. return offset.X;
  228. }
  229. }
  230. public static double Top(this Object value)
  231. {
  232. if (value.GetType() == typeof(Canvas))
  233. {
  234. var g = ((UIElement)value).TransformToVisual(Application.Current.RootVisual);
  235. var offset = g.Transform(new Point(0, 0));
  236. return offset.Y;
  237. }
  238. else
  239. {
  240. var g = ((UserControl)value).TransformToVisual(Application.Current.RootVisual);
  241. var offset = g.Transform(new Point(0, 0));
  242. return offset.Y;
  243. }
  244. }
  245. public static ArrowType ArrowTypeFromString(this string value)
  246. {
  247. switch (value)
  248. {
  249. case "Arrow":
  250. return ArrowType.Arrow;
  251. case "NoArrow":
  252. return ArrowType.NoArrow;
  253. case "OpenArrow":
  254. return ArrowType.OpenArrow;
  255. case "OvalArrow":
  256. return ArrowType.OvalArrow;
  257. case "StealthArrow":
  258. return ArrowType.StealthArrow;
  259. default://change this value for a default arrow type
  260. return ArrowType.StealthArrow;
  261. }
  262. }
  263. }
  264. }