777 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			777 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Drawing;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
using System.Windows.Forms;
 | 
						|
 | 
						|
namespace DevComponents.Instrumentation.Primitives
 | 
						|
{
 | 
						|
    public class KnobStyle3 : BaseKnob
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Constructor
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="knobControl">Associated knob control</param>
 | 
						|
        public KnobStyle3(KnobControl knobControl)
 | 
						|
            : base(knobControl)
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        #region Knob Configuration
 | 
						|
 | 
						|
        #region ConfigureKnob
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Configures the given knob control
 | 
						|
        /// by establishing various default object parameters
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public override void ConfigureKnob(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            base.ConfigureKnob(e);
 | 
						|
 | 
						|
            // Calculate default sizes and bounding object rectangles
 | 
						|
 | 
						|
            ZoneIndWidth = KnobWidth * 0.034f;
 | 
						|
 | 
						|
            MajorTickSize = new Size((int)(KnobWidth * 0.018), (int)(KnobWidth * 0.05));
 | 
						|
            MinorTickSize = new Size(MajorTickSize.Width / 2, MajorTickSize.Height);
 | 
						|
 | 
						|
            IndTickHeight = MajorTickSize.Height / 3;
 | 
						|
 | 
						|
            CalculateBoundingRects();
 | 
						|
 | 
						|
            // Fill in the default knob colors
 | 
						|
 | 
						|
            DefaultColorTable.MajorTickColor = Color.Black;
 | 
						|
            DefaultColorTable.MinorTickColor = Color.Black;
 | 
						|
            DefaultColorTable.ZoneIndicatorColor = Color.Black;
 | 
						|
            DefaultColorTable.KnobIndicatorPointerColor = Color.Black;
 | 
						|
            DefaultColorTable.KnobIndicatorPointerBorderColor = Color.Gray;
 | 
						|
 | 
						|
            DefaultColorTable.KnobFaceColor = new LinearGradientColorTable(Color.Goldenrod, Color.Goldenrod, 40);
 | 
						|
            DefaultColorTable.KnobIndicatorColor = new LinearGradientColorTable(Color.White, Color.LightGray);
 | 
						|
            DefaultColorTable.MinZoneIndicatorColor = new LinearGradientColorTable(Color.White, Color.Green);
 | 
						|
            DefaultColorTable.MaxZoneIndicatorColor = new LinearGradientColorTable(Color.Yellow, Color.Red);
 | 
						|
            DefaultColorTable.MidZoneIndicatorColor = new LinearGradientColorTable(Color.CornflowerBlue);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalculateBoundingRects
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates several default control
 | 
						|
        /// // bounding rectangles
 | 
						|
        /// </summary>
 | 
						|
        private void CalculateBoundingRects()
 | 
						|
        {
 | 
						|
            // Calculate the bounding Zone indicator rectangle and width
 | 
						|
 | 
						|
            int delta = MaxLabelWidth + MajorTickSize.Height;
 | 
						|
 | 
						|
            ZoneIndicatorBounds = new Rectangle(delta, delta,
 | 
						|
                KnobWidth - (delta * 2), KnobWidth - (delta * 2));
 | 
						|
 | 
						|
            // Calculate the KnobFace and inset face rectangles
 | 
						|
 | 
						|
            delta = (int)(ZoneIndicatorBounds.Width * .025f + ZoneIndWidth);
 | 
						|
 | 
						|
            KnobFaceBounds = ZoneIndicatorBounds;
 | 
						|
            KnobFaceBounds.Inflate(-delta, -delta);
 | 
						|
 | 
						|
            // Calculate the KnobIndicator bounding rectangle
 | 
						|
 | 
						|
            delta = (int)(ZoneIndicatorBounds.Width * .14f);
 | 
						|
 | 
						|
            KnobIndicatorBounds = ZoneIndicatorBounds;
 | 
						|
            KnobIndicatorBounds.Inflate(-delta, -delta);
 | 
						|
 | 
						|
            // Calculate the TickLabel bounding rect
 | 
						|
 | 
						|
            delta = (int)((MaxLabelWidth + IndTickHeight) * .60f);
 | 
						|
 | 
						|
            TickLabelBounds = new Rectangle(ZoneIndicatorBounds.Location, ZoneIndicatorBounds.Size);
 | 
						|
            TickLabelBounds.Inflate(delta, delta);
 | 
						|
 | 
						|
            // Calculate the focus rectangle
 | 
						|
 | 
						|
            FocusRectBounds = KnobIndicatorBounds;
 | 
						|
 | 
						|
            delta = (int)(KnobIndicatorBounds.Width * .025);
 | 
						|
            FocusRectBounds.Inflate(-delta, -delta);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Part rendering code
 | 
						|
 | 
						|
        #region RenderZoneIndicator
 | 
						|
 | 
						|
        #region RenderZoneIndicator
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the zone indicator
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public override void RenderZoneIndicator(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            if (ZoneIndicatorBounds.Width > 10 && ZoneIndicatorBounds.Height > 10)
 | 
						|
            {
 | 
						|
                Graphics g = e.Graphics;
 | 
						|
 | 
						|
                int leftEndAngle = Knob.StartAngle;
 | 
						|
                int rightStartAngle = Knob.StartAngle;
 | 
						|
 | 
						|
                // Render the left zone - if present
 | 
						|
 | 
						|
                if (Knob.MinZonePercentage > 0)
 | 
						|
                {
 | 
						|
                    float pct = Knob.MinZonePercentage / 100f;
 | 
						|
 | 
						|
                    RenderArc(g, Knob.StartAngle,
 | 
						|
                              Knob.SweepAngle * pct, LeftZoneIndicatorColor);
 | 
						|
 | 
						|
                    leftEndAngle = (int)(Knob.StartAngle + Knob.SweepAngle * pct);
 | 
						|
                }
 | 
						|
                
 | 
						|
                // Render the right-hand zone - if present
 | 
						|
 | 
						|
                if (Knob.MaxZonePercentage > 0)
 | 
						|
                {
 | 
						|
                    float pct = Knob.MaxZonePercentage / 100f;
 | 
						|
 | 
						|
                    RenderArc(g, Knob.StartAngle + Knob.SweepAngle * (1 - pct),
 | 
						|
                              Knob.SweepAngle * pct, RightZoneIndicatorColor);
 | 
						|
 | 
						|
                    rightStartAngle = (int)(Knob.StartAngle + Knob.SweepAngle * (1 - pct));
 | 
						|
                }
 | 
						|
 | 
						|
                // Render the middle zone
 | 
						|
 | 
						|
                if (rightStartAngle != leftEndAngle)
 | 
						|
                {
 | 
						|
                    RenderArc(g, leftEndAngle,
 | 
						|
                        rightStartAngle - leftEndAngle, MiddleZoneIndicatorColor);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderArc
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders a gradient indicator arc by dividing
 | 
						|
        /// the arc into sub-arcs, enabling us to utilize normal
 | 
						|
        /// rectangle gradient support
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="a1">Starting angle</param>
 | 
						|
        /// <param name="s1">Sweep angle</param>
 | 
						|
        /// <param name="ct"></param>
 | 
						|
        private void RenderArc(Graphics g, float a1, float s1, LinearGradientColorTable ct)
 | 
						|
        {
 | 
						|
            float n1 = Math.Abs(s1);
 | 
						|
 | 
						|
            Color c1 = ct.Start;
 | 
						|
            Color c2 = ct.End.IsEmpty == false ? ct.End : ct.Start;
 | 
						|
 | 
						|
            // Calculate our rect and inflate to
 | 
						|
            // make room for the indicator arc
 | 
						|
 | 
						|
            Rectangle rect = new
 | 
						|
                Rectangle(ZoneIndicatorBounds.Location, ZoneIndicatorBounds.Size);
 | 
						|
 | 
						|
            int dw = (int)(ZoneIndWidth / 2);
 | 
						|
 | 
						|
            rect.Inflate(-dw, -dw);
 | 
						|
 | 
						|
            // Calculate the RGB color deltas
 | 
						|
 | 
						|
            float dr = (c2.R - c1.R) / n1;
 | 
						|
            float dg = (c2.G - c1.G) / n1;
 | 
						|
            float db = (c2.B - c1.B) / n1;
 | 
						|
 | 
						|
            // Set our initial starting color and range
 | 
						|
 | 
						|
            Color c3 = Color.FromArgb(c1.ToArgb());
 | 
						|
 | 
						|
            float s2 = s1;
 | 
						|
            float a2 = a1;
 | 
						|
 | 
						|
            int pa = (s1 > 0) ? 100 : -100;
 | 
						|
 | 
						|
            // Loop through the arc, processing sub-arcs less
 | 
						|
            // than 180 degrees so that we can use GDI+ built-in
 | 
						|
            // gradient rectangle support
 | 
						|
 | 
						|
            while (s2 != 0)
 | 
						|
            {
 | 
						|
                // Limit our sweep angle pass to 90 degrees
 | 
						|
 | 
						|
                float sw = (s2 > 0) ? 
 | 
						|
                    Math.Min(s2, 90) : Math.Max(s2, -90);
 | 
						|
 | 
						|
                // Calculate our sub-sweep angle points.  This
 | 
						|
                // enables us to create an associated bounding
 | 
						|
                // rectangle for the sub-sweep arc
 | 
						|
 | 
						|
                Point pt1 = CalcCoord(a2);
 | 
						|
                Point pt2 = CalcCoord(a2 + sw);
 | 
						|
 | 
						|
                Rectangle r = new Rectangle();
 | 
						|
 | 
						|
                r.Location = new Point(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y));
 | 
						|
                r.Size = new Size(Math.Abs(pt1.X - pt2.X), Math.Abs(pt1.Y - pt2.Y));
 | 
						|
 | 
						|
                if (r.Width == 0)
 | 
						|
                    r.Width = 1;
 | 
						|
 | 
						|
                if (r.Height == 0)
 | 
						|
                    r.Height = 1;
 | 
						|
 | 
						|
                // Calculate the terminal color for the
 | 
						|
                // sub-sweep arc
 | 
						|
 | 
						|
                float n = Math.Abs(sw);
 | 
						|
 | 
						|
                int red = (int)(c3.R + n * dr);
 | 
						|
                red = Math.Max(Math.Min(red, 255), 0);
 | 
						|
 | 
						|
                int green = (int)(c3.G + n * dg);
 | 
						|
                green = Math.Max(Math.Min(green, 255), 0);
 | 
						|
 | 
						|
                int blue = (int)(c3.B + n * db);
 | 
						|
                blue = Math.Max(Math.Min(blue, 255), 0);
 | 
						|
                
 | 
						|
                Color c4 = Color.FromArgb(red, green, blue);
 | 
						|
 | 
						|
                // Tally up this sub-sweep
 | 
						|
 | 
						|
                s2 -= sw;
 | 
						|
 | 
						|
                // Render the sub-arc with an appropriately
 | 
						|
                // orientated gradient brush, and draw the arc
 | 
						|
 | 
						|
                using (LinearGradientBrush lbr = new LinearGradientBrush(r, c3, c4, a2 + pa))
 | 
						|
                {
 | 
						|
                    using (Pen pen = new Pen(lbr, (int)ZoneIndWidth))
 | 
						|
                        g.DrawArc(pen, rect, a2, sw);
 | 
						|
                }
 | 
						|
 | 
						|
                // Bump up our starting angle to reflect the
 | 
						|
                // processing of this sub-arc
 | 
						|
 | 
						|
                a2 += sw;
 | 
						|
 | 
						|
                // Set the next starting color to the
 | 
						|
                // ending color for this arc
 | 
						|
 | 
						|
                c3 = c4;
 | 
						|
            }
 | 
						|
 | 
						|
            // Render the bounding indicator arcs
 | 
						|
 | 
						|
            using (GraphicsPath p1 = new GraphicsPath())
 | 
						|
            {
 | 
						|
                rect.Inflate(-dw, -dw);
 | 
						|
 | 
						|
                p1.AddArc(ZoneIndicatorBounds, a1, s1);
 | 
						|
                p1.AddArc(rect, a1 + s1, -s1);
 | 
						|
 | 
						|
                // Let Windows close the arcs, and then
 | 
						|
                // render them
 | 
						|
 | 
						|
                p1.CloseFigure();
 | 
						|
 | 
						|
                using (Pen pen = new Pen(ZoneIndicatorColor, MinorTickSize.Width))
 | 
						|
                    g.DrawPath(pen, p1);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalcCoord
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates the arc coordinates for 
 | 
						|
        /// a given angle
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="a2">Angle</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Point CalcCoord(float a2)
 | 
						|
        {
 | 
						|
            Point pt = new Point();
 | 
						|
 | 
						|
            // Normalize the angle and calculate some
 | 
						|
            // working vars
 | 
						|
 | 
						|
            if (a2 < 0)
 | 
						|
                a2 += 360;
 | 
						|
 | 
						|
            a2 = a2 % 360;
 | 
						|
 | 
						|
            int delta = ZoneIndicatorBounds.X + ZoneIndicatorBounds.Width / 2;
 | 
						|
            int radius = ZoneIndicatorBounds.Width / 2;
 | 
						|
            int d = (int)(ZoneIndWidth / 2);
 | 
						|
 | 
						|
            // Determine the angle quadrant, and then calculate
 | 
						|
            // the intersecting coordinate accordingly
 | 
						|
 | 
						|
            if (a2 < 90)
 | 
						|
            {
 | 
						|
                pt.X = (int)(Math.Cos(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
                pt.Y = (int)(Math.Sin(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
            }
 | 
						|
            else if (a2 < 180)
 | 
						|
            {
 | 
						|
                pt.X = -(int)(Math.Sin(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
                pt.Y = (int)(Math.Cos(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
            }
 | 
						|
            else if (a2 < 270)
 | 
						|
            {
 | 
						|
                pt.X = -(int)(Math.Cos(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
                pt.Y = -(int)(Math.Sin(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                pt.X = (int)(Math.Sin(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
                pt.Y = -(int)(Math.Cos(GetRadians(a2 % 90)) * (radius + d));
 | 
						|
            }
 | 
						|
 | 
						|
            // Adjust the point to the intersecting arc
 | 
						|
 | 
						|
            pt.X += delta;
 | 
						|
            pt.Y += delta;
 | 
						|
 | 
						|
            return (pt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderTickMinor
 | 
						|
 | 
						|
        #region RenderTickMinor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the minor tick marks
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public override 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));
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetMinorTickPoints
 | 
						|
 | 
						|
        /// <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 = ZoneIndicatorBounds.Width / 2 - (int)ZoneIndWidth;
 | 
						|
 | 
						|
            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
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderTickMajor
 | 
						|
 | 
						|
        #region RenderTickMajor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the Major Tick marks
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public override 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));
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetMajorTickPoints
 | 
						|
 | 
						|
        /// <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 = ZoneIndicatorBounds.Width / 2 - (int)ZoneIndWidth;
 | 
						|
 | 
						|
            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 + 1) + dx);
 | 
						|
            pts[1].Y = (int)(Math.Sin(rad) * (h + MajorTickSize.Height + 1) + dy);
 | 
						|
 | 
						|
            return (pts);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderKnobFace
 | 
						|
 | 
						|
        #region RenderKnobFace
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the knob face
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public override void RenderKnobFace(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            if (KnobFaceBounds.Width > 10 && KnobFaceBounds.Height > 10)
 | 
						|
            {
 | 
						|
                Graphics g = e.Graphics;
 | 
						|
 | 
						|
                // Allocate a path to accumulate the knob
 | 
						|
                // drawing pieces
 | 
						|
 | 
						|
                using (GraphicsPath path = new GraphicsPath())
 | 
						|
                {
 | 
						|
                    // Render the face shadow
 | 
						|
 | 
						|
                    RenderInset(g, path, Pens.Gray, MinorTickSize.Width);
 | 
						|
 | 
						|
                    using (SolidBrush br =
 | 
						|
                        new SolidBrush(Color.FromArgb(160, Color.Gray)))
 | 
						|
                    {
 | 
						|
                        g.FillPath(br, path);
 | 
						|
                    }
 | 
						|
 | 
						|
                    path.Reset();
 | 
						|
 | 
						|
                    // Render the face front
 | 
						|
 | 
						|
                    using (Pen pen = new Pen(Color.White, MinorTickSize.Width))
 | 
						|
                        RenderInset(g, path, pen, 0);
 | 
						|
 | 
						|
                    using (Brush br = KnobFaceColor.GetBrush(KnobFaceBounds))
 | 
						|
                        g.FillPath(br, path);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderInset
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the face, including the arc insets
 | 
						|
        /// as well as the connecting segments
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="path">Path to render to</param>
 | 
						|
        /// <param name="pen">Outlining pen</param>
 | 
						|
        /// <param name="offset">Delta offset - used for shadowing</param>
 | 
						|
        private void RenderInset(Graphics g, GraphicsPath path, Pen pen, int offset)
 | 
						|
        {
 | 
						|
            // Calculate the bounding rectangle
 | 
						|
            // for the inset segments
 | 
						|
 | 
						|
            Rectangle rInset = KnobFaceBounds;
 | 
						|
 | 
						|
            int w = (int)(ZoneIndWidth);
 | 
						|
            rInset.Inflate(-w, -w);
 | 
						|
 | 
						|
            // Calculate the bounding rectangle
 | 
						|
            // for the inset arcs
 | 
						|
 | 
						|
            int radius = (int)(KnobWidth * .055f);
 | 
						|
 | 
						|
            Rectangle r = new Rectangle(0, 0, radius, radius);
 | 
						|
 | 
						|
            // Loop through each arc point and
 | 
						|
            // render the individual arc insets
 | 
						|
 | 
						|
            for (int i = 0; i < 12; i++)
 | 
						|
            {
 | 
						|
                // Calculate the inset location and
 | 
						|
                // render the inset arc
 | 
						|
 | 
						|
                r.Location = GetArcPoint(rInset, i * 30f, (int)(offset - radius * .5f));
 | 
						|
 | 
						|
                path.AddArc(r, (i * 30) - 90, -180);
 | 
						|
            }
 | 
						|
 | 
						|
            // Let Windows connect the arcs, and
 | 
						|
            // then draw the completed path
 | 
						|
 | 
						|
            path.CloseFigure();
 | 
						|
 | 
						|
            g.DrawPath(pen, path);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetArcPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates the arc point at the given
 | 
						|
        /// degree and offset
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="rInset">Inset bounding rectangle</param>
 | 
						|
        /// <param name="degree">Degree to position arc inset</param>
 | 
						|
        /// <param name="offset">Offset (used for shading)</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Point GetArcPoint(Rectangle rInset, float degree, int offset)
 | 
						|
        {
 | 
						|
            // Calculate the default position
 | 
						|
 | 
						|
            double rad = GetRadians(degree);
 | 
						|
 | 
						|
            int dx = rInset.X + rInset.Width / 2;
 | 
						|
            int dy = rInset.Y + rInset.Height / 2;
 | 
						|
            int h = rInset.Width / 2 + (int)ZoneIndWidth;
 | 
						|
 | 
						|
            Point pt = new Point();
 | 
						|
 | 
						|
            pt.X = (int)(Math.Cos(rad) * h + dx);
 | 
						|
            pt.Y = (int)(Math.Sin(rad) * h + dy);
 | 
						|
 | 
						|
            // Offset the point if so requested
 | 
						|
            // (face shadow support)
 | 
						|
 | 
						|
            pt.Offset(offset, offset);
 | 
						|
 | 
						|
            return (pt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderKnobIndicator
 | 
						|
 | 
						|
        #region RenderKnobIndicator
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the knob face
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        public override void RenderKnobIndicator(PaintEventArgs e)
 | 
						|
        {
 | 
						|
            if (KnobIndicatorBounds.Width > 10 && KnobIndicatorBounds.Height > 10)
 | 
						|
            {
 | 
						|
                Graphics g = e.Graphics;
 | 
						|
 | 
						|
                // Allocate a graphics path and calculate
 | 
						|
                // its bounding rectangle
 | 
						|
 | 
						|
                using (GraphicsPath path = new GraphicsPath())
 | 
						|
                {
 | 
						|
                    Rectangle r = new
 | 
						|
                        Rectangle(KnobIndicatorBounds.Location, KnobIndicatorBounds.Size);
 | 
						|
 | 
						|
                    int delta = (int) (KnobWidth*.020f);
 | 
						|
 | 
						|
                    // Render the knob, it's shadow, and
 | 
						|
                    // the hilight crescent
 | 
						|
 | 
						|
                    r.Offset(delta, delta);
 | 
						|
                    RenderIndFace(g, path, r);
 | 
						|
 | 
						|
                    r.Offset(-delta*2, -delta*2);
 | 
						|
                    RenderIndCrescent(g, path, r);
 | 
						|
 | 
						|
                    // Render the indicator arrow
 | 
						|
 | 
						|
                    path.AddLines(GetIndicatorPoints());
 | 
						|
                    path.CloseFigure();
 | 
						|
 | 
						|
                    // Fill the closed arrow
 | 
						|
 | 
						|
                    using (SolidBrush br = new SolidBrush(KnobIndicatorPointerColor))
 | 
						|
                    {
 | 
						|
                        g.FillPath(br, path);
 | 
						|
 | 
						|
                        // Outline the arrow
 | 
						|
 | 
						|
                        if (KnobIndicatorPointerBorderWidth > 0 &&
 | 
						|
                            KnobIndicatorPointerColor.Equals(KnobIndicatorPointerBorderColor) == false)
 | 
						|
                        {
 | 
						|
                            using (Pen pen = new Pen(KnobIndicatorPointerBorderColor, KnobIndicatorPointerBorderWidth))
 | 
						|
                                g.DrawPath(pen, path);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderIndCrescent
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the hilight crescent
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="path">Accumulating GraphicsPath</param>
 | 
						|
        /// <param name="r">Bounding rectangle</param>
 | 
						|
        private void RenderIndCrescent(Graphics g, GraphicsPath path, Rectangle r)
 | 
						|
        {
 | 
						|
            // Add the bottom crescent arc
 | 
						|
 | 
						|
            path.AddArc(r, 8, 78);
 | 
						|
 | 
						|
            // Calculate the intersecting upper arc
 | 
						|
            // and add it to the path
 | 
						|
 | 
						|
            int cradius = r.Width / 2;
 | 
						|
            int nradius = (int)(cradius * 1.5f);
 | 
						|
 | 
						|
            int dr = nradius - cradius;
 | 
						|
            int dz = (int)(dr * Math.Cos(45) * 1.6f);
 | 
						|
 | 
						|
            Rectangle r2 = new Rectangle(r.X - dr - dz, r.Y - dr - dz, nradius * 2, nradius * 2);
 | 
						|
 | 
						|
            path.AddArc(r2, 70, -50);
 | 
						|
 | 
						|
            Color c = Color.FromArgb(170, KnobIndicatorColor.Start);
 | 
						|
 | 
						|
            using (LinearGradientBrush lbr =
 | 
						|
                new LinearGradientBrush(KnobIndicatorBounds, Color.White, c, 45f))
 | 
						|
            {
 | 
						|
                g.FillPath(lbr, path);
 | 
						|
            }
 | 
						|
 | 
						|
            path.Reset();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RenderIndFace
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Renders the face of the knob indicator
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="path">Accumulating GraphicsPath</param>
 | 
						|
        /// <param name="r">Bounding rectangle</param>
 | 
						|
        private void RenderIndFace(Graphics g, GraphicsPath path, Rectangle r)
 | 
						|
        {
 | 
						|
            // Render the knob shadow
 | 
						|
 | 
						|
            Color c3 = Color.FromArgb(100, ControlPaint.Dark(KnobIndicatorColor.End));
 | 
						|
 | 
						|
            using (SolidBrush br = new SolidBrush(c3))
 | 
						|
                g.FillEllipse(br, r);
 | 
						|
 | 
						|
            // Render the knob
 | 
						|
 | 
						|
            using (Brush br = KnobIndicatorColor.GetBrush(KnobIndicatorBounds))
 | 
						|
                g.FillEllipse(br, KnobIndicatorBounds);
 | 
						|
 | 
						|
            path.Reset();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetIndicatorPoints
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates a series of points that
 | 
						|
        /// defines the indicator arrow
 | 
						|
        /// </summary>
 | 
						|
        /// <returns>An array of defining points</returns>
 | 
						|
        private Point[] GetIndicatorPoints()
 | 
						|
        {
 | 
						|
            float degrees = (float)(Knob.SweepAngle / ValueCount) *
 | 
						|
                (float)(Knob.Value - Knob.MinValue) + Knob.StartAngle;
 | 
						|
 | 
						|
            int arrowHeight = (int)(KnobWidth * .025f);
 | 
						|
 | 
						|
            double rad0 = GetRadians(degrees - 19);
 | 
						|
            double rad1 = GetRadians(degrees);
 | 
						|
            double rad2 = GetRadians(degrees + 19);
 | 
						|
 | 
						|
            int dx = KnobIndicatorBounds.X + KnobIndicatorBounds.Width / 2 + 1;
 | 
						|
            int dy = KnobIndicatorBounds.Y + KnobIndicatorBounds.Height / 2 + 1;
 | 
						|
            int h = KnobIndicatorBounds.Width / 2;
 | 
						|
 | 
						|
            Point[] pts = new Point[3];
 | 
						|
 | 
						|
            pts[0].X = (int)(Math.Cos(rad0) * h + dx);
 | 
						|
            pts[0].Y = (int)(Math.Sin(rad0) * h + dy);
 | 
						|
 | 
						|
            pts[1].X = (int)(Math.Cos(rad1) * (h + arrowHeight) + dx);
 | 
						|
            pts[1].Y = (int)(Math.Sin(rad1) * (h + arrowHeight) + dy);
 | 
						|
 | 
						|
            pts[2].X = (int)(Math.Cos(rad2) * h + dx);
 | 
						|
            pts[2].Y = (int)(Math.Sin(rad2) * h + dy);
 | 
						|
 | 
						|
            return (pts);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
    }
 | 
						|
}
 |