CrossBandObject.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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 System.Drawing.Design;
  8. using System.ComponentModel;
  9. using FastReport.Utils;
  10. using FastReport.TypeEditors;
  11. using FastReport.Design.PageDesigners.Page;
  12. namespace FastReport
  13. {
  14. /// <summary>
  15. /// Specifies the shape of the <b>CrossBandObject</b>.
  16. /// </summary>
  17. internal enum CrossBandShape
  18. {
  19. /// <summary>
  20. /// Specifies the vertical line shape.
  21. /// </summary>
  22. Line,
  23. /// <summary>
  24. /// Specifies the rectangle shape.
  25. /// </summary>
  26. Rectangle
  27. }
  28. /// <summary>
  29. /// Represents an object that can be printed across several bands.
  30. /// </summary>
  31. internal class CrossBandObject : ReportComponentBase
  32. {
  33. private CrossBandShape shape;
  34. private BandBase startBand;
  35. private BandBase endBand;
  36. private float endBandHeight;
  37. #region Properties
  38. /// <summary>
  39. /// Gets or sets the object's shape.
  40. /// </summary>
  41. [DefaultValue(ShapeKind.Rectangle)]
  42. [Category("Appearance")]
  43. public CrossBandShape Shape
  44. {
  45. get { return shape; }
  46. set { shape = value; }
  47. }
  48. [Category("Layout")]
  49. public BandBase EndBand
  50. {
  51. get { return endBand; }
  52. set { endBand = value; }
  53. }
  54. [Category("Layout")]
  55. public float EndBandHeight
  56. {
  57. get { return endBandHeight; }
  58. set
  59. {
  60. endBandHeight = value;
  61. if (endBand != null)
  62. Height = endBand.AbsTop - AbsTop + endBandHeight;
  63. }
  64. }
  65. public override float Top
  66. {
  67. get { return base.Top; }
  68. set
  69. {
  70. base.Top = value;
  71. if (endBand != null)
  72. endBandHeight = AbsBottom - endBand.AbsTop;
  73. }
  74. }
  75. public override float Height
  76. {
  77. get { return base.Height; }
  78. set
  79. {
  80. base.Height = value;
  81. if (endBand != null)
  82. endBandHeight = AbsBottom - endBand.AbsTop;
  83. }
  84. }
  85. #endregion
  86. #region Private Methods
  87. private void FindStartEndBands()
  88. {
  89. startBand = null;
  90. endBand = null;
  91. List<BandBase> list = new List<BandBase>();
  92. foreach (Base c in Page.AllObjects)
  93. {
  94. if (c is BandBase)
  95. list.Add(c as BandBase);
  96. }
  97. int bandGap = ReportWorkspace.ClassicView && IsDesigning ? BandBase.HeaderSize : 4;
  98. foreach (BandBase c in list)
  99. {
  100. bool topInside = AbsTop > c.AbsTop - bandGap && AbsTop < c.AbsBottom + 1;
  101. if (topInside)
  102. {
  103. startBand = c;
  104. break;
  105. }
  106. }
  107. foreach (BandBase c in list)
  108. {
  109. bool bottomInside = AbsBottom > c.AbsTop - bandGap && AbsBottom < c.AbsBottom + 1;
  110. if (bottomInside)
  111. {
  112. endBand = c;
  113. break;
  114. }
  115. }
  116. }
  117. #endregion
  118. #region Protected Methods
  119. /// <inheritdoc/>
  120. protected override SelectionPoint[] GetSelectionPoints()
  121. {
  122. if (Shape == CrossBandShape.Line)
  123. return new SelectionPoint[] {
  124. new SelectionPoint(AbsLeft, AbsTop, SizingPoint.TopCenter),
  125. new SelectionPoint(AbsLeft, AbsTop + Height, SizingPoint.BottomCenter) };
  126. return base.GetSelectionPoints();
  127. }
  128. #endregion
  129. #region Public Methods
  130. /// <inheritdoc/>
  131. public override void Assign(Base source)
  132. {
  133. base.Assign(source);
  134. CrossBandObject src = source as CrossBandObject;
  135. Shape = src.Shape;
  136. EndBand = src.EndBand;
  137. EndBandHeight = src.EndBandHeight;
  138. }
  139. /// <inheritdoc/>
  140. public override void Draw(FRPaintEventArgs e)
  141. {
  142. if (IsDesigning)
  143. {
  144. // force set height
  145. EndBandHeight = EndBandHeight;
  146. }
  147. base.Draw(e);
  148. if (Shape == CrossBandShape.Line)
  149. {
  150. Border.Lines = BorderLines.Left;
  151. Width = 0;
  152. }
  153. Border.Draw(e, new RectangleF(AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY));
  154. }
  155. /// <inheritdoc/>
  156. public override bool PointInObject(PointF point)
  157. {
  158. using (Pen pen = new Pen(Color.Black, 10))
  159. using (GraphicsPath path = new GraphicsPath())
  160. {
  161. path.AddLine(AbsLeft, AbsTop, AbsRight, AbsTop);
  162. path.AddLine(AbsRight, AbsTop, AbsRight, AbsBottom);
  163. path.AddLine(AbsRight, AbsBottom, AbsLeft, AbsBottom);
  164. path.AddLine(AbsLeft, AbsBottom, AbsLeft, AbsTop);
  165. return path.IsOutlineVisible(point, pen);
  166. }
  167. }
  168. /// <inheritdoc/>
  169. public override void CheckParent(bool immediately)
  170. {
  171. if (!(Parent is BandBase) || !IsSelected || IsAncestor)
  172. return;
  173. if (Top < 0 || Top > (Parent as BandBase).Height || EndBand == null ||
  174. EndBandHeight < 0 || EndBandHeight > EndBand.Height)
  175. {
  176. FindStartEndBands();
  177. if (startBand != null && HasFlag(Flags.CanChangeParent))
  178. {
  179. Top = (int)Math.Round((AbsTop - startBand.AbsTop) / Page.SnapSize.Height) * Page.SnapSize.Height;
  180. Parent = startBand;
  181. }
  182. if (endBand != null)
  183. {
  184. Height = endBand.AbsTop - AbsTop + (int)Math.Round((AbsBottom - endBand.AbsTop) / Page.SnapSize.Height) * Page.SnapSize.Height;
  185. }
  186. }
  187. }
  188. /// <inheritdoc/>
  189. public override void Serialize(FRWriter writer)
  190. {
  191. CrossBandObject c = writer.DiffObject as CrossBandObject;
  192. base.Serialize(writer);
  193. if (Shape != c.Shape)
  194. writer.WriteValue("Shape", Shape);
  195. if (EndBand != null)
  196. writer.WriteRef("EndBand", EndBand);
  197. if (FloatDiff(EndBandHeight, c.EndBandHeight))
  198. writer.WriteFloat("EndBandHeight", EndBandHeight);
  199. }
  200. /// <inheritdoc/>
  201. public override void OnBeforeInsert(int flags)
  202. {
  203. Shape = (CrossBandShape)flags;
  204. Border.Lines = BorderLines.All;
  205. }
  206. #endregion
  207. /// <summary>
  208. /// Initializes a new instance of the <see cref="CrossBandObject"/> class with the default settings.
  209. /// </summary>
  210. public CrossBandObject()
  211. {
  212. Border.Lines = BorderLines.All;
  213. }
  214. }
  215. }