LinkTool.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using System.Linq;
  2. using System.Windows.Input;
  3. using System.Windows;
  4. using System.Windows.Controls;
  5. namespace SHJX.Service.WorkFlowEdit
  6. {
  7. public class LinkTool : ILinkTool
  8. {
  9. protected DiagramView View { get; private set; }
  10. protected IDiagramController Controller { get { return View.Controller; } }
  11. protected Point DragStart { get; set; }
  12. protected ILink Link { get; set; }
  13. protected LinkThumbKind Thumb { get; set; }
  14. protected LinkInfo InitialState { get; set; }
  15. protected LinkAdorner Adorner { get; set; }
  16. private bool _isNewLink;
  17. public LinkTool(DiagramView view)
  18. {
  19. View = view;
  20. }
  21. public void BeginDrag(Point start, ILink link, LinkThumbKind thumb)
  22. {
  23. BeginDrag(start, link, thumb, false);
  24. }
  25. protected virtual void BeginDrag(Point start, ILink link, LinkThumbKind thumb, bool isNew)
  26. {
  27. _isNewLink = isNew;
  28. DragStart = start;
  29. Link = link;
  30. Thumb = thumb;
  31. InitialState = new LinkInfo(link);
  32. Adorner = CreateAdorner();
  33. View.DragAdorner = Adorner;
  34. }
  35. public virtual void DragTo(Vector vector)
  36. {
  37. vector = UpdateVector(vector);
  38. var point = DragStart + vector;
  39. var port = View.Children.OfType<INode>().SelectMany(p => p.Ports)
  40. .Where(p => p.IsNear(point) && CanLinkTo(p))
  41. .OrderBy(p => GeometryHelper.Length(p.Center, point))
  42. .FirstOrDefault();
  43. UpdateLink(point, port);
  44. Adorner.Port = port;
  45. Link.UpdatePath();
  46. }
  47. protected virtual void UpdateLink(Point point, IPort port)
  48. {
  49. if (Thumb == LinkThumbKind.Source)
  50. {
  51. Link.Source = port;
  52. Link.SourcePoint = port == null ? point : (Point?)null;
  53. }
  54. else
  55. {
  56. Link.Target = port;
  57. Link.TargetPoint = port == null ? point : (Point?)null;
  58. }
  59. }
  60. protected virtual bool CanLinkTo(IPort port)
  61. {
  62. var pb = port as PortBase;
  63. if (pb != null)
  64. {
  65. if (Thumb == LinkThumbKind.Source)
  66. return pb.CanAcceptOutgoingLinks;
  67. else
  68. return pb.CanAcceptIncomingLinks;
  69. }
  70. else
  71. return true;
  72. }
  73. public virtual bool CanDrop()
  74. {
  75. return Adorner.Port != null;
  76. }
  77. public virtual void EndDrag(bool doCommit)
  78. {
  79. if (doCommit)
  80. {
  81. Controller.UpdateLink(InitialState, Link);
  82. }
  83. else
  84. {
  85. if (_isNewLink)
  86. View.Children.Remove((Control)Link);
  87. else
  88. InitialState.UpdateLink(Link);
  89. }
  90. Link.UpdatePath();
  91. Link = null;
  92. Adorner = null;
  93. }
  94. public virtual void BeginDragNewLink(Point start, IPort port)
  95. {
  96. var link = CreateNewLink(port);
  97. if (link != null && link is Control)
  98. {
  99. var thumb = (link.Source != null) ? LinkThumbKind.Target : LinkThumbKind.Source;
  100. View.Children.Add((Control)link);
  101. BeginDrag(start, link, thumb, true);
  102. }
  103. }
  104. protected virtual ILink CreateNewLink(IPort port)
  105. {
  106. var link = new SegmentLink();
  107. BindNewLinkToPort(port, link);
  108. return link;
  109. }
  110. protected virtual void BindNewLinkToPort(IPort port, LinkBase link)
  111. {
  112. link.EndCap = true;
  113. var portBase = port as PortBase;
  114. if (portBase != null)
  115. {
  116. if (portBase.CanAcceptIncomingLinks && !portBase.CanAcceptOutgoingLinks)
  117. link.Target = port;
  118. else
  119. link.Source = port;
  120. }
  121. else
  122. link.Source = port;
  123. }
  124. protected virtual LinkAdorner CreateAdorner()
  125. {
  126. return new LinkAdorner(View, DragStart) { Cursor = Cursors.Cross };
  127. }
  128. protected virtual Vector UpdateVector(Vector vector)
  129. {
  130. return vector;
  131. }
  132. }
  133. }