RadialPointer.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System.Drawing;
  2. using System.Drawing.Drawing2D;
  3. using FastReport.Utils;
  4. using System.ComponentModel;
  5. namespace FastReport.Gauge.Radial
  6. {
  7. /// <summary>
  8. /// Represents a linear pointer.
  9. /// </summary>
  10. #if !DEBUG
  11. [DesignTimeVisible(false)]
  12. #endif
  13. public class RadialPointer : GaugePointer
  14. {
  15. #region Fields
  16. private RadialScale scale;
  17. private bool gradAutoRotate;
  18. #endregion // Fields
  19. /// <summary>
  20. /// Gets or sets the value, indicating that gradient should be rotated automatically
  21. /// </summary>
  22. [Browsable(true)]
  23. public bool GradientAutoRotate
  24. {
  25. get { return gradAutoRotate; }
  26. set { gradAutoRotate = value; }
  27. }
  28. #region Constructors
  29. /// <summary>
  30. /// Initializes a new instance of the <see cref="RadialPointer"/>
  31. /// </summary>
  32. /// <param name="parent">The parent gauge object.</param>
  33. /// <param name="scale">The scale object.</param>
  34. public RadialPointer(GaugeObject parent, RadialScale scale) : base(parent)
  35. {
  36. this.scale = scale;
  37. gradAutoRotate = true;
  38. }
  39. #endregion // Constructors
  40. #region Private Methods
  41. private void DrawHorz(FRPaintEventArgs e)
  42. {
  43. IGraphics g = e.Graphics;
  44. Pen pen = e.Cache.GetPen(BorderColor, BorderWidth * e.ScaleX, DashStyle.Solid);
  45. PointF center = (Parent as RadialGauge).Center;
  46. float circleWidth = Parent.Width / 16f;
  47. float circleHeight = Parent.Height / 16f;
  48. RectangleF pointerCircle = new RectangleF(center.X - circleWidth / 2 * e.ScaleX, center.Y - circleHeight / 2 * e.ScaleY, circleWidth * e.ScaleX, circleHeight * e.ScaleY);
  49. //double rotateTo = (scale.AverageValue - Parent.Minimum);
  50. double startAngle = -135 * RadialGauge.Radians;
  51. double angle = (Parent.Value - Parent.Minimum) / scale.StepValue * scale.MajorStep * RadialGauge.Radians;
  52. if ((Parent as RadialGauge).Type == RadialGaugeType.Semicircle)
  53. {
  54. if ((Parent as RadialGauge).Position == RadialGaugePosition.Bottom || (Parent as RadialGauge).Position == RadialGaugePosition.Top)
  55. {
  56. startAngle = -90 * RadialGauge.Radians;
  57. if ((Parent as RadialGauge).Position == RadialGaugePosition.Bottom)
  58. angle *= -1;
  59. }
  60. else if ((Parent as RadialGauge).Position == RadialGaugePosition.Left)
  61. startAngle = -180 * RadialGauge.Radians;
  62. else if ((Parent as RadialGauge).Position == RadialGaugePosition.Right)
  63. {
  64. startAngle = -180 * RadialGauge.Radians;
  65. angle *= -1;
  66. }
  67. }
  68. else if (RadialUtils.IsQuadrant(Parent))
  69. {
  70. if (RadialUtils.IsLeft(Parent) && RadialUtils.IsTop(Parent))
  71. startAngle = -90 * RadialGauge.Radians;
  72. else if (RadialUtils.IsLeft(Parent) && RadialUtils.IsBottom(Parent))
  73. startAngle = -180 * RadialGauge.Radians;
  74. else if (RadialUtils.IsRight(Parent) && RadialUtils.IsTop(Parent))
  75. startAngle = 90 * RadialGauge.Radians;
  76. else if (RadialUtils.IsRight(Parent) && RadialUtils.IsBottom(Parent))
  77. {
  78. startAngle = 180 * RadialGauge.Radians;
  79. angle *= -1;
  80. }
  81. }
  82. //double startAngle = rotateTo / scale.StepValue * -scale.MajorStep * RadialGauge.Radians;
  83. float ptrLineY = center.Y - pointerCircle.Width / 2 - pointerCircle.Width / 5;
  84. float ptrLineY1 = scale.AvrTick.Y + scale.MinorTicks.Length * 1.7f;
  85. float ptrLineWidth = circleWidth / 3 * e.ScaleX;
  86. PointF[] pointerPerpStrt = new PointF[2];
  87. pointerPerpStrt[0] = new PointF(center.X - ptrLineWidth, ptrLineY);
  88. pointerPerpStrt[1] = new PointF(center.X + ptrLineWidth, ptrLineY);
  89. PointF[] pointerPerpEnd = new PointF[2];
  90. pointerPerpEnd[0] = new PointF(center.X - ptrLineWidth / 3, ptrLineY1);
  91. pointerPerpEnd[1] = new PointF(center.X + ptrLineWidth / 3, ptrLineY1);
  92. pointerPerpStrt = RadialUtils.RotateVector(pointerPerpStrt, startAngle, center);
  93. pointerPerpEnd = RadialUtils.RotateVector(pointerPerpEnd, startAngle, center);
  94. PointF[] rotatedPointerPerpStrt = RadialUtils.RotateVector(pointerPerpStrt, angle, center);
  95. PointF[] rotatedPointerPerpEnd = RadialUtils.RotateVector(pointerPerpEnd, angle, center);
  96. //calc brush rect
  97. float x = 0, y = 0, dx = 0, dy = 0;
  98. if (angle / RadialGauge.Radians >= 0 && angle / RadialGauge.Radians < 45)
  99. {
  100. x = rotatedPointerPerpEnd[1].X;
  101. y = rotatedPointerPerpEnd[0].Y - (rotatedPointerPerpEnd[0].Y - pointerCircle.Y);
  102. dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X;
  103. dy = rotatedPointerPerpEnd[0].Y - pointerCircle.Y;
  104. }
  105. else if (angle / RadialGauge.Radians >= 45 && angle / RadialGauge.Radians < 90)
  106. {
  107. x = rotatedPointerPerpEnd[0].X;
  108. y = rotatedPointerPerpEnd[1].Y;
  109. dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X;
  110. dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[0].Y;
  111. }
  112. else if (angle / RadialGauge.Radians >= 90 && angle / RadialGauge.Radians < 135)
  113. {
  114. x = rotatedPointerPerpEnd[0].X;
  115. y = rotatedPointerPerpEnd[1].Y;
  116. dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X;
  117. dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[1].Y;
  118. }
  119. else if (angle / RadialGauge.Radians >= 135 && angle / RadialGauge.Radians < 225)
  120. {
  121. x = pointerCircle.X;
  122. y = rotatedPointerPerpEnd[0].Y;
  123. dx = rotatedPointerPerpEnd[1].X - pointerCircle.X;
  124. dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[0].Y;
  125. }
  126. else if (angle / RadialGauge.Radians >= 225)
  127. {
  128. x = pointerCircle.X;
  129. y = pointerCircle.Y;
  130. dx = rotatedPointerPerpEnd[0].X - pointerCircle.X;
  131. dy = rotatedPointerPerpEnd[1].Y - pointerCircle.Y;
  132. }
  133. RectangleF brushRect = new RectangleF(x, y, dx, dy);
  134. if (gradAutoRotate && Fill is LinearGradientFill)
  135. {
  136. (Fill as LinearGradientFill).Angle = (int)(startAngle / RadialGauge.Radians + angle / RadialGauge.Radians) + 90;
  137. }
  138. Brush brush = Fill.CreateBrush(brushRect, e.ScaleX, e.ScaleY);
  139. PointF[] p = new PointF[]
  140. {
  141. rotatedPointerPerpStrt[0],
  142. rotatedPointerPerpStrt[1],
  143. rotatedPointerPerpEnd[1],
  144. rotatedPointerPerpEnd[0],
  145. };
  146. GraphicsPath path = new GraphicsPath();
  147. path.AddLines(p);
  148. path.AddLine(p[3], p[0]);
  149. g.FillAndDrawEllipse(pen, brush, pointerCircle);
  150. g.FillAndDrawPath(pen, brush, path);
  151. }
  152. #endregion // Private Methods
  153. #region Public Methods
  154. /// <inheritdoc/>
  155. public override void Draw(FRPaintEventArgs e)
  156. {
  157. base.Draw(e);
  158. DrawHorz(e);
  159. }
  160. #endregion // Public Methods
  161. }
  162. }