Workspace.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. using FastReport.Utils;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System.Drawing.Drawing2D;
  6. using System.Windows.Forms;
  7. namespace FastReport.FastQueryBuilder
  8. {
  9. internal class Workspace : UserControl
  10. {
  11. private PosCounter posC = new PosCounter(10, 10);
  12. private List<TableView> tableViews = new List<TableView>();
  13. private LinkMenu linkMenu;
  14. private Link highlightLink;
  15. public Workspace()
  16. {
  17. AllowDrop = true;
  18. BackColor = SystemColors.AppWorkspace;
  19. linkMenu = new LinkMenu(this);
  20. linkMenu.DeleteLink += LinkMenu_DeleteLink;
  21. SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
  22. }
  23. public List<Link> Links { get; set; }
  24. public event AddTableEventHandler OnAddTable;
  25. public void Clear()
  26. {
  27. foreach (TableView c in tableViews)
  28. {
  29. c.Dispose();
  30. }
  31. tableViews.Clear();
  32. Refresh();
  33. }
  34. public void AddTable(Table table) => AddTable(table, posC.Next);
  35. public void AddTable(Table table, Point pos) => OnAddTable?.Invoke(this, new AddTableEventArgs(table, pos));
  36. public ITableView DoAddTable(Table table, Point position)
  37. {
  38. TableView tbl = new TableView();
  39. tbl.OnDeleteTable += OnDeleteTable;
  40. table.TableView = tbl;
  41. tbl.Table = table;
  42. tbl.Location = new Point(-1000, -1000);
  43. tbl.Parent = this;
  44. tbl.Scale(new SizeF(this.DpiMultiplier(), this.DpiMultiplier()));
  45. tbl.UpdateDpiDependencies();
  46. tbl.Location = position.IsEmpty ? posC.Next : position;
  47. tbl.BringToFront();
  48. tableViews.Add(tbl);
  49. Refresh();
  50. return tbl;
  51. }
  52. private void OnDeleteTable(object sender, AddTableEventArgs e)
  53. {
  54. for (int i = Links.Count - 1; i >= 0; i--)
  55. {
  56. if ((Links[i].From.Table == e.table) || (Links[i].To.Table == e.table))
  57. Links.RemoveAt(i);
  58. }
  59. tableViews.Remove((TableView)e.table.TableView);
  60. Refresh();
  61. }
  62. private void LinkMenu_DeleteLink(object sender, EventArgs e)
  63. {
  64. Links.Remove(linkMenu.CurrentLink);
  65. Refresh();
  66. }
  67. private GraphicsPath GetLinkPath(Link link)
  68. {
  69. LinkPosition lp1, lp2;
  70. int cp1 = link.From.Left + link.From.Width / 2;
  71. int cp2 = link.To.Left + link.To.Width / 2;
  72. if (cp1 > cp2)
  73. {
  74. if ((link.From.Left) < link.To.Left + link.To.Width)
  75. {
  76. lp1 = LinkPosition.Right;
  77. lp2 = LinkPosition.Right;
  78. }
  79. else
  80. {
  81. lp1 = LinkPosition.Left;
  82. lp2 = LinkPosition.Right;
  83. }
  84. }
  85. else
  86. {
  87. if ((link.From.Left + link.From.Width) > link.To.Left)
  88. {
  89. lp2 = LinkPosition.Left;
  90. lp1 = LinkPosition.Left;
  91. }
  92. else
  93. {
  94. lp2 = LinkPosition.Left;
  95. lp1 = LinkPosition.Right;
  96. }
  97. }
  98. Point pnt1 = link.From.GetPosition(lp1);
  99. Point pnt2 = link.To.GetPosition(lp2);
  100. int _2 = this.LogicalToDevice(2);
  101. int _4 = this.LogicalToDevice(4);
  102. int _8 = this.LogicalToDevice(8);
  103. var path = new GraphicsPath();
  104. int dx = (lp1 == LinkPosition.Left) ? _8 : -_8;
  105. Point pnt3 = new Point(pnt1.X + dx, pnt1.Y);
  106. path.AddLine(pnt1, pnt3);
  107. path.AddLine(pnt1, pnt2);
  108. dx = (lp2 == LinkPosition.Left) ? _4 : -_4;
  109. pnt3 = new Point(pnt2.X + dx, pnt2.Y);
  110. path.AddLine(pnt2, pnt3);
  111. path.AddRectangle(new Rectangle(pnt3.X + dx - _4, pnt3.Y - _2, _4, _4));
  112. return path;
  113. }
  114. private bool HitTestLink(Link link, Point point)
  115. {
  116. using (var path = GetLinkPath(link))
  117. using (var pen = new Pen(Color.Black, this.LogicalToDevice(5f)))
  118. {
  119. path.Widen(pen);
  120. return path.IsVisible(point);
  121. }
  122. }
  123. private void DrawLink(Link link, Graphics g, bool highlight)
  124. {
  125. using (var path = GetLinkPath(link))
  126. using (Pen pen = new Pen(highlight ? SystemColors.Highlight : Color.Black, this.LogicalToDevice(highlight ? 2 : 1)))
  127. {
  128. g.DrawPath(pen, path);
  129. }
  130. }
  131. protected override void OnDragOver(DragEventArgs e)
  132. {
  133. base.OnDragOver(e);
  134. if (e.Data.GetDataPresent(typeof(Table)))
  135. e.Effect = DragDropEffects.Copy;
  136. else
  137. e.Effect = DragDropEffects.None;
  138. }
  139. protected override void OnDragDrop(DragEventArgs e)
  140. {
  141. base.OnDragDrop(e);
  142. Table _table = (Table)e.Data.GetData(typeof(Table));
  143. if (_table != null)
  144. {
  145. AddTable(_table, PointToClient(new Point(e.X, e.Y)));
  146. }
  147. }
  148. protected override void OnPaint(PaintEventArgs e)
  149. {
  150. base.OnPaint(e);
  151. if (tableViews.Count == 0)
  152. {
  153. TextRenderer.DrawText(e.Graphics, Res.Get("Forms,QueryBuilder,Hint"), Font, DisplayRectangle, Color.Black, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
  154. return;
  155. }
  156. e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
  157. foreach (var link in Links)
  158. {
  159. DrawLink(link, e.Graphics, link == highlightLink);
  160. }
  161. }
  162. protected override void OnMouseMove(MouseEventArgs e)
  163. {
  164. base.OnMouseMove(e);
  165. Link hl = null;
  166. foreach (var link in Links)
  167. {
  168. if (HitTestLink(link, e.Location))
  169. {
  170. hl = link;
  171. break;
  172. }
  173. }
  174. if (highlightLink != hl)
  175. {
  176. highlightLink = hl;
  177. Cursor = hl == null ? Cursors.Default : Cursors.Hand;
  178. Refresh();
  179. }
  180. }
  181. protected override void OnMouseUp(MouseEventArgs e)
  182. {
  183. base.OnMouseUp(e);
  184. if (highlightLink != null)
  185. {
  186. linkMenu.Show(this, e.Location, highlightLink);
  187. }
  188. }
  189. protected override void OnSizeChanged(EventArgs e)
  190. {
  191. base.OnSizeChanged(e);
  192. posC.maxX = Width;
  193. posC.maxY = Height;
  194. }
  195. public void UpdateDpiDependencies()
  196. {
  197. posC.stepX = posC.stepY = this.LogicalToDevice(200);
  198. linkMenu.UpdateDpiDependencies();
  199. foreach (var tv in tableViews)
  200. {
  201. tv.UpdateDpiDependencies();
  202. }
  203. }
  204. }
  205. }