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
}
}