819 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			819 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Drawing;
 | 
						|
using System.Windows.Forms;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
 | 
						|
namespace DevComponents.Instrumentation.Primitives
 | 
						|
{
 | 
						|
    public class BaseKnob
 | 
						|
    {
 | 
						|
        #region Private variables
 | 
						|
 | 
						|
        private bool _Reset = true;
 | 
						|
        private int _KnobIndicatorPointerBorderWidth = -1;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Protected variables
 | 
						|
 | 
						|
        protected KnobControl Knob;             // Associated KnobControl
 | 
						|
 | 
						|
        protected int MajorTicks;               // Number of major ticks
 | 
						|
        protected int MinorTicks;               // Number of minor ticks
 | 
						|
        protected Size MajorTickSize;           // Size of a major tick
 | 
						|
        protected Size MinorTickSize;           // Size of a minor tick
 | 
						|
 | 
						|
        protected int KnobWidth;                // Normalized knob width
 | 
						|
        protected int IndTickHeight;            // Ind tick height;
 | 
						|
        protected int MaxLabelWidth;            // Maximum label width
 | 
						|
        protected float ZoneIndWidth;           // Zone indicator width
 | 
						|
 | 
						|
        protected KnobColorTable DefaultColorTable;    // Default Knob color table
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Internal variables
 | 
						|
 | 
						|
        internal Rectangle TickLabelBounds;     // Tick Label bounding rectangle
 | 
						|
        internal Rectangle KnobFaceBounds;      // Knob face bounding rectangle
 | 
						|
        internal Rectangle KnobIndicatorBounds; // Knob Indicator bounding rectangle
 | 
						|
        internal Rectangle FocusRectBounds;     // Focus bounding rectangle
 | 
						|
        internal Rectangle ZoneIndicatorBounds; // Zone indicator bounding rectangle
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Constructor
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="knobControl">Associated knob control</param>
 | 
						|
        public BaseKnob(KnobControl knobControl)
 | 
						|
        {
 | 
						|
            Knob = knobControl;
 | 
						|
 | 
						|
            DefaultColorTable = new KnobColorTable();
 | 
						|
        }
 | 
						|
 | 
						|
        #region Public Properties
 | 
						|
 | 
						|
        #region MajorTickColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MajorTickColor
 | 
						|
        /// </summary>
 | 
						|
        protected Color MajorTickColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color c = Knob.KnobColor.MajorTickColor;
 | 
						|
 | 
						|
                return (c.IsEmpty == false ?
 | 
						|
                    c : DefaultColorTable.MajorTickColor);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MinorTickColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MinorTickColor
 | 
						|
        /// </summary>
 | 
						|
        protected Color MinorTickColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color c = Knob.KnobColor.MinorTickColor;
 | 
						|
 | 
						|
                return (c.IsEmpty == false ?
 | 
						|
                    c : DefaultColorTable.MinorTickColor);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region KnobIndicatorPointerBorderColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// KnobIndicatorPointerBorderColor
 | 
						|
        /// </summary>
 | 
						|
        protected Color KnobIndicatorPointerBorderColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color c = Knob.KnobColor.KnobIndicatorPointerBorderColor;
 | 
						|
 | 
						|
                return (c.IsEmpty == false ?
 | 
						|
                    c : DefaultColorTable.KnobIndicatorPointerBorderColor);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region KnobIndicatorPointerBorderWidth
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// KnobIndicatorPointerBorderWidth
 | 
						|
        /// </summary>
 | 
						|
        protected int KnobIndicatorPointerBorderWidth
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                int width = Knob.KnobColor.KnobIndicatorPointerBorderWidth;
 | 
						|
 | 
						|
                if (width <= 0)
 | 
						|
                    return (DefaultColorTable.KnobIndicatorPointerBorderWidth);
 | 
						|
 | 
						|
                return (width);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region KnobIndicatorPointerColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// KnobIndicatorPointerColor
 | 
						|
        /// </summary>
 | 
						|
        protected Color KnobIndicatorPointerColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color c = Knob.KnobColor.KnobIndicatorPointerColor;
 | 
						|
 | 
						|
                return (c.IsEmpty == false ?
 | 
						|
                    c : DefaultColorTable.KnobIndicatorPointerColor);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ZoneIndicatorColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// ZoneIndicatorBaseColor
 | 
						|
        /// </summary>
 | 
						|
        protected Color ZoneIndicatorColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color c = Knob.KnobColor.ZoneIndicatorColor;
 | 
						|
 | 
						|
                return (c.IsEmpty == false ?
 | 
						|
                    c : DefaultColorTable.ZoneIndicatorColor);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region KnobFaceColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// KnobFaceColor
 | 
						|
        /// </summary>
 | 
						|
        protected LinearGradientColorTable KnobFaceColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return (ApplyColor(Knob.KnobColor.KnobFaceColor,
 | 
						|
                                   DefaultColorTable.KnobFaceColor));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region KnobIndicatorColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// KnobIndicatorColor
 | 
						|
        /// </summary>
 | 
						|
        protected LinearGradientColorTable KnobIndicatorColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return (ApplyColor(Knob.KnobColor.KnobIndicatorColor,
 | 
						|
                                   DefaultColorTable.KnobIndicatorColor));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region LeftZoneIndicatorColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// LeftZoneIndicatorColor
 | 
						|
        /// </summary>
 | 
						|
        protected LinearGradientColorTable LeftZoneIndicatorColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return (ApplyColor(Knob.KnobColor.MinZoneIndicatorColor,
 | 
						|
                                   DefaultColorTable.MinZoneIndicatorColor));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MiddleZoneIndicatorColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MiddleZoneIndicatorColor
 | 
						|
        /// </summary>
 | 
						|
        protected LinearGradientColorTable MiddleZoneIndicatorColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return (ApplyColor(Knob.KnobColor.MidZoneIndicatorColor,
 | 
						|
                                   DefaultColorTable.MidZoneIndicatorColor));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RightZoneIndicatorColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// RightZoneIndicatorColor
 | 
						|
        /// </summary>
 | 
						|
        protected LinearGradientColorTable RightZoneIndicatorColor
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                return (ApplyColor(Knob.KnobColor.MaxZoneIndicatorColor,
 | 
						|
                                   DefaultColorTable.MaxZoneIndicatorColor));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TickLabelFormat
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MajorTickColor
 | 
						|
        /// </summary>
 | 
						|
        protected string TickLabelFormat
 | 
						|
        {
 | 
						|
            get { return (Knob.TickLabelFormat); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ApplyColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// ApplyColor
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="c"></param>
 | 
						|
        /// <param name="d"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private LinearGradientColorTable ApplyColor(
 | 
						|
            LinearGradientColorTable c, LinearGradientColorTable d)
 | 
						|
        {
 | 
						|
            if (c.IsEmpty == true)
 | 
						|
                return (d);
 | 
						|
 | 
						|
            if (c.Start.IsEmpty == false && c.End.IsEmpty == false)
 | 
						|
                return (c);
 | 
						|
 | 
						|
            return (new LinearGradientColorTable(
 | 
						|
                c.Start.IsEmpty ? d.Start : c.Start,
 | 
						|
                c.End.IsEmpty ? d.End : c.End, c.GradientAngle));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Knob configuration
 | 
						|
 | 
						|
        #region ConfigureKnob
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Main control configuration routine
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public virtual void ConfigureKnob(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            // Calculate the bounding width for the control to be the 
 | 
						|
            // minimum of either the width and the height
 | 
						|
 | 
						|
            KnobWidth = Math.Min(Knob.Width, Knob.Height);
 | 
						|
            KnobWidth = Math.Max(KnobWidth, Knob.MinKnobSize);
 | 
						|
 | 
						|
            if ((KnobWidth % 2) != 0)
 | 
						|
                KnobWidth -= 1;
 | 
						|
 | 
						|
            // Calculate the number of Major and Minor ticks and then
 | 
						|
            // measure each associated label so that we can mane sure we
 | 
						|
            // have enough room for them in the control rectangle
 | 
						|
 | 
						|
            CalculateTicksCounts();
 | 
						|
            MeasureTickLabels();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ResetKnob
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Sets the reset state to true, signifying
 | 
						|
        /// that the control needs to be reconfigured
 | 
						|
        /// before it is redrawn to the screen
 | 
						|
        /// </summary>
 | 
						|
        public void ResetKnob()
 | 
						|
        {
 | 
						|
            _Reset = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InitRender
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes the rendering process by making
 | 
						|
        /// sure that the control is reconfigured if
 | 
						|
        /// necessary
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public void InitRender(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            if (_Reset == true)
 | 
						|
            {
 | 
						|
                ConfigureKnob(e);
 | 
						|
 | 
						|
                _Reset = false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Render processing
 | 
						|
 | 
						|
        public virtual void RenderZoneIndicator(PaintEventArgs e) { }
 | 
						|
        public virtual void RenderKnobFace(PaintEventArgs e) { }
 | 
						|
        public virtual void RenderKnobIndicator(PaintEventArgs e) { }
 | 
						|
 | 
						|
        #region RenderTickMinor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the minor tick marks
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public virtual void RenderTickMinor(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            using (Pen pen = new Pen(MinorTickColor, MinorTickSize.Width))
 | 
						|
            {
 | 
						|
                for (int i = 0; i < MinorTicks; i++)
 | 
						|
                {
 | 
						|
                    // Don't draw a minor tick if it overlaps
 | 
						|
                    // with a previous major tick
 | 
						|
 | 
						|
                    if (Knob.MajorTickAmount > 0)
 | 
						|
                    {
 | 
						|
                        if ((i == 0 || i == MinorTicks - 1) ||
 | 
						|
                            ((Knob.MinorTickAmount * i) % Knob.MajorTickAmount == 0))
 | 
						|
                            continue;
 | 
						|
                    }
 | 
						|
 | 
						|
                    g.DrawLines(pen, GetMinorTickPoints(i));
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates a series of points
 | 
						|
        /// that defines the tick mark
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="tick">Tick to calculate</param>
 | 
						|
        /// <returns>An array of points that defines the tick</returns>
 | 
						|
        private Point[] GetMinorTickPoints(int tick)
 | 
						|
        {
 | 
						|
            float degree = GetTickDegree((float)Knob.MinorTickAmount, tick);
 | 
						|
            double rad = GetRadians(degree);
 | 
						|
 | 
						|
            int dx = ZoneIndicatorBounds.X + ZoneIndicatorBounds.Width / 2;
 | 
						|
            int dy = ZoneIndicatorBounds.Y + ZoneIndicatorBounds.Height / 2;
 | 
						|
            int h = (int)(ZoneIndicatorBounds.Width / 2 + ZoneIndWidth / 2 - 1);
 | 
						|
 | 
						|
            Point[] pts = new Point[2];
 | 
						|
 | 
						|
            pts[0].X = (int)(Math.Cos(rad) * h + dx);
 | 
						|
            pts[0].Y = (int)(Math.Sin(rad) * h + dy);
 | 
						|
 | 
						|
            pts[1].X = (int)(Math.Cos(rad) * (h + MinorTickSize.Height) + dx);
 | 
						|
            pts[1].Y = (int)(Math.Sin(rad) * (h + MinorTickSize.Height) + dy);
 | 
						|
 | 
						|
            return (pts);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderTickMajor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the Major Tick marks
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public virtual void RenderTickMajor(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            // Loop through each tick
 | 
						|
 | 
						|
            using (Pen pen1 = new Pen(MajorTickColor, MajorTickSize.Width))
 | 
						|
            {
 | 
						|
                for (int i = 0; i < MajorTicks; i++)
 | 
						|
                    g.DrawLines(pen1, GetMajorTickPoints(i));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates a series of points
 | 
						|
        /// that defines the tick mark
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="tick">Tick to calculate</param>
 | 
						|
        /// <returns>An array of points that defines the tick</returns>
 | 
						|
        private Point[] GetMajorTickPoints(int tick)
 | 
						|
        {
 | 
						|
            float degree = GetTickDegree((float)Knob.MajorTickAmount, tick);
 | 
						|
            double rad = GetRadians(degree);
 | 
						|
 | 
						|
            int dx = ZoneIndicatorBounds.X + ZoneIndicatorBounds.Width / 2;
 | 
						|
            int dy = ZoneIndicatorBounds.Y + ZoneIndicatorBounds.Height / 2;
 | 
						|
            int h = (int)(ZoneIndicatorBounds.Width / 2 + ZoneIndWidth / 2) - 1;
 | 
						|
 | 
						|
            Point[] pts = new Point[2];
 | 
						|
 | 
						|
            pts[0].X = (int)(Math.Cos(rad) * h + dx);
 | 
						|
            pts[0].Y = (int)(Math.Sin(rad) * h + dy);
 | 
						|
 | 
						|
            pts[1].X = (int)(Math.Cos(rad) * (h + MajorTickSize.Height) + dx);
 | 
						|
            pts[1].Y = (int)(Math.Sin(rad) * (h + MajorTickSize.Height) + dy);
 | 
						|
 | 
						|
            return (pts);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderTickLabel
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the major tick label
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public virtual void RenderTickLabel(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            // Allocate a StrFormat to use in the display
 | 
						|
            // of out tick label text
 | 
						|
 | 
						|
            using (StringFormat strFormat = new StringFormat(StringFormatFlags.NoClip))
 | 
						|
            {
 | 
						|
                strFormat.Alignment = StringAlignment.Center;
 | 
						|
 | 
						|
                float radius = TickLabelBounds.Width / 2;
 | 
						|
 | 
						|
                // Grab our tick label font - which is
 | 
						|
                // dynamically sized according to the control
 | 
						|
 | 
						|
                Font labelFont = Knob.Font;
 | 
						|
 | 
						|
                int dx = KnobWidth / 2;
 | 
						|
                int dy = (KnobWidth - (int) labelFont.SizeInPoints) / 2;
 | 
						|
 | 
						|
                // Loop through each major tick
 | 
						|
 | 
						|
                float dpt = (float) (Knob.SweepAngle * Knob.MajorTickAmount / ValueCount);
 | 
						|
 | 
						|
                for (int i = 0; i < MajorTicks; i++)
 | 
						|
                {
 | 
						|
                    if (Math.Abs(dpt * i) < 360)
 | 
						|
                    {
 | 
						|
                        float degree = dpt * i + Knob.StartAngle;
 | 
						|
 | 
						|
                        if (dpt < 0)
 | 
						|
                        {
 | 
						|
                            if (degree < Knob.StartAngle + Knob.SweepAngle)
 | 
						|
                                degree = Knob.StartAngle + Knob.SweepAngle;
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            if (degree > Knob.StartAngle + Knob.SweepAngle)
 | 
						|
                                degree = Knob.StartAngle + Knob.SweepAngle;
 | 
						|
                        }
 | 
						|
 | 
						|
                        decimal x = Math.Min(Knob.MinValue + (i * Knob.MajorTickAmount), Knob.MaxValue);
 | 
						|
                        string s = ((int)x == x) ? ((int)x).ToString(TickLabelFormat) : x.ToString(TickLabelFormat);
 | 
						|
                        Size sz = TextRenderer.MeasureText(s, labelFont);
 | 
						|
 | 
						|
                        double currentAngle = GetRadians(degree);
 | 
						|
 | 
						|
                        Point pt = new Point((int) (dx - sz.Width / 2 + radius * (float) Math.Cos(currentAngle)),
 | 
						|
                                             (int) (dy + radius * (float) Math.Sin(currentAngle)));
 | 
						|
 | 
						|
                        Rectangle r = new Rectangle(pt, new Size(1000, 1000));
 | 
						|
 | 
						|
                        TextRenderer.DrawText(g, s, labelFont, r,
 | 
						|
                                              Knob.ForeColor, TextFormatFlags.Left);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderFocusRect
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the base focus rect
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public virtual void RenderFocusRect(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            using (Pen pen = new Pen(Color.DarkGray))
 | 
						|
            {
 | 
						|
                pen.DashStyle = DashStyle.Dash;
 | 
						|
 | 
						|
                g.DrawEllipse(pen, FocusRectBounds);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetValueFromPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines the control Value from
 | 
						|
        /// a specified Point on the control
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point on the control</param>
 | 
						|
        /// <returns>Value</returns>
 | 
						|
        public decimal GetValueFromPoint(Point pt)
 | 
						|
        {
 | 
						|
            // Calculate the relative X and Y
 | 
						|
            // coordinate pair for the given point
 | 
						|
 | 
						|
            int radius = ZoneIndicatorBounds.Width / 2;
 | 
						|
 | 
						|
            Point cpt = new Point(ZoneIndicatorBounds.X + radius, ZoneIndicatorBounds.Y + radius);
 | 
						|
 | 
						|
            int dx = pt.X - cpt.X;
 | 
						|
            int dy = pt.Y - cpt.Y;
 | 
						|
 | 
						|
            // Determine the radians for the given coord pair
 | 
						|
            // based upon which quadrant it is located in
 | 
						|
 | 
						|
            double radians;
 | 
						|
 | 
						|
            if (dx >= 0)
 | 
						|
            {
 | 
						|
                if (dy >= 0)
 | 
						|
                    radians = Math.Atan((double)dy / dx);
 | 
						|
                else
 | 
						|
                    radians = -Math.Atan((double)dx / dy) + Math.PI * 1.5;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (dy >= 0)
 | 
						|
                    radians = -Math.Atan((double)dx / dy) + Math.PI / 2;
 | 
						|
                else
 | 
						|
                    radians = Math.Atan((double)dy / dx) + Math.PI;
 | 
						|
            }
 | 
						|
 | 
						|
            // Convert our calculated Radians to Degrees
 | 
						|
            // and then 'normalize' our values to the
 | 
						|
            // current StartAngle
 | 
						|
 | 
						|
            int degrees = (int)GetDegrees(radians);
 | 
						|
 | 
						|
            decimal normal = degrees - Knob.StartAngle;
 | 
						|
 | 
						|
            if (Knob.SweepAngle < 0)
 | 
						|
            {
 | 
						|
                normal = 360 - normal;
 | 
						|
                normal = normal % 360;
 | 
						|
            }
 | 
						|
 | 
						|
            if (normal < 0)
 | 
						|
                normal += 360;
 | 
						|
 | 
						|
            // If our normalized angle is within the
 | 
						|
            // SweepAngle, then return the associated
 | 
						|
            // range value
 | 
						|
 | 
						|
            int n = Math.Abs(Knob.SweepAngle);
 | 
						|
 | 
						|
            if (normal >= 0 && normal <= n)
 | 
						|
                return (normal * ValueCount / n + Knob.MinValue);
 | 
						|
 | 
						|
            // The normalized angle is outside the SweepAngle, so
 | 
						|
            // return either the MinValue or MaxValue (based upon
 | 
						|
            // which one is closer)
 | 
						|
 | 
						|
            return ((normal >= n + (360 - n) / 2) ? Knob.MinValue : Knob.MaxValue);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalculateTicksCounts
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculate how many major and
 | 
						|
        /// minor ticks are presented on the control
 | 
						|
        /// </summary>
 | 
						|
        private void CalculateTicksCounts()
 | 
						|
        {
 | 
						|
            decimal count = ValueCount;
 | 
						|
 | 
						|
            // Calculate the number of major ticks
 | 
						|
 | 
						|
            MajorTicks = 0;
 | 
						|
 | 
						|
            if (Knob.MajorTickAmount > 0)
 | 
						|
            {
 | 
						|
                MajorTicks = (int)(count / Knob.MajorTickAmount);
 | 
						|
 | 
						|
                if (MajorTicks * Knob.MajorTickAmount < count)
 | 
						|
                    MajorTicks++;
 | 
						|
 | 
						|
                MajorTicks++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Calculate the number of minor ticks
 | 
						|
 | 
						|
            MinorTicks = 0;
 | 
						|
 | 
						|
            if (Knob.MinorTickAmount > 0)
 | 
						|
            {
 | 
						|
                MinorTicks = (int)(count / Knob.MinorTickAmount);
 | 
						|
 | 
						|
                if (MinorTicks * Knob.MinorTickAmount < count)
 | 
						|
                    MinorTicks++;
 | 
						|
 | 
						|
                MinorTicks++;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MeasureTickLabels
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Measure the width of each text label in order to
 | 
						|
        /// make sure we have room for it in the control
 | 
						|
        /// </summary>
 | 
						|
        private void MeasureTickLabels()
 | 
						|
        {
 | 
						|
            MaxLabelWidth = 0;
 | 
						|
 | 
						|
            if (Knob.ShowTickLabels == true)
 | 
						|
            {
 | 
						|
                Font labelFont = Knob.Font;
 | 
						|
 | 
						|
                for (int i = 0; i < MajorTicks; i++)
 | 
						|
                {
 | 
						|
                    // Save the text and width for later use
 | 
						|
 | 
						|
                    decimal n =  Knob.MinValue + (i * Knob.MajorTickAmount);
 | 
						|
 | 
						|
                    string s = n.ToString(TickLabelFormat);
 | 
						|
 | 
						|
                    int w = TextRenderer.MeasureText(s, labelFont).Width + 2;
 | 
						|
 | 
						|
                    // Keep track of the maximum width
 | 
						|
 | 
						|
                    if (w > MaxLabelWidth)
 | 
						|
                        MaxLabelWidth = w;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetTickDegree
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the arc degree associated with
 | 
						|
        /// the given gauge tick
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="tickAmount">Major or minor tick amount</param>
 | 
						|
        /// <param name="tick">The tick to convert</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        protected float GetTickDegree(float tickAmount, int tick)
 | 
						|
        {
 | 
						|
            float dpt = (Knob.SweepAngle * tickAmount) / (float)ValueCount;
 | 
						|
            float degree = dpt * tick + Knob.StartAngle;
 | 
						|
 | 
						|
            if (dpt < 0)
 | 
						|
            {
 | 
						|
                if (degree < Knob.StartAngle + Knob.SweepAngle)
 | 
						|
                    degree = Knob.StartAngle + Knob.SweepAngle;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (degree > Knob.StartAngle + Knob.SweepAngle)
 | 
						|
                    degree = Knob.StartAngle + Knob.SweepAngle;
 | 
						|
            }
 | 
						|
 | 
						|
            return (degree);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetRadians
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Converts Degrees to Radians
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="theta">Degrees</param>
 | 
						|
        /// <returns>Radians</returns>
 | 
						|
        public double GetRadians(float theta)
 | 
						|
        {
 | 
						|
            return (theta * Math.PI / 180);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDegrees
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Converts Radians to Degrees
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="radians">Radians</param>
 | 
						|
        /// <returns>Degrees</returns>
 | 
						|
        public double GetDegrees(double radians)
 | 
						|
        {
 | 
						|
            return (radians * 180 / Math.PI);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ValueCount
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the value range, expressed as a count
 | 
						|
        /// </summary>
 | 
						|
        internal decimal ValueCount
 | 
						|
        {
 | 
						|
            get { return (Knob.MaxValue - Knob.MinValue); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointInControl
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if a given Point is within
 | 
						|
        /// the bounds of the control
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public virtual bool PointInControl(Point pt)
 | 
						|
        {
 | 
						|
            // Allow a little leeway around the control
 | 
						|
 | 
						|
            Rectangle r = new Rectangle(ZoneIndicatorBounds.Location, ZoneIndicatorBounds.Size);
 | 
						|
 | 
						|
            r.Inflate(40, 40);
 | 
						|
 | 
						|
            int radius = r.Width / 2;
 | 
						|
 | 
						|
            Point cpt = new Point(r.X + radius, r.Y + radius);
 | 
						|
 | 
						|
            return (PointInCircle(pt, cpt, radius));      
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointInCircle
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if a given point is within a given circle
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point in question</param>
 | 
						|
        /// <param name="cpt">Center Point</param>
 | 
						|
        /// <param name="radius">Circle radius</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public bool PointInCircle(Point pt, Point cpt, int radius)
 | 
						|
        {
 | 
						|
            int a = pt.X - cpt.X;
 | 
						|
            int b = pt.Y - cpt.Y;
 | 
						|
 | 
						|
            int c = (int)Math.Sqrt(a * a + b * b);
 | 
						|
 | 
						|
            return (c < radius);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
}
 |