using System.Drawing; using System.Drawing.Drawing2D; using FastReport.Utils; using System.ComponentModel; namespace FastReport.Gauge.Radial { /// /// Represents a linear pointer. /// #if !DEBUG [DesignTimeVisible(false)] #endif public class RadialPointer : GaugePointer { #region Fields private RadialScale scale; private bool gradAutoRotate; #endregion // Fields /// /// Gets or sets the value, indicating that gradient should be rotated automatically /// [Browsable(true)] public bool GradientAutoRotate { get { return gradAutoRotate; } set { gradAutoRotate = value; } } #region Constructors /// /// Initializes a new instance of the /// /// The parent gauge object. /// The scale object. public RadialPointer(GaugeObject parent, RadialScale scale) : base(parent) { this.scale = scale; gradAutoRotate = true; } #endregion // Constructors #region Private Methods private void DrawHorz(FRPaintEventArgs e) { IGraphics g = e.Graphics; Pen pen = e.Cache.GetPen(BorderColor, BorderWidth * e.ScaleX, DashStyle.Solid); PointF center = (Parent as RadialGauge).Center; float circleWidth = Parent.Width / 16f; float circleHeight = Parent.Height / 16f; RectangleF pointerCircle = new RectangleF(center.X - circleWidth/2 * e.ScaleX, center.Y - circleHeight/2 * e.ScaleY, circleWidth * e.ScaleX, circleHeight * e.ScaleY); //double rotateTo = (scale.AverageValue - Parent.Minimum); double startAngle = -135 * RadialGauge.Radians; double angle = (Parent.Value - Parent.Minimum) / scale.StepValue * scale.MajorStep * RadialGauge.Radians; if ((Parent as RadialGauge).Type == RadialGaugeType.Semicircle) { if ((Parent as RadialGauge).Position == RadialGaugePosition.Bottom || (Parent as RadialGauge).Position == RadialGaugePosition.Top) { startAngle = -90 * RadialGauge.Radians; if((Parent as RadialGauge).Position == RadialGaugePosition.Bottom) angle *= -1; } else if ((Parent as RadialGauge).Position == RadialGaugePosition.Left) startAngle = -180 * RadialGauge.Radians; else if ((Parent as RadialGauge).Position == RadialGaugePosition.Right) { startAngle = -180 * RadialGauge.Radians; angle *= -1; } } else if (RadialUtils.IsQuadrant(Parent)) { if (RadialUtils.IsLeft(Parent) && RadialUtils.IsTop(Parent)) startAngle = -90 * RadialGauge.Radians; else if (RadialUtils.IsLeft(Parent) && RadialUtils.IsBottom(Parent)) startAngle = -180 * RadialGauge.Radians; else if (RadialUtils.IsRight(Parent) && RadialUtils.IsTop(Parent)) startAngle = 90 * RadialGauge.Radians; else if (RadialUtils.IsRight(Parent) && RadialUtils.IsBottom(Parent)) { startAngle = 180 * RadialGauge.Radians; angle *= -1; } } //double startAngle = rotateTo / scale.StepValue * -scale.MajorStep * RadialGauge.Radians; float ptrLineY = center.Y - pointerCircle.Width / 2 - pointerCircle.Width / 5; float ptrLineY1 = scale.AvrTick.Y + scale.MinorTicks.Length * 1.7f; float ptrLineWidth = circleWidth / 3 * e.ScaleX; PointF[] pointerPerpStrt = new PointF[2]; pointerPerpStrt[0] = new PointF(center.X - ptrLineWidth, ptrLineY); pointerPerpStrt[1] = new PointF(center.X + ptrLineWidth, ptrLineY); PointF[] pointerPerpEnd = new PointF[2]; pointerPerpEnd[0] = new PointF(center.X - ptrLineWidth / 3, ptrLineY1); pointerPerpEnd[1] = new PointF(center.X + ptrLineWidth / 3, ptrLineY1); pointerPerpStrt = RadialUtils.RotateVector(pointerPerpStrt, startAngle, center); pointerPerpEnd = RadialUtils.RotateVector(pointerPerpEnd, startAngle, center); PointF[] rotatedPointerPerpStrt = RadialUtils.RotateVector(pointerPerpStrt, angle, center); PointF[] rotatedPointerPerpEnd = RadialUtils.RotateVector(pointerPerpEnd, angle, center); //calc brush rect float x = 0, y = 0, dx = 0, dy = 0; if(angle / RadialGauge.Radians >= 0 && angle / RadialGauge.Radians < 45) { x = rotatedPointerPerpEnd[1].X; y = rotatedPointerPerpEnd[0].Y - (rotatedPointerPerpEnd[0].Y - pointerCircle.Y); dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X; dy = rotatedPointerPerpEnd[0].Y - pointerCircle.Y; } else if (angle / RadialGauge.Radians >= 45 && angle / RadialGauge.Radians < 90) { x = rotatedPointerPerpEnd[0].X; y = rotatedPointerPerpEnd[1].Y; dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X; dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[0].Y; } else if (angle / RadialGauge.Radians >= 90 && angle / RadialGauge.Radians < 135) { x = rotatedPointerPerpEnd[0].X; y = rotatedPointerPerpEnd[1].Y; dx = pointerCircle.X + pointerCircle.Width - rotatedPointerPerpEnd[0].X; dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[1].Y; } else if (angle / RadialGauge.Radians >= 135 && angle / RadialGauge.Radians < 225) { x = pointerCircle.X; y = rotatedPointerPerpEnd[0].Y; dx = rotatedPointerPerpEnd[1].X - pointerCircle.X; dy = pointerCircle.Y + pointerCircle.Height - rotatedPointerPerpEnd[0].Y; } else if (angle / RadialGauge.Radians >= 225) { x = pointerCircle.X; y = pointerCircle.Y; dx = rotatedPointerPerpEnd[0].X - pointerCircle.X; dy = rotatedPointerPerpEnd[1].Y - pointerCircle.Y; } RectangleF brushRect = new RectangleF(x, y, dx, dy); if (gradAutoRotate && Fill is LinearGradientFill) { (Fill as LinearGradientFill).Angle = (int)(startAngle / RadialGauge.Radians + angle / RadialGauge.Radians) + 90; } Brush brush = Fill.CreateBrush(brushRect, e.ScaleX, e.ScaleY); PointF[] p = new PointF[] { rotatedPointerPerpStrt[0], rotatedPointerPerpStrt[1], rotatedPointerPerpEnd[1], rotatedPointerPerpEnd[0], }; GraphicsPath path = new GraphicsPath(); path.AddLines(p); path.AddLine(p[3], p[0]); g.FillAndDrawEllipse(pen, brush, pointerCircle); g.FillAndDrawPath(pen, brush, path); } #endregion // Private Methods #region Public Methods /// public override void Assign(GaugePointer src) { base.Assign(src); RadialPointer s = src as RadialPointer; } /// public override void Draw(FRPaintEventArgs e) { base.Draw(e); DrawHorz(e); } /// public override void Serialize(FRWriter writer, string prefix, GaugePointer diff) { base.Serialize(writer, prefix, diff); } #endregion // Public Methods } }