1071 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1071 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.ComponentModel;
 | |
| using System.Drawing;
 | |
| using System.Drawing.Design;
 | |
| using System.Drawing.Drawing2D;
 | |
| using System.Windows.Forms;
 | |
| using DevComponents.Instrumentation.Primitives;
 | |
| 
 | |
| namespace DevComponents.Instrumentation
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Collection of GaugeRanges
 | |
|     /// </summary>
 | |
|     public class GaugeRangeCollection : GenericCollection<GaugeRange>
 | |
|     {
 | |
|         #region ICloneable Members
 | |
| 
 | |
|         public override object Clone()
 | |
|         {
 | |
|             GaugeRangeCollection copy = new GaugeRangeCollection();
 | |
| 
 | |
|             CopyToItem(copy);
 | |
| 
 | |
|             return (copy);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CopyToItem
 | |
| 
 | |
|         internal void CopyToItem(GaugeRangeCollection copy)
 | |
|         {
 | |
|             foreach (GaugeRange item in this)
 | |
|             {
 | |
|                 GaugeRange ic = new GaugeRange();
 | |
| 
 | |
|                 item.CopyToItem(ic);
 | |
| 
 | |
|                 copy.Add(ic);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     public class GaugeRange : GaugeStrip
 | |
|     {
 | |
|         #region Private variables
 | |
| 
 | |
|         private DisplayPlacement _Placement;
 | |
| 
 | |
|         private float _StartWidth;
 | |
|         private float _EndWidth;
 | |
|         private int _Radius;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         public GaugeRange(GaugeScale scale)
 | |
|             : base(scale)
 | |
|         {
 | |
|             InitGaugeRange();
 | |
|         }
 | |
| 
 | |
|         public GaugeRange()
 | |
|         {
 | |
|             InitGaugeRange();
 | |
|         }
 | |
| 
 | |
|         #region InitGaugeRange
 | |
| 
 | |
|         private void InitGaugeRange()
 | |
|         {
 | |
|             _Placement = DisplayPlacement.Near;
 | |
| 
 | |
|             _StartWidth = .15f;
 | |
|             _EndWidth = .30f;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region EndWidth
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the End Width of the Range, specified as a percentage
 | |
|         /// </summary>
 | |
|         [Browsable(true)]
 | |
|         [Category("Layout"), DefaultValue(.3f)]
 | |
|         [Editor("DevComponents.Instrumentation.Design.WidthMaxRangeValueEditor, DevComponents.Instrumentation.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=76cb4c6eb576bca5", typeof(UITypeEditor))]
 | |
|         [Description("Indicates the End Width of the Range, specified as a percentage.")]
 | |
|         public float EndWidth
 | |
|         {
 | |
|             get { return (_EndWidth); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_EndWidth != value)
 | |
|                 {
 | |
|                     if (value < 0 || value > 1)
 | |
|                         throw new ArgumentException("Width must be bwtween 0 and 1");
 | |
| 
 | |
|                     _EndWidth = value;
 | |
| 
 | |
|                     OnGaugeItemChanged(true);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Placement
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the Placement of the Range with respect to the Scale
 | |
|         /// </summary>
 | |
|         [Browsable(true)]
 | |
|         [Category("Layout"), DefaultValue(DisplayPlacement.Near)]
 | |
|         [Description("Indicates the Placement of the Range with respect to the Scale.")]
 | |
|         public DisplayPlacement Placement
 | |
|         {
 | |
|             get { return (_Placement); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_Placement != value)
 | |
|                 {
 | |
|                     _Placement = value;
 | |
| 
 | |
|                     OnGaugeItemChanged(true);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region StartWidth
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the Start Width of the Range, specified as a percentage
 | |
|         /// </summary>
 | |
|         [Browsable(true)]
 | |
|         [Category("Layout"), DefaultValue(.15f)]
 | |
|         [Editor("DevComponents.Instrumentation.Design.WidthMaxRangeValueEditor, DevComponents.Instrumentation.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=76cb4c6eb576bca5", typeof(UITypeEditor))]
 | |
|         [Description("Indicates the Start Width of the Range, specified as a percentage.")]
 | |
|         public float StartWidth
 | |
|         {
 | |
|             get { return (_StartWidth); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_StartWidth != value)
 | |
|                 {
 | |
|                     if (value < 0 || value > 1)
 | |
|                         throw new ArgumentException("Width must be bwtween 0 and 1");
 | |
| 
 | |
|                     _StartWidth = value;
 | |
| 
 | |
|                     OnGaugeItemChanged(true);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Internal properties
 | |
| 
 | |
|         #region AbsScaleOffset
 | |
| 
 | |
|         internal int AbsScaleOffset
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (Scale is GaugeCircularScale)
 | |
|                     return ((int)(((GaugeCircularScale)Scale).AbsRadius * ScaleOffset));
 | |
| 
 | |
|                 return ((int)(((GaugeLinearScale)Scale).AbsScaleWidth * ScaleOffset));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RecalcLayout
 | |
| 
 | |
|         public override void RecalcLayout()
 | |
|         {
 | |
|             if (NeedRecalcLayout == true)
 | |
|             {
 | |
|                 base.RecalcLayout();
 | |
| 
 | |
|                 if (Scale is GaugeCircularScale)
 | |
|                     RecalcCircularLayout(Scale as GaugeCircularScale);
 | |
| 
 | |
|                 else if (Scale is GaugeLinearScale)
 | |
|                     RecalcLinearLayout(Scale as GaugeLinearScale);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RecalcCircularLayout
 | |
| 
 | |
|         private void RecalcCircularLayout(GaugeCircularScale scale)
 | |
|         {
 | |
|             _Radius = scale.AbsRadius;
 | |
| 
 | |
|             Point center = Scale.Center;
 | |
|             int offset = AbsScaleOffset;
 | |
|             int scaleWidth = (int)(_Radius * scale.Width);
 | |
| 
 | |
|             switch (_Placement)
 | |
|             {
 | |
|                 case DisplayPlacement.Near:
 | |
|                     _Radius -= ((scaleWidth / 2) + offset);
 | |
|                     break;
 | |
| 
 | |
|                 case DisplayPlacement.Center:
 | |
|                     _Radius += offset;
 | |
| 
 | |
|                     break;
 | |
| 
 | |
|                 case DisplayPlacement.Far:
 | |
|                     _Radius += ((scaleWidth / 2) + offset);
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             Bounds = new Rectangle(center.X - _Radius,
 | |
|                                    center.Y - _Radius, _Radius * 2, _Radius * 2);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RecalcLinearLayout
 | |
| 
 | |
|         private void RecalcLinearLayout(GaugeLinearScale scale)
 | |
|         {
 | |
|             float spread = (float)Math.Abs(scale.MaxValue - scale.MinValue);
 | |
| 
 | |
|             if (spread == 0)
 | |
|                 spread = 1;
 | |
| 
 | |
|             if (scale.Orientation == Orientation.Horizontal)
 | |
|                 CalcHorizontalMetrics(scale, spread);
 | |
|             else
 | |
|                 CalcVerticalMetrics(scale, spread);
 | |
|         }
 | |
| 
 | |
|         #region CalcHorizontalMetrics
 | |
| 
 | |
|         private void CalcHorizontalMetrics(GaugeLinearScale scale, float spread)
 | |
|         {
 | |
|             int length = scale.ScaleBounds.Width;
 | |
|             int width = scale.Bounds.Height;
 | |
|             int scaleWidth = scale.ScaleBounds.Height;
 | |
| 
 | |
|             float dl = length / spread;
 | |
| 
 | |
|             int start = (int)(dl * MinValue);
 | |
|             int len = (int)(dl * (MaxValue - MinValue));
 | |
|             int offset = (int)(width * ScaleOffset);
 | |
| 
 | |
|             int y = 0;
 | |
| 
 | |
|             switch (_Placement)
 | |
|             {
 | |
|                 case DisplayPlacement.Near:
 | |
|                     y -= ((scaleWidth / 2) + offset);
 | |
|                     break;
 | |
| 
 | |
|                 case DisplayPlacement.Center:
 | |
|                     y += offset;
 | |
|                     break;
 | |
| 
 | |
|                 case DisplayPlacement.Far:
 | |
|                     y += ((scaleWidth / 2) + offset);
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             Rectangle r = scale.Bounds;
 | |
| 
 | |
|             if (scale.Reversed == true)
 | |
|                 r.X = r.Right - (start + len);
 | |
|             else
 | |
|                 r.X += start;
 | |
| 
 | |
|             r.Width = len;
 | |
|             r.Y = scale.Center.Y + y;
 | |
|             r.Height = 0;
 | |
| 
 | |
|             Bounds = r;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CalcVerticalMetrics
 | |
| 
 | |
|         private void CalcVerticalMetrics(GaugeLinearScale scale, float spread)
 | |
|         {
 | |
|             int length = scale.ScaleBounds.Height;
 | |
|             int width = scale.Bounds.Width;
 | |
|             int scaleWidth = scale.ScaleBounds.Width;
 | |
| 
 | |
|             float dl = length / spread;
 | |
| 
 | |
|             int start = (int)(dl * MinValue);
 | |
|             int len = (int)(dl * (MaxValue - MinValue));
 | |
|             int offset = (int)(width * ScaleOffset);
 | |
| 
 | |
|             int x = 0;
 | |
| 
 | |
|             switch (_Placement)
 | |
|             {
 | |
|                 case DisplayPlacement.Near:
 | |
|                     x -= ((scaleWidth / 2) + offset);
 | |
|                     break;
 | |
| 
 | |
|                 case DisplayPlacement.Center:
 | |
|                     x += offset;
 | |
|                     break;
 | |
| 
 | |
|                 case DisplayPlacement.Far:
 | |
|                     x += ((scaleWidth / 2) + offset);
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             Rectangle r = scale.Bounds;
 | |
| 
 | |
|             if (scale.Reversed == true)
 | |
|                 r.Y += start;
 | |
|             else
 | |
|                 r.Y = r.Bottom - (start + len);
 | |
| 
 | |
|             r.X = scale.Center.X + x;
 | |
|             r.Width = 0;
 | |
|             r.Height = len;
 | |
| 
 | |
|             Bounds = r;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region OnPaint
 | |
| 
 | |
|         public override void OnPaint(PaintEventArgs e)
 | |
|         {
 | |
|             RecalcLayout();
 | |
| 
 | |
|             if (Scale.GaugeControl.OnPreRenderScaleRange(e, this) == false)
 | |
|             {
 | |
|                 if (Scale is GaugeCircularScale)
 | |
|                     PaintCircularRange(e, Scale as GaugeCircularScale);
 | |
| 
 | |
|                 else if (Scale is GaugeLinearScale)
 | |
|                     PaintLinearRange(e, Scale as GaugeLinearScale);
 | |
| 
 | |
|                 Scale.GaugeControl.OnPostRenderScaleRange(e, this);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintCircularRange
 | |
| 
 | |
|         private void PaintCircularRange(PaintEventArgs e, GaugeCircularScale scale)
 | |
|         {
 | |
|             GraphicsPath path = GetRangePath();
 | |
| 
 | |
|             if (path != null)
 | |
|             {
 | |
|                 if (SweepAngle != 0 && _Radius > 1)
 | |
|                 {
 | |
|                     int radius = scale.AbsRadius;
 | |
| 
 | |
|                     int n1 = (int)(radius * _StartWidth);
 | |
|                     int n2 = (int)(radius * _EndWidth);
 | |
| 
 | |
|                     if (_Radius - n1 <= 0)
 | |
|                         n1 = _Radius - 1;
 | |
| 
 | |
|                     if (_Radius - n2 <= 0)
 | |
|                         n2 = _Radius - 1;
 | |
| 
 | |
|                     PaintRange(e.Graphics, path, n1, n2);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetCircularRangePath
 | |
| 
 | |
|         private GraphicsPath GetCircularRangePath(int n1, int n2)
 | |
|         {
 | |
|             switch (_Placement)
 | |
|             {
 | |
|                 case DisplayPlacement.Near:
 | |
|                     return (GetNearCircularRangePath(n1, n2));
 | |
| 
 | |
|                 case DisplayPlacement.Center:
 | |
|                     return (GetCenterCircularRangePath(n1, n2));
 | |
| 
 | |
|                 default:
 | |
|                     return (GetFarCircularRangePath(n1, n2));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetNearCircularRangePath
 | |
| 
 | |
|         private GraphicsPath GetNearCircularRangePath(int n1, int n2)
 | |
|         {
 | |
|             GraphicsPath path = new GraphicsPath();
 | |
| 
 | |
|             float angle = StartAngle + SweepAngle;
 | |
| 
 | |
|             path.AddArc(Bounds, StartAngle, SweepAngle);
 | |
| 
 | |
|             if (n1 == n2)
 | |
|             {
 | |
|                 Rectangle r = Bounds;
 | |
|                 r.Inflate(-n1, -n1);
 | |
| 
 | |
|                 path.AddArc(r, angle, -SweepAngle);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int n = path.PointCount;
 | |
| 
 | |
|                 float dx = SweepAngle / n;
 | |
|                 float dy = (float)(n2 - n1) / n;
 | |
|                 float radius = _Radius - n2;
 | |
| 
 | |
|                 PointF[] pts = new PointF[n + 1];
 | |
| 
 | |
|                 for (int i = 0; i < n; i++)
 | |
|                 {
 | |
|                     pts[i] = GetPoint(radius, angle);
 | |
| 
 | |
|                     radius += dy;
 | |
|                     angle -= dx;
 | |
|                 }
 | |
| 
 | |
|                 pts[n] = GetPoint(_Radius - n1, StartAngle);
 | |
| 
 | |
|                 path.AddCurve(pts);
 | |
|             }
 | |
| 
 | |
|             path.CloseFigure();
 | |
| 
 | |
|             return (path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetCenterCircularRangePath
 | |
| 
 | |
|         private GraphicsPath GetCenterCircularRangePath(int n1, int n2)
 | |
|         {
 | |
|             GraphicsPath path = new GraphicsPath();
 | |
| 
 | |
|             Rectangle r = Bounds;
 | |
|             r.Inflate(n1 / 2, n1 / 2);
 | |
| 
 | |
|             path.AddArc(r, StartAngle, SweepAngle);
 | |
| 
 | |
|             if (n1 == n2)
 | |
|             {
 | |
|                 r.Inflate(-n1, -n1);
 | |
| 
 | |
|                 path.AddArc(r, StartAngle + SweepAngle, -SweepAngle);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int n = path.PointCount;
 | |
|                 path.Reset();
 | |
| 
 | |
|                 float angle = StartAngle;
 | |
|                 float radius = _Radius + (n1 / 2);
 | |
| 
 | |
|                 float dx = SweepAngle / n;
 | |
|                 float dy = (float)(n2 - n1) / n / 2;
 | |
| 
 | |
|                 PointF[] pts = new PointF[n + 1];
 | |
| 
 | |
|                 for (int i = 0; i < n; i++)
 | |
|                 {
 | |
|                     pts[i] = GetPoint(radius, angle);
 | |
| 
 | |
|                     radius += dy;
 | |
|                     angle += dx;
 | |
|                 }
 | |
| 
 | |
|                 pts[n] = GetPoint(radius, angle);
 | |
| 
 | |
|                 path.AddCurve(pts);
 | |
| 
 | |
|                 radius = _Radius - (n2 / 2);
 | |
| 
 | |
|                 for (int i = 0; i < n; i++)
 | |
|                 {
 | |
|                     pts[i] = GetPoint(radius, angle);
 | |
| 
 | |
|                     radius += dy;
 | |
|                     angle -= dx;
 | |
|                 }
 | |
| 
 | |
|                 pts[n] = GetPoint(radius, angle);
 | |
| 
 | |
|                 path.AddCurve(pts);
 | |
|             }
 | |
| 
 | |
|             path.CloseFigure();
 | |
| 
 | |
|             return (path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetFarCircularRangePath
 | |
| 
 | |
|         private GraphicsPath GetFarCircularRangePath(int n1, int n2)
 | |
|         {
 | |
|             GraphicsPath path = new GraphicsPath();
 | |
| 
 | |
|             float angle = StartAngle + SweepAngle;
 | |
| 
 | |
|             path.AddArc(Bounds, StartAngle, SweepAngle);
 | |
| 
 | |
|             if (n1 == n2)
 | |
|             {
 | |
|                 Rectangle r = Bounds;
 | |
|                 r.Inflate(n1, n1);
 | |
| 
 | |
|                 path.AddArc(r, angle, -SweepAngle);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int n = path.PointCount;
 | |
| 
 | |
|                 float radius = _Radius + n2;
 | |
|                 float dx = SweepAngle/n;
 | |
|                 float dy = (float)(n2 - n1) / n;
 | |
| 
 | |
|                 PointF[] pts = new PointF[n + 1];
 | |
| 
 | |
|                 for (int i = 0; i < n; i++)
 | |
|                 {
 | |
|                     pts[i] = GetPoint(radius, angle);
 | |
| 
 | |
|                     radius -= dy;
 | |
|                     angle -= dx;
 | |
|                 }
 | |
| 
 | |
|                 pts[n] = GetPoint(_Radius + n1, StartAngle);
 | |
| 
 | |
|                 path.AddCurve(pts);
 | |
|             }
 | |
| 
 | |
|             path.CloseFigure();
 | |
| 
 | |
|             return (path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintLinearRange
 | |
| 
 | |
|         private void PaintLinearRange(PaintEventArgs e, GaugeLinearScale scale)
 | |
|         {
 | |
|             GraphicsPath path = GetRangePath();
 | |
| 
 | |
|             if (path != null)
 | |
|             {
 | |
|                 int width = scale.AbsWidth;
 | |
| 
 | |
|                 int n1 = (int)(width * _StartWidth);
 | |
|                 int n2 = (int)(width * _EndWidth);
 | |
| 
 | |
|                 if (n1 > 0 || n2 > 0)
 | |
|                     PaintRange(e.Graphics, path, n1, n2);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetLinearRangePath
 | |
| 
 | |
|         private GraphicsPath GetLinearRangePath(
 | |
|             int n1, int n2, Orientation orientation)
 | |
|         {
 | |
|             if (Scale.Reversed == true)
 | |
|             {
 | |
|                 int n3 = n1;
 | |
| 
 | |
|                 n1 = n2;
 | |
|                 n2 = n3;
 | |
|             }
 | |
| 
 | |
|             switch (_Placement)
 | |
|             {
 | |
|                 case DisplayPlacement.Near:
 | |
|                     return (GetNearLinearRangePath(n1, n2, orientation));
 | |
| 
 | |
|                 case DisplayPlacement.Center:
 | |
|                     return (GetCenterLinearRangePath(n1, n2, orientation));
 | |
| 
 | |
|                 default:
 | |
|                     return (GetFarLinearRangePath(n1, n2, orientation));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region GetNearLinearRangePath
 | |
| 
 | |
|         private GraphicsPath GetNearLinearRangePath(
 | |
|             int n1, int n2, Orientation orientation)
 | |
|         {
 | |
|             GraphicsPath path = new GraphicsPath();
 | |
| 
 | |
|             if (orientation == Orientation.Horizontal)
 | |
|             {
 | |
|                 Point[] pts = new Point[] {
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                     new Point(Bounds.Right, Bounds.Y),
 | |
|                     new Point(Bounds.Right, Bounds.Y - n2),
 | |
|                     new Point(Bounds.X, Bounds.Y - n1),
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                 };
 | |
| 
 | |
|                 path.AddLines(pts);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Point[] pts = new Point[] {
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                     new Point(Bounds.X, Bounds.Bottom),
 | |
|                     new Point(Bounds.X - n1, Bounds.Bottom),
 | |
|                     new Point(Bounds.X - n2, Bounds.Y),
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                 };
 | |
| 
 | |
|                 path.AddLines(pts);
 | |
|             }
 | |
| 
 | |
|             return (path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetCenterLinearRangePath
 | |
| 
 | |
|         private GraphicsPath GetCenterLinearRangePath(
 | |
|             int n1, int n2, Orientation orientation)
 | |
|         {
 | |
|             GraphicsPath path = new GraphicsPath();
 | |
| 
 | |
|             int dn1 = n1 / 2;
 | |
|             int dn2 = n2 / 2;
 | |
| 
 | |
|             if (orientation == Orientation.Horizontal)
 | |
|             {
 | |
|                 Point[] pts = new Point[] {
 | |
|                     new Point(Bounds.X, Bounds.Y + dn1),
 | |
|                     new Point(Bounds.Right, Bounds.Y + dn2),
 | |
|                     new Point(Bounds.Right, Bounds.Y - dn2),
 | |
|                     new Point(Bounds.X, Bounds.Y - dn1),
 | |
|                     new Point(Bounds.X, Bounds.Y + dn1),
 | |
|                 };
 | |
| 
 | |
|                 path.AddLines(pts);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Point[] pts = new Point[] {
 | |
|                     new Point(Bounds.X + dn2, Bounds.Y),
 | |
|                     new Point(Bounds.Right + dn1, Bounds.Bottom),
 | |
|                     new Point(Bounds.Right - dn1, Bounds.Bottom),
 | |
|                     new Point(Bounds.X - dn2, Bounds.Y),
 | |
|                     new Point(Bounds.X + dn2, Bounds.Y),
 | |
|                 };
 | |
| 
 | |
|                 path.AddLines(pts);
 | |
|             }
 | |
| 
 | |
|             return (path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetFarLinearRangePath
 | |
| 
 | |
|         private GraphicsPath GetFarLinearRangePath(
 | |
|             int n1, int n2, Orientation orientation)
 | |
|         {
 | |
|             GraphicsPath path = new GraphicsPath();
 | |
| 
 | |
|             if (orientation == Orientation.Horizontal)
 | |
|             {
 | |
|                 Point[] pts = new Point[] {
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                     new Point(Bounds.Right, Bounds.Y),
 | |
|                     new Point(Bounds.Right, Bounds.Y + n2),
 | |
|                     new Point(Bounds.X, Bounds.Y + n1),
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                 };
 | |
| 
 | |
|                 path.AddLines(pts);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Point[] pts = new Point[] {
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                     new Point(Bounds.X, Bounds.Bottom),
 | |
|                     new Point(Bounds.Right + n1, Bounds.Bottom),
 | |
|                     new Point(Bounds.Right + n2 , Bounds.Y),
 | |
|                     new Point(Bounds.X, Bounds.Y),
 | |
|                 };
 | |
| 
 | |
|                 path.AddLines(pts);
 | |
|             }
 | |
|             
 | |
|             return (path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintRange
 | |
| 
 | |
|         #region PaintRange
 | |
| 
 | |
|         private void PaintRange(Graphics g, GraphicsPath path, int n1, int n2)
 | |
|         {
 | |
|             if (FillColor.End.IsEmpty == true || FillColor.Color1 == FillColor.Color2 ||
 | |
|                 FillColor.GradientFillType == GradientFillType.None)
 | |
|             {
 | |
|                 using (Brush br = new SolidBrush(FillColor.Color1))
 | |
|                     g.FillPath(br, path);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 switch (FillColor.GradientFillType)
 | |
|                 {
 | |
|                     case GradientFillType.Auto:
 | |
|                     case GradientFillType.StartToEnd:
 | |
|                         PaintRangeStartToEnd(g, path, n1, n2);
 | |
|                         break;
 | |
| 
 | |
|                     case GradientFillType.Angle:
 | |
|                         PaintRangeByAngle(g, path);
 | |
|                         break;
 | |
| 
 | |
|                     case GradientFillType.Center:
 | |
|                         PaintRangeByCenter(g, path, n1, n2);
 | |
|                         break;
 | |
| 
 | |
|                     case GradientFillType.HorizontalCenter:
 | |
|                         PaintRangeByHc(g, path);
 | |
|                         break;
 | |
| 
 | |
|                     case GradientFillType.VerticalCenter:
 | |
|                         PaintRangeByVc(g, path);
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (FillColor.BorderWidth > 0)
 | |
|             {
 | |
|                 using (Pen pen = new Pen(FillColor.BorderColor, FillColor.BorderWidth))
 | |
|                 {
 | |
|                     pen.Alignment = PenAlignment.Inset;
 | |
| 
 | |
|                     g.DrawPath(pen, path);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintRangeStartToEnd
 | |
| 
 | |
|         private void PaintRangeStartToEnd(
 | |
|             Graphics g, GraphicsPath path, int n1, int n2)
 | |
|         {
 | |
|             if (Scale is GaugeCircularScale)
 | |
|                 PaintCircularRangeStartToEnd(g, path, n1, n2, Scale as GaugeCircularScale);
 | |
|             else
 | |
|                 PaintLinearRangeStartToEnd(g, path, Scale as GaugeLinearScale);
 | |
|         }
 | |
| 
 | |
|         #region PaintCircularRangeStartToEnd
 | |
| 
 | |
|         private void PaintCircularRangeStartToEnd(Graphics g,
 | |
|             GraphicsPath path, int n1, int n2, GaugeCircularScale scale)
 | |
|         {
 | |
|             if (FillColor.Color2.IsEmpty == true || (FillColor.Color1 == FillColor.Color2))
 | |
|             {
 | |
|                 using (Brush br = new SolidBrush(FillColor.Color1))
 | |
|                     g.FillPath(br, path);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int n = Math.Max(n1, n2) * 3;
 | |
| 
 | |
|                 if (n > 0)
 | |
|                 {
 | |
|                     using (PathGradientBrush br =
 | |
|                         scale.CreateGradient(Bounds, StartAngle, SweepAngle, FillColor, n))
 | |
|                     {
 | |
|                         g.FillPath(br, path);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintLinearRangeStartToEnd
 | |
| 
 | |
|         private void PaintLinearRangeStartToEnd(Graphics g, GraphicsPath path, GaugeLinearScale scale)
 | |
|         {
 | |
|             if (FillColor.Color2.IsEmpty == true || (FillColor.Color1 == FillColor.Color2))
 | |
|             {
 | |
|                 using (Brush br = new SolidBrush(FillColor.Color1))
 | |
|                     g.FillPath(br, path);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int angle = (scale.Orientation == Orientation.Horizontal ? 0 : -90);
 | |
| 
 | |
|                 if (Scale.Reversed == true)
 | |
|                     angle += 180;
 | |
| 
 | |
|                 Rectangle r = Rectangle.Round(path.GetBounds());
 | |
|                 r.Inflate(1, 1);
 | |
| 
 | |
|                 using (Brush br = FillColor.GetBrush(r, angle))
 | |
|                     g.FillPath(br, path);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintRangeByAngle
 | |
| 
 | |
|         private void PaintRangeByAngle(Graphics g, GraphicsPath path)
 | |
|         {
 | |
|             Rectangle r = Rectangle.Round(path.GetBounds());
 | |
|             r.Inflate(1, 1);
 | |
| 
 | |
|             using (Brush br = FillColor.GetBrush(r))
 | |
|                 g.FillPath(br, path);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintRangeByCenter
 | |
| 
 | |
|         private void PaintRangeByCenter(Graphics g, GraphicsPath path, int n1, int n2)
 | |
|         {
 | |
|             if (Scale is GaugeCircularScale)
 | |
|                 PaintCircularRangeByCenter(g, path, n1, n2);
 | |
|             else
 | |
|                 PaintLinearRangeByCenter(g, path);
 | |
|         }
 | |
| 
 | |
|         #region PaintCircularRangeByCenter
 | |
| 
 | |
|         private void PaintCircularRangeByCenter(
 | |
|             Graphics g, GraphicsPath path, int n1, int n2)
 | |
|         {
 | |
|             using (PathGradientBrush br = new PathGradientBrush(path))
 | |
|             {
 | |
|                 br.CenterColor = FillColor.Color1;
 | |
|                 br.SurroundColors = new Color[] { FillColor.Color2 };
 | |
|                 br.CenterPoint = Scale.Center;
 | |
| 
 | |
|                 float m = (float)Math.Max(n1, n2) / _Radius;
 | |
| 
 | |
|                 Blend blnd = new Blend();
 | |
|                 blnd.Positions = new float[] { 0f, m, 1f };
 | |
|                 blnd.Factors = new float[] { 1f, 0f, 0f };
 | |
|                 br.Blend = blnd;
 | |
| 
 | |
|                 g.FillPath(br, path);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintLinearRangeByCenter
 | |
| 
 | |
|         private void PaintLinearRangeByCenter(Graphics g, GraphicsPath path)
 | |
|         {
 | |
|             using (PathGradientBrush br = new PathGradientBrush(path))
 | |
|             {
 | |
|                 br.CenterColor = FillColor.Color1;
 | |
|                 br.SurroundColors = new Color[] { FillColor.Color2 };
 | |
| 
 | |
|                 g.FillPath(br, path);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintRangeByHc
 | |
| 
 | |
|         private void PaintRangeByHc(Graphics g, GraphicsPath path)
 | |
|         {
 | |
|             Rectangle r = Rectangle.Round(path.GetBounds());
 | |
|             r.Height /= 2;
 | |
| 
 | |
|             using (LinearGradientBrush br = new
 | |
|                 LinearGradientBrush(r, FillColor.Color1, FillColor.Color2, 90))
 | |
|             {
 | |
|                 br.WrapMode = WrapMode.TileFlipXY;
 | |
| 
 | |
|                 g.FillPath(br, path);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PaintRangeByVc
 | |
| 
 | |
|         private void PaintRangeByVc(Graphics g, GraphicsPath path)
 | |
|         {
 | |
|             Rectangle r = Rectangle.Round( path.GetBounds());
 | |
|             r.Width /= 2;
 | |
| 
 | |
|             using (LinearGradientBrush br = new
 | |
|                 LinearGradientBrush(r, FillColor.Color1, FillColor.Color2, 0f))
 | |
|             {
 | |
|                 br.WrapMode = WrapMode.TileFlipXY;
 | |
| 
 | |
|                 g.FillPath(br, path);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region FindItem
 | |
| 
 | |
|         #region FindItem
 | |
| 
 | |
|         internal override GaugeItem FindItem(Point pt)
 | |
|         {
 | |
|             GraphicsPath path = GetRangePath();
 | |
| 
 | |
|             if (path != null)
 | |
|             {
 | |
|                 if (path.IsVisible(pt) == true)
 | |
|                     return (this);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetRangePath
 | |
| 
 | |
|         public GraphicsPath GetRangePath()
 | |
|         {
 | |
|             if (StripePath == null)
 | |
|             {
 | |
|                 if (Scale is GaugeCircularScale)
 | |
|                     StripePath = GetCRangePathEx(Scale as GaugeCircularScale);
 | |
|                 else
 | |
|                     StripePath = GetLRangePathEx(Scale as GaugeLinearScale);
 | |
|             }
 | |
| 
 | |
|             return (StripePath);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetCRangePathEx
 | |
| 
 | |
|         private GraphicsPath GetCRangePathEx(GaugeCircularScale scale)
 | |
|         {
 | |
|             if (SweepAngle != 0 && _Radius > 1)
 | |
|             {
 | |
|                 int radius = scale.AbsRadius;
 | |
| 
 | |
|                 int n1 = (int)(radius * _StartWidth);
 | |
|                 int n2 = (int)(radius * _EndWidth);
 | |
| 
 | |
|                 if (_Radius - n1 <= 0)
 | |
|                     n1 = _Radius - 1;
 | |
| 
 | |
|                 if (_Radius - n2 <= 0)
 | |
|                     n2 = _Radius - 1;
 | |
| 
 | |
|                 return (GetCircularRangePath(n1, n2));
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetLRangePathEx
 | |
| 
 | |
|         private GraphicsPath GetLRangePathEx(GaugeLinearScale scale)
 | |
|         {
 | |
|             if ((scale.Orientation == Orientation.Horizontal && Bounds.Width > 0) ||
 | |
|                 (scale.Orientation == Orientation.Vertical && Bounds.Height > 0))
 | |
|             {
 | |
|                 int width = scale.AbsWidth;
 | |
| 
 | |
|                 int n1 = (int)(width * _StartWidth);
 | |
|                 int n2 = (int)(width * _EndWidth);
 | |
| 
 | |
|                 if (n1 > 0 || n2 > 0)
 | |
|                     return (GetLinearRangePath(n1, n2, scale.Orientation));
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ICloneable Members
 | |
| 
 | |
|         public override object Clone()
 | |
|         {
 | |
|             GaugeRange copy = new GaugeRange();
 | |
| 
 | |
|             CopyToItem(copy);
 | |
| 
 | |
|             return (copy);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CopyToItem
 | |
| 
 | |
|         public override void CopyToItem(GaugeItem copy)
 | |
|         {
 | |
|             GaugeRange c = copy as GaugeRange;
 | |
| 
 | |
|             if (c != null)
 | |
|             {
 | |
|                 base.CopyToItem(c);
 | |
| 
 | |
|                 c.EndWidth = _EndWidth;
 | |
|                 c.Placement = _Placement;
 | |
|                 c.StartWidth = _StartWidth;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 |