Guides.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using FastReport.Utils;
  8. namespace FastReport.Design.PageDesigners.Page
  9. {
  10. internal class Guides
  11. {
  12. private ReportWorkspace workspace;
  13. private List<LinkInfo> guideLinks;
  14. public ReportPage Page
  15. {
  16. get { return workspace.Page; }
  17. }
  18. public Designer Designer
  19. {
  20. get { return workspace.Designer; }
  21. }
  22. private void CheckVGuide(ref float kx, float coord)
  23. {
  24. if (Page.Guides == null)
  25. return;
  26. float closestGuide = float.PositiveInfinity;
  27. foreach (float f in Page.Guides)
  28. {
  29. if (Math.Abs(coord + kx - f) < Math.Abs(coord + kx - closestGuide))
  30. closestGuide = f;
  31. }
  32. if (Math.Abs(coord + kx - closestGuide) < ReportWorkspace.Grid.SnapSize * 2)
  33. kx = closestGuide - coord;
  34. }
  35. private void CheckHGuide(ref float ky, float coord, ComponentBase c)
  36. {
  37. BandBase band = c.Parent as BandBase;
  38. if (band == null || band.Guides == null)
  39. return;
  40. float closestGuide = float.PositiveInfinity;
  41. foreach (float f in band.Guides)
  42. {
  43. if (Math.Abs(coord + ky - f) < Math.Abs(coord + ky - closestGuide))
  44. closestGuide = f;
  45. }
  46. if (Math.Abs(coord + ky - closestGuide) < ReportWorkspace.Grid.SnapSize * 2)
  47. ky = closestGuide - coord;
  48. }
  49. private void DrawGuides(Graphics g, object obj)
  50. {
  51. FloatCollection guides = null;
  52. bool vertical = false;
  53. float offs = 0;
  54. if (obj is ReportPage)
  55. {
  56. guides = (obj as ReportPage).Guides;
  57. vertical = true;
  58. }
  59. else if (obj is BandBase)
  60. {
  61. guides = (obj as BandBase).Guides;
  62. offs = (obj as BandBase).Top;
  63. }
  64. if (guides != null)
  65. {
  66. Pen pen = new Pen(Color.CornflowerBlue);
  67. pen.DashStyle = DashStyle.Dot;
  68. foreach (float f in guides)
  69. {
  70. float scale = workspace.GetScale();
  71. if (vertical)
  72. g.DrawLine(pen, f * scale, 0, f * scale, workspace.Height);
  73. else
  74. {
  75. if (f > 0 && f < (obj as BandBase).Height)
  76. g.DrawLine(pen, 0, (f + offs) * scale, workspace.Width, (f + offs) * scale);
  77. }
  78. }
  79. pen.Dispose();
  80. }
  81. }
  82. public void Draw(Graphics g)
  83. {
  84. // draw guides
  85. DrawGuides(g, Page);
  86. foreach (Base obj in Designer.Objects)
  87. {
  88. if (obj is BandBase)
  89. DrawGuides(g, obj);
  90. }
  91. }
  92. public void CheckGuides(ref float kx, ref float ky)
  93. {
  94. foreach (Base obj in Designer.SelectedObjects)
  95. {
  96. if (obj is ComponentBase && !(obj is BandBase))
  97. {
  98. ComponentBase c = obj as ComponentBase;
  99. CheckVGuide(ref kx, c.Left);
  100. CheckVGuide(ref kx, c.Right);
  101. CheckHGuide(ref ky, c.Top, c);
  102. CheckHGuide(ref ky, c.Bottom, c);
  103. }
  104. }
  105. }
  106. public void BeforeMoveHGuide(BandBase band, int guide)
  107. {
  108. guideLinks.Clear();
  109. foreach (Base obj in Designer.Objects)
  110. {
  111. if (obj is ReportComponentBase && !(obj is BandBase) && obj.Parent == band)
  112. {
  113. ReportComponentBase c = obj as ReportComponentBase;
  114. LinkPoint link = LinkPoint.None;
  115. if (Math.Abs(c.Top - band.Guides[guide]) < 0.01)
  116. link = LinkPoint.Top;
  117. else if (Math.Abs(c.Bottom - band.Guides[guide]) < 0.01)
  118. link = LinkPoint.Bottom;
  119. if (link != LinkPoint.None)
  120. {
  121. LinkInfo info = new LinkInfo();
  122. info.obj = c;
  123. info.link = link;
  124. // check if object is also linked to another guide
  125. int i = band.Guides.IndexOf(c.Top);
  126. if (i != -1 && i != guide)
  127. info.doubleLinked = true;
  128. i = band.Guides.IndexOf(c.Bottom);
  129. if (i != -1 && i != guide)
  130. info.doubleLinked = true;
  131. guideLinks.Add(info);
  132. }
  133. }
  134. }
  135. }
  136. public void MoveHGuide(BandBase band, int guide, float ky)
  137. {
  138. foreach (LinkInfo link in guideLinks)
  139. {
  140. if (!link.doubleLinked)
  141. link.obj.Top += ky;
  142. else
  143. {
  144. if (link.link == LinkPoint.Top)
  145. {
  146. link.obj.Top += ky;
  147. link.obj.Height -= ky;
  148. }
  149. else if (link.link == LinkPoint.Bottom)
  150. link.obj.Height += ky;
  151. }
  152. }
  153. }
  154. public void BeforeMoveVGuide(int guide)
  155. {
  156. guideLinks.Clear();
  157. foreach (Base obj in Designer.Objects)
  158. {
  159. if (obj is ReportComponentBase && !(obj is BandBase))
  160. {
  161. ReportComponentBase c = obj as ReportComponentBase;
  162. LinkPoint link = LinkPoint.None;
  163. if (Math.Abs(c.Left - Page.Guides[guide]) < 0.01)
  164. link = LinkPoint.Left;
  165. else if (Math.Abs(c.Right - Page.Guides[guide]) < 0.01)
  166. link = LinkPoint.Right;
  167. if (link != LinkPoint.None)
  168. {
  169. LinkInfo info = new LinkInfo();
  170. info.obj = c;
  171. info.link = link;
  172. // check if object is also linked to another guide
  173. int i = Page.Guides.IndexOf(c.Left);
  174. if (i != -1 && i != guide)
  175. info.doubleLinked = true;
  176. i = Page.Guides.IndexOf(c.Right);
  177. if (i != -1 && i != guide)
  178. info.doubleLinked = true;
  179. guideLinks.Add(info);
  180. }
  181. }
  182. }
  183. }
  184. public void MoveVGuide(int guide, float kx)
  185. {
  186. foreach (LinkInfo link in guideLinks)
  187. {
  188. if (!link.doubleLinked)
  189. link.obj.Left += kx;
  190. else
  191. {
  192. if (link.link == LinkPoint.Left)
  193. {
  194. link.obj.Left += kx;
  195. link.obj.Width -= kx;
  196. }
  197. else if (link.link == LinkPoint.Right)
  198. link.obj.Width += kx;
  199. }
  200. }
  201. }
  202. public Guides(ReportWorkspace w)
  203. {
  204. workspace = w;
  205. guideLinks = new List<LinkInfo>();
  206. }
  207. private enum LinkPoint { None, Left, Top, Right, Bottom }
  208. private class LinkInfo
  209. {
  210. public ReportComponentBase obj;
  211. public LinkPoint link;
  212. public bool doubleLinked;
  213. }
  214. }
  215. }