DotNet 4.8.1 build of DotNetBar
This commit is contained in:
@@ -0,0 +1,818 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,599 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using DevComponents.Instrumentation.Primitives;
|
||||
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
[TypeConverter(typeof(KnobColorTableConvertor))]
|
||||
public class KnobColorTable
|
||||
{
|
||||
public static readonly KnobColorTable Empty = new KnobColorTable();
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when ColorTable has changed
|
||||
/// </summary>
|
||||
[Description("Event raised when ColorTable has changed.")]
|
||||
public event EventHandler<EventArgs> ColorTableChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private variables
|
||||
|
||||
private Color _MajorTickColor = Color.Empty;
|
||||
private Color _MinorTickColor = Color.Empty;
|
||||
private Color _ZoneIndicatorColor = Color.Empty;
|
||||
private Color _KnobIndicatorPointerColor = Color.Empty;
|
||||
private Color _KnobIndicatorPointerBorderColor = Color.Empty;
|
||||
|
||||
private LinearGradientColorTable _KnobFaceColor = new LinearGradientColorTable();
|
||||
private LinearGradientColorTable _KnobIndicatorColor = new LinearGradientColorTable();
|
||||
private LinearGradientColorTable _MinZoneIndicatorColor = new LinearGradientColorTable();
|
||||
private LinearGradientColorTable _MaxZoneIndicatorColor = new LinearGradientColorTable();
|
||||
private LinearGradientColorTable _MidZoneIndicatorColor = new LinearGradientColorTable();
|
||||
|
||||
private int _KnobIndicatorPointerBorderWidth;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public KnobColorTable()
|
||||
{
|
||||
_KnobFaceColor = new LinearGradientColorTable();
|
||||
_KnobFaceColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
_KnobIndicatorColor = new LinearGradientColorTable();
|
||||
_KnobIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
_MinZoneIndicatorColor = new LinearGradientColorTable();
|
||||
_MinZoneIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
_MaxZoneIndicatorColor = new LinearGradientColorTable();
|
||||
_MaxZoneIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
_MidZoneIndicatorColor = new LinearGradientColorTable();
|
||||
_MidZoneIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
}
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region MajorTickColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the Major Tick marks
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the Major Tick marks")]
|
||||
public Color MajorTickColor
|
||||
{
|
||||
get { return (_MajorTickColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_MajorTickColor != value)
|
||||
{
|
||||
_MajorTickColor = value;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeMajorTickColor()
|
||||
{
|
||||
return (_MajorTickColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetMajorTickColor()
|
||||
{
|
||||
MajorTickColor = Color.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MinorTickColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the Minor Tick marks
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the Minor Tick marks")]
|
||||
public Color MinorTickColor
|
||||
{
|
||||
get { return (_MinorTickColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_MinorTickColor != value)
|
||||
{
|
||||
_MinorTickColor = value;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeMinorTickColor()
|
||||
{
|
||||
return (_MinorTickColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetMinorTickColor()
|
||||
{
|
||||
MinorTickColor = Color.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region KnobIndicatorPointerBorderColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the KnobIndicatorPointer Border
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the KnobIndicatorPointer Border")]
|
||||
public Color KnobIndicatorPointerBorderColor
|
||||
{
|
||||
get { return (_KnobIndicatorPointerBorderColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_KnobIndicatorPointerBorderColor != value)
|
||||
{
|
||||
_KnobIndicatorPointerBorderColor = value;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeKnobIndicatorPointerBorderColor()
|
||||
{
|
||||
return (_KnobIndicatorPointerBorderColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetKnobIndicatorPointerBorderColor()
|
||||
{
|
||||
KnobIndicatorPointerBorderColor = Color.Empty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region KnobIndicatorPointerBorderWidth
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the KnobIndicatorPointer Border
|
||||
/// </summary>
|
||||
[Browsable(true), DefaultValue(0)]
|
||||
[Description("Indicates the width of the KnobIndicatorPointer Border")]
|
||||
public int KnobIndicatorPointerBorderWidth
|
||||
{
|
||||
get { return (_KnobIndicatorPointerBorderWidth); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_KnobIndicatorPointerBorderWidth != value)
|
||||
{
|
||||
_KnobIndicatorPointerBorderWidth = value;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region KnobIndicatorPointerColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the KnobIndicatorPointer
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the KnobIndicatorPointer")]
|
||||
public Color KnobIndicatorPointerColor
|
||||
{
|
||||
get { return (_KnobIndicatorPointerColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_KnobIndicatorPointerColor != value)
|
||||
{
|
||||
_KnobIndicatorPointerColor = value;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeKnobIndicatorPointerColor()
|
||||
{
|
||||
return (_KnobIndicatorPointerColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetKnobIndicatorPointerColor()
|
||||
{
|
||||
KnobIndicatorPointerColor = Color.Empty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ZoneIndicatorColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the ZoneIndicator
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the ZoneIndicator")]
|
||||
public Color ZoneIndicatorColor
|
||||
{
|
||||
get { return (_ZoneIndicatorColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_ZoneIndicatorColor != value)
|
||||
{
|
||||
_ZoneIndicatorColor = value;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeZoneIndicatorColor()
|
||||
{
|
||||
return (_ZoneIndicatorColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetZoneIndicatorColor()
|
||||
{
|
||||
ZoneIndicatorColor = Color.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region KnobFaceColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the KnobFace
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the KnobFace")]
|
||||
public LinearGradientColorTable KnobFaceColor
|
||||
{
|
||||
get { return (_KnobFaceColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_KnobFaceColor != value)
|
||||
{
|
||||
if (_KnobFaceColor != null)
|
||||
_KnobFaceColor.ColorTableChanged -= KnobColorTableChanged;
|
||||
|
||||
_KnobFaceColor = value;
|
||||
|
||||
if (_KnobFaceColor != null)
|
||||
_KnobFaceColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeKnobFaceColor()
|
||||
{
|
||||
return (_KnobFaceColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetKnobFaceColor()
|
||||
{
|
||||
KnobFaceColor = LinearGradientColorTable.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region KnobIndicatorColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the KnobIndicator
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the KnobIndicator")]
|
||||
public LinearGradientColorTable KnobIndicatorColor
|
||||
{
|
||||
get { return (_KnobIndicatorColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_KnobIndicatorColor != value)
|
||||
{
|
||||
if (_KnobIndicatorColor != null)
|
||||
_KnobIndicatorColor.ColorTableChanged -= KnobColorTableChanged;
|
||||
|
||||
_KnobIndicatorColor = value;
|
||||
|
||||
if (_KnobIndicatorColor != null)
|
||||
_KnobIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeKnobIndicatorColor()
|
||||
{
|
||||
return (_KnobIndicatorColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetKnobIndicatorColor()
|
||||
{
|
||||
KnobIndicatorColor = LinearGradientColorTable.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MinZoneIndicatorColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the MinZoneIndicator
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the MinZoneIndicator")]
|
||||
public LinearGradientColorTable MinZoneIndicatorColor
|
||||
{
|
||||
get { return (_MinZoneIndicatorColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_MinZoneIndicatorColor != value)
|
||||
{
|
||||
if (_MinZoneIndicatorColor != null)
|
||||
_MinZoneIndicatorColor.ColorTableChanged -= KnobColorTableChanged;
|
||||
|
||||
_MinZoneIndicatorColor = value;
|
||||
|
||||
if (_MinZoneIndicatorColor != null)
|
||||
_MinZoneIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeMinZoneIndicatorColor()
|
||||
{
|
||||
return (_MinZoneIndicatorColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetMinZoneIndicatorColor()
|
||||
{
|
||||
MinZoneIndicatorColor = LinearGradientColorTable.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MaxZoneIndicatorColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the MaxZoneIndicator
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the MaxZoneIndicator")]
|
||||
public LinearGradientColorTable MaxZoneIndicatorColor
|
||||
{
|
||||
get { return (_MaxZoneIndicatorColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_MaxZoneIndicatorColor != value)
|
||||
{
|
||||
if (_MaxZoneIndicatorColor != null)
|
||||
_MaxZoneIndicatorColor.ColorTableChanged -= KnobColorTableChanged;
|
||||
|
||||
_MaxZoneIndicatorColor = value;
|
||||
|
||||
if (_MaxZoneIndicatorColor != null)
|
||||
_MaxZoneIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeMaxZoneIndicatorColor()
|
||||
{
|
||||
return (_MaxZoneIndicatorColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetMaxZoneIndicatorColor()
|
||||
{
|
||||
MaxZoneIndicatorColor = LinearGradientColorTable.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MidZoneIndicatorColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the MidZoneIndicator
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Description("Indicates the color of the MidZoneIndicator")]
|
||||
public LinearGradientColorTable MidZoneIndicatorColor
|
||||
{
|
||||
get { return (_MidZoneIndicatorColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_MidZoneIndicatorColor != value)
|
||||
{
|
||||
if (_MidZoneIndicatorColor != null)
|
||||
_MidZoneIndicatorColor.ColorTableChanged -= KnobColorTableChanged;
|
||||
|
||||
_MidZoneIndicatorColor = value;
|
||||
|
||||
if (_MidZoneIndicatorColor != null)
|
||||
_MidZoneIndicatorColor.ColorTableChanged += KnobColorTableChanged;
|
||||
|
||||
OnColorTableChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeMidZoneIndicatorColor()
|
||||
{
|
||||
return (_MidZoneIndicatorColor.IsEmpty == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void ResetMidZoneIndicatorColor()
|
||||
{
|
||||
MidZoneIndicatorColor = LinearGradientColorTable.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsEmpty
|
||||
|
||||
[Browsable(false)]
|
||||
public bool IsEmpty
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_MajorTickColor.IsEmpty && _MinorTickColor.IsEmpty && _KnobIndicatorPointerColor.IsEmpty &&
|
||||
_KnobFaceColor.IsEmpty && _ZoneIndicatorColor.IsEmpty && _MinZoneIndicatorColor.IsEmpty &&
|
||||
_MaxZoneIndicatorColor.IsEmpty && _MidZoneIndicatorColor.IsEmpty && _KnobIndicatorColor.IsEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region KnobColorTableChanged
|
||||
|
||||
/// <summary>
|
||||
/// KnobColorTableChanged
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void KnobColorTableChanged(object sender, EventArgs e)
|
||||
{
|
||||
OnColorTableChange();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnColorTableChange
|
||||
|
||||
/// <summary>
|
||||
/// OnColorTableChange
|
||||
/// </summary>
|
||||
private void OnColorTableChange()
|
||||
{
|
||||
if (ColorTableChanged != null)
|
||||
ColorTableChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region KnobColorTableConvertor
|
||||
|
||||
/// <summary>
|
||||
/// KnobColorTableConvertor
|
||||
/// </summary>
|
||||
public class KnobColorTableConvertor : ExpandableObjectConverter
|
||||
{
|
||||
public override object ConvertTo(
|
||||
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
{
|
||||
KnobColorTable kct = value as KnobColorTable;
|
||||
|
||||
if (kct != null)
|
||||
{
|
||||
ColorConverter cvt = new ColorConverter();
|
||||
|
||||
string s;
|
||||
|
||||
if ((s = MyColorConverter(kct.KnobFaceColor, cvt)) != null)
|
||||
return (s);
|
||||
|
||||
if ((s = MyColorConverter(kct.KnobIndicatorColor, cvt)) != null)
|
||||
return (s);
|
||||
|
||||
if ((s = MyColorConverter(kct.MinZoneIndicatorColor, cvt)) != null)
|
||||
return (s);
|
||||
|
||||
if ((s = MyColorConverter(kct.MidZoneIndicatorColor, cvt)) != null)
|
||||
return (s);
|
||||
|
||||
if ((s = MyColorConverter(kct.MaxZoneIndicatorColor, cvt)) != null)
|
||||
return (s);
|
||||
|
||||
if (kct.MinorTickColor.IsEmpty == false)
|
||||
return (cvt.ConvertToString(kct.MinorTickColor));
|
||||
|
||||
if (kct.MajorTickColor.IsEmpty == false)
|
||||
return (cvt.ConvertToString(kct.MajorTickColor));
|
||||
|
||||
if (kct.KnobIndicatorPointerColor.IsEmpty == false)
|
||||
return (cvt.ConvertToString(kct.KnobIndicatorPointerColor));
|
||||
|
||||
if (kct.ZoneIndicatorColor.IsEmpty == false)
|
||||
return (cvt.ConvertToString(kct.ZoneIndicatorColor));
|
||||
|
||||
return (String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return (base.ConvertTo(context, culture, value, destinationType));
|
||||
}
|
||||
|
||||
#region MyColorConverter
|
||||
|
||||
/// <summary>
|
||||
/// MyColorConverter
|
||||
/// </summary>
|
||||
/// <param name="ct">ColorTable</param>
|
||||
/// <param name="cvt">ColorConverter</param>
|
||||
/// <returns>string or null</returns>
|
||||
private string MyColorConverter(LinearGradientColorTable ct, ColorConverter cvt)
|
||||
{
|
||||
if (ct.Start.IsEmpty == false)
|
||||
return (cvt.ConvertToString(ct.Start));
|
||||
|
||||
if (ct.End.IsEmpty == false)
|
||||
return (cvt.ConvertToString(ct.Start));
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
36
PROMS/DotNetBar Source Code/InstrumentationControls/Knobs/KnobControl.Designer.cs
generated
Normal file
36
PROMS/DotNetBar Source Code/InstrumentationControls/Knobs/KnobControl.Designer.cs
generated
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
partial class KnobControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DevComponents.Instrumentation.Primitives
|
||||
{
|
||||
public class KnobStyle1 : BaseKnob
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="knobControl">Associated knob control</param>
|
||||
public KnobStyle1(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 = 2;
|
||||
|
||||
MajorTickSize = new Size((int)(KnobWidth * 0.015), (int)(KnobWidth * 0.017));
|
||||
MinorTickSize = new Size(MajorTickSize.Width / 2, MajorTickSize.Height);
|
||||
|
||||
IndTickHeight = (int)ZoneIndWidth;
|
||||
|
||||
CalculateBoundingRects();
|
||||
|
||||
// Fill in the default knob colors
|
||||
|
||||
DefaultColorTable.MajorTickColor = Color.Black;
|
||||
DefaultColorTable.MinorTickColor = Color.Black;
|
||||
DefaultColorTable.ZoneIndicatorColor = Color.Black;
|
||||
DefaultColorTable.KnobIndicatorPointerColor = Color.Gray;
|
||||
DefaultColorTable.KnobIndicatorPointerBorderColor = Color.Gray;
|
||||
|
||||
DefaultColorTable.KnobFaceColor = new LinearGradientColorTable(Color.Black, Color.Gray, 40);
|
||||
DefaultColorTable.KnobIndicatorColor = new LinearGradientColorTable(Color.Gray, Color.White, 40);
|
||||
DefaultColorTable.MinZoneIndicatorColor = new LinearGradientColorTable(Color.White, Color.Green);
|
||||
DefaultColorTable.MaxZoneIndicatorColor = new LinearGradientColorTable(Color.Yellow, Color.Red);
|
||||
}
|
||||
|
||||
#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 + (int)(KnobWidth * 0.04f);
|
||||
|
||||
ZoneIndicatorBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the KnobFace and inset face rectangles
|
||||
|
||||
delta += 1;
|
||||
|
||||
KnobFaceBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the KnobIndicator bounding rectangle
|
||||
|
||||
delta += (int)(KnobWidth * .07f);
|
||||
|
||||
KnobIndicatorBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the TickLabel bounding rect
|
||||
|
||||
delta = (int)((MaxLabelWidth + IndTickHeight) * .85f);
|
||||
|
||||
TickLabelBounds = new Rectangle(ZoneIndicatorBounds.Location, ZoneIndicatorBounds.Size);
|
||||
TickLabelBounds.Inflate(delta, delta);
|
||||
|
||||
// Calculate the focus rectangle
|
||||
|
||||
FocusRectBounds = new Rectangle(KnobIndicatorBounds.Location, KnobIndicatorBounds.Size);
|
||||
|
||||
delta = (int)(KnobIndicatorBounds.Width * .035);
|
||||
|
||||
FocusRectBounds.Inflate(-delta, -delta);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Part rendering code
|
||||
|
||||
#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;
|
||||
|
||||
using (Pen pen = new Pen(ZoneIndicatorColor, 2))
|
||||
g.DrawEllipse(pen, ZoneIndicatorBounds);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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;
|
||||
|
||||
using (Brush br = KnobFaceColor.GetBrush(KnobFaceBounds))
|
||||
g.FillEllipse(br, KnobFaceBounds);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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;
|
||||
|
||||
// Render the Indicator shadow
|
||||
|
||||
Rectangle r = new Rectangle(KnobIndicatorBounds.X, KnobIndicatorBounds.Y,
|
||||
KnobIndicatorBounds.Width, KnobIndicatorBounds.Height);
|
||||
|
||||
int delta = (int) (KnobWidth * .025f);
|
||||
|
||||
r.Offset(delta, delta);
|
||||
|
||||
using (SolidBrush br = new
|
||||
SolidBrush(Color.FromArgb(160, KnobFaceColor.Start)))
|
||||
{
|
||||
g.FillEllipse(br, r);
|
||||
}
|
||||
|
||||
r.Offset(-delta, -delta);
|
||||
|
||||
// Render the indicator
|
||||
|
||||
using (LinearGradientBrush br = new
|
||||
LinearGradientBrush(KnobIndicatorBounds, KnobIndicatorColor.End, KnobIndicatorColor.Start, -40f))
|
||||
g.FillEllipse(br, KnobIndicatorBounds);
|
||||
|
||||
delta = (int) (r.Width * .02f);
|
||||
|
||||
r.Inflate(-delta, -delta);
|
||||
|
||||
using (Brush br = KnobIndicatorColor.GetBrush(r))
|
||||
g.FillEllipse(br, r);
|
||||
|
||||
// Render the indicator dimple
|
||||
|
||||
r = GetIndicatorRect();
|
||||
|
||||
delta = (int) (r.Width * .05f);
|
||||
|
||||
r.Inflate(delta, delta);
|
||||
|
||||
using (Brush lgb = new
|
||||
LinearGradientBrush(r, Color.White, KnobIndicatorPointerColor, -40f))
|
||||
{
|
||||
g.FillEllipse(lgb, r);
|
||||
}
|
||||
|
||||
r.Inflate(-delta, -delta);
|
||||
|
||||
using (LinearGradientBrush lgb = new
|
||||
LinearGradientBrush(r, KnobIndicatorPointerColor, Color.White, 220f))
|
||||
{
|
||||
g.FillEllipse(lgb, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the knob indicator rectangle
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Rectangle GetIndicatorRect()
|
||||
{
|
||||
float degrees = (float)(Knob.SweepAngle / ValueCount) *
|
||||
(float)(Knob.Value - Knob.MinValue) + Knob.StartAngle;
|
||||
|
||||
double radians = GetRadians(degrees);
|
||||
|
||||
int dx = KnobIndicatorBounds.X + KnobIndicatorBounds.Width / 2;
|
||||
int dy = KnobIndicatorBounds.Y + KnobIndicatorBounds.Height / 2;
|
||||
int h = (int)(KnobIndicatorBounds.Width * .3f);
|
||||
|
||||
int x = (int)(Math.Cos(radians) * h + dx);
|
||||
int y = (int)(Math.Sin(radians) * h + dy);
|
||||
|
||||
int radius = (int)(KnobIndicatorBounds.Width * .12f);
|
||||
|
||||
Rectangle r = new Rectangle(x - radius, y - radius, radius * 2, radius * 2);
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DevComponents.Instrumentation.Primitives
|
||||
{
|
||||
public class KnobStyle2 : BaseKnob
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="knobControl">Associated knob control</param>
|
||||
public KnobStyle2(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.047f;
|
||||
|
||||
MajorTickSize = new Size((int)(KnobWidth * 0.008), (int)(KnobWidth * 0.017));
|
||||
MinorTickSize = new Size(1, (int)(KnobWidth * 0.02));
|
||||
|
||||
IndTickHeight = (int)ZoneIndWidth / 3;
|
||||
|
||||
CalculateBoundingRects();
|
||||
|
||||
// Fill in the default knob colors
|
||||
|
||||
DefaultColorTable.MajorTickColor = Color.Black;
|
||||
DefaultColorTable.MinorTickColor = Color.Gray;
|
||||
DefaultColorTable.ZoneIndicatorColor = Color.SteelBlue;
|
||||
DefaultColorTable.KnobIndicatorPointerColor = Color.Black;
|
||||
DefaultColorTable.KnobIndicatorPointerBorderColor = Color.Black;
|
||||
|
||||
DefaultColorTable.KnobFaceColor = new LinearGradientColorTable(Color.White, Color.LightGray);
|
||||
DefaultColorTable.KnobIndicatorColor = new LinearGradientColorTable(0xFFFFFF, 0x1A507B);
|
||||
DefaultColorTable.MinZoneIndicatorColor = new LinearGradientColorTable(Color.White, Color.Green);
|
||||
DefaultColorTable.MaxZoneIndicatorColor = new LinearGradientColorTable(Color.Yellow, Color.Red);
|
||||
}
|
||||
|
||||
#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 + (int)(KnobWidth * 0.05f);
|
||||
|
||||
ZoneIndicatorBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the KnobFace and inset face rectangles
|
||||
|
||||
delta += (int)ZoneIndWidth + 1;
|
||||
|
||||
KnobFaceBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the KnobIndicator bounding rectangle
|
||||
|
||||
delta += (int)(KnobWidth * .068f);
|
||||
|
||||
KnobIndicatorBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the TickLabel bounding rect
|
||||
|
||||
delta = (int)((MaxLabelWidth + IndTickHeight) * .60f + IndTickHeight);
|
||||
|
||||
TickLabelBounds = new Rectangle(ZoneIndicatorBounds.Location, ZoneIndicatorBounds.Size);
|
||||
TickLabelBounds.Inflate(delta, delta);
|
||||
|
||||
// Calculate the focus rectangle
|
||||
|
||||
FocusRectBounds = new Rectangle(KnobFaceBounds.Location, KnobFaceBounds.Size);
|
||||
|
||||
delta = (int)(KnobFaceBounds.Width * .025);
|
||||
|
||||
FocusRectBounds.Inflate(-delta, -delta);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Part rendering code
|
||||
|
||||
#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;
|
||||
|
||||
Color c = ControlPaint.Light(ZoneIndicatorColor, .30f);
|
||||
|
||||
int passes = (int) (ZoneIndWidth);
|
||||
int adj = 100 / passes;
|
||||
|
||||
Rectangle r = new Rectangle(ZoneIndicatorBounds.X,
|
||||
ZoneIndicatorBounds.Y, ZoneIndicatorBounds.Width, ZoneIndicatorBounds.Height);
|
||||
|
||||
r.Inflate(-passes, -passes);
|
||||
|
||||
for (int i = 0; i < passes; i++)
|
||||
{
|
||||
using (Pen pen = new Pen(c, 2))
|
||||
{
|
||||
g.DrawEllipse(pen, r);
|
||||
|
||||
r.Inflate(1, 1);
|
||||
|
||||
c = Color.FromArgb(Math.Max(0, c.R - adj),
|
||||
Math.Max(0, c.G - adj), Math.Max(0, c.B - adj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 * .1f);
|
||||
|
||||
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 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())
|
||||
{
|
||||
// Draw the 14 arc segments all the way to the
|
||||
// center of the knob just in case the user wants
|
||||
// to render a different sized/shaped knob indicator
|
||||
|
||||
Rectangle rInset = new Rectangle(KnobFaceBounds.X, KnobFaceBounds.Y,
|
||||
KnobFaceBounds.Width, KnobFaceBounds.Height);
|
||||
|
||||
int w = KnobFaceBounds.Width/2 - 1;
|
||||
|
||||
rInset.Inflate(-w, -w);
|
||||
|
||||
const float arc = 360f/14;
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
if (i%2 == 0)
|
||||
{
|
||||
path.AddArc(KnobFaceBounds, i*arc, arc);
|
||||
path.AddArc(rInset, (i + 1)*arc, -arc);
|
||||
|
||||
// Let Windows connect the arcs
|
||||
|
||||
path.CloseFigure();
|
||||
}
|
||||
}
|
||||
|
||||
// Select an appropriate hatch size given
|
||||
// the overall size of the control
|
||||
|
||||
HatchStyle hs = (KnobWidth < 250)
|
||||
? HatchStyle.LightUpwardDiagonal
|
||||
: HatchStyle.WideUpwardDiagonal;
|
||||
|
||||
// Fill the face and then draw the outlining path
|
||||
|
||||
using (HatchBrush hbr = new HatchBrush(hs, KnobFaceColor.Start, KnobFaceColor.End))
|
||||
g.FillPath(hbr, path);
|
||||
|
||||
using (Pen pen = new Pen(KnobFaceColor.End))
|
||||
g.DrawPath(pen, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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 draw the
|
||||
// arrow lines into it
|
||||
|
||||
using (GraphicsPath path = new GraphicsPath())
|
||||
{
|
||||
path.AddLines(GetIndicatorPoints());
|
||||
path.CloseFigure();
|
||||
|
||||
// Fill the closed arrow
|
||||
|
||||
using (SolidBrush br = new SolidBrush(KnobIndicatorPointerColor))
|
||||
g.FillPath(br, path);
|
||||
|
||||
// Outline the arrow and draw the knob face
|
||||
|
||||
if (KnobIndicatorPointerBorderWidth > 0 &&
|
||||
KnobIndicatorPointerColor.Equals(KnobIndicatorPointerBorderColor) == false)
|
||||
{
|
||||
using (Pen pen = new Pen(KnobIndicatorPointerBorderColor, KnobIndicatorPointerBorderWidth))
|
||||
g.DrawPath(pen, path);
|
||||
}
|
||||
|
||||
// Fill the knob face
|
||||
|
||||
using (Brush br = KnobIndicatorColor.GetBrush(KnobIndicatorBounds))
|
||||
g.FillEllipse(br, KnobIndicatorBounds);
|
||||
|
||||
// Reset the path and add a glossy looking
|
||||
// hilight to the control face
|
||||
|
||||
path.Reset();
|
||||
path.AddEllipse(KnobIndicatorBounds);
|
||||
|
||||
using (PathGradientBrush pgb = new PathGradientBrush(path))
|
||||
{
|
||||
pgb.CenterColor = KnobIndicatorColor.Start;
|
||||
pgb.SurroundColors = new Color[] {KnobIndicatorColor.End};
|
||||
|
||||
int radius = KnobIndicatorBounds.Width/2;
|
||||
int dr = Math.Max((int) (radius*.1f), 5);
|
||||
|
||||
float dx = (radius - dr)*(float) Math.Sin(GetRadians(60));
|
||||
float dy = (radius - dr)*(float) Math.Cos(GetRadians(60));
|
||||
|
||||
pgb.CenterPoint = new PointF(KnobIndicatorBounds.X + radius - dx,
|
||||
KnobIndicatorBounds.Y + radius - dy);
|
||||
|
||||
g.FillRectangle(pgb, KnobIndicatorBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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 * .052f);
|
||||
|
||||
double rad0 = GetRadians(degrees - 17);
|
||||
double rad1 = GetRadians(degrees);
|
||||
double rad2 = GetRadians(degrees + 17);
|
||||
|
||||
int n = (int)(KnobIndicatorBounds.Width * .03f);
|
||||
|
||||
if (n < 2)
|
||||
n = 2;
|
||||
|
||||
int dx = KnobIndicatorBounds.X + KnobIndicatorBounds.Width / 2 + 1;
|
||||
int dy = KnobIndicatorBounds.Y + KnobIndicatorBounds.Height / 2 + 1;
|
||||
int h = KnobIndicatorBounds.Width / 2 + n;
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,776 @@
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DevComponents.Instrumentation.Primitives
|
||||
{
|
||||
public class KnobStyle4 : BaseKnob
|
||||
{
|
||||
#region Private instance variables
|
||||
|
||||
private Rectangle _KnobFaceInset; // Knob face inset rect
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="knobControl">Associated knob control</param>
|
||||
public KnobStyle4(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.025f;
|
||||
|
||||
MajorTickSize = new Size((int)(KnobWidth * 0.01), (int)(KnobWidth * 0.04));
|
||||
MinorTickSize = new Size(MajorTickSize.Width, (int)(MajorTickSize.Height * .60f));
|
||||
|
||||
IndTickHeight = (int)ZoneIndWidth + MajorTickSize.Height;
|
||||
|
||||
CalculateBoundingRects();
|
||||
|
||||
// Fill in the default knob colors
|
||||
|
||||
DefaultColorTable.MajorTickColor = Color.Gray;
|
||||
DefaultColorTable.MinorTickColor = Color.DeepSkyBlue;
|
||||
DefaultColorTable.ZoneIndicatorColor = Color.DeepSkyBlue;
|
||||
DefaultColorTable.KnobIndicatorPointerColor = Color.White;
|
||||
DefaultColorTable.KnobIndicatorPointerBorderColor = Color.Gray;
|
||||
|
||||
DefaultColorTable.KnobFaceColor = new LinearGradientColorTable(Color.White, ColorFactory.GetColor(0xAAAAAA), 40);
|
||||
DefaultColorTable.KnobIndicatorColor = new LinearGradientColorTable(Color.White, ColorFactory.GetColor(0xAAAAAA), 20);
|
||||
DefaultColorTable.MinZoneIndicatorColor = new LinearGradientColorTable(Color.White, Color.Green);
|
||||
DefaultColorTable.MaxZoneIndicatorColor = new LinearGradientColorTable( Color.Yellow, Color.Red);
|
||||
|
||||
DefaultColorTable.KnobIndicatorPointerBorderWidth = 2;
|
||||
}
|
||||
|
||||
#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 + (int)(KnobWidth * 0.04f);
|
||||
|
||||
ZoneIndicatorBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// Calculate the KnobFace and inset face rectangles
|
||||
|
||||
delta += (int)(ZoneIndWidth);
|
||||
|
||||
KnobFaceBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
_KnobFaceInset = new Rectangle(KnobFaceBounds.X, KnobFaceBounds.Y,
|
||||
KnobFaceBounds.Width, KnobFaceBounds.Height);
|
||||
|
||||
_KnobFaceInset.Inflate(-(int)(KnobWidth * .02f), -(int)(KnobWidth * .02f));
|
||||
|
||||
// Calculate the KnobIndicator bounding rectangle
|
||||
|
||||
delta += (int)(KnobFaceBounds.Width * .23f);
|
||||
|
||||
KnobIndicatorBounds = new Rectangle(delta, delta,
|
||||
KnobWidth - (delta * 2), KnobWidth - (delta * 2));
|
||||
|
||||
// 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 = new Rectangle(KnobIndicatorBounds.Location, KnobIndicatorBounds.Size);
|
||||
|
||||
delta = (int)(KnobIndicatorBounds.Width * .045);
|
||||
|
||||
FocusRectBounds.Inflate(-delta, -delta);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Part rendering code
|
||||
|
||||
#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;
|
||||
|
||||
using (Pen pen = new Pen(ZoneIndicatorColor, ZoneIndWidth))
|
||||
g.DrawArc(pen, ZoneIndicatorBounds, Knob.StartAngle - 1, Knob.SweepAngle + 2);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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())
|
||||
{
|
||||
// Draw the 12, 30 degree arc segments
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
path.AddArc((i % 2 == 0)
|
||||
? KnobFaceBounds : _KnobFaceInset, i * 30 - 15, 30);
|
||||
}
|
||||
|
||||
path.CloseFigure();
|
||||
|
||||
// Fill the face and then draw the outlining path
|
||||
|
||||
using (Brush br = KnobFaceColor.GetBrush(KnobFaceBounds))
|
||||
g.FillPath(br, path);
|
||||
|
||||
g.DrawPath(Pens.Gray, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RenderKnobIndicator
|
||||
|
||||
#region RenderKnobIndicator
|
||||
|
||||
/// <summary>
|
||||
/// Renders the knob indicator
|
||||
/// </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 draw the
|
||||
// arrow lines into it
|
||||
|
||||
using (GraphicsPath path = new GraphicsPath())
|
||||
{
|
||||
path.AddLines(GetIndicatorPoints());
|
||||
|
||||
path.CloseFigure();
|
||||
|
||||
// Fill the closed arrow
|
||||
|
||||
using (SolidBrush br = new SolidBrush(KnobIndicatorPointerColor))
|
||||
g.FillPath(br, path);
|
||||
|
||||
// Outline the arrow and draw the knob face
|
||||
|
||||
if (KnobIndicatorPointerBorderWidth > 0 &&
|
||||
KnobIndicatorPointerColor.Equals(KnobIndicatorPointerBorderColor) == false)
|
||||
{
|
||||
int width = KnobIndicatorPointerBorderWidth;
|
||||
|
||||
using (Pen pen = new Pen(KnobIndicatorPointerBorderColor, width))
|
||||
g.DrawPath(pen, path);
|
||||
}
|
||||
|
||||
Color c = ControlPaint.Dark(KnobIndicatorColor.End, .4f);
|
||||
|
||||
using (Pen pen = new Pen(c, 2))
|
||||
g.DrawArc(pen, KnobIndicatorBounds, 0, 360);
|
||||
|
||||
// Fill the knob face
|
||||
|
||||
using (Brush br = KnobIndicatorColor.GetBrush(KnobIndicatorBounds))
|
||||
g.FillEllipse(br, KnobIndicatorBounds);
|
||||
|
||||
// Reset the path and add a glossy looking
|
||||
// hilight to the top of the control
|
||||
|
||||
path.Reset();
|
||||
|
||||
path.AddArc(KnobFaceBounds, 180, 180);
|
||||
path.CloseFigure();
|
||||
|
||||
using (LinearGradientBrush lgb =
|
||||
new LinearGradientBrush(KnobFaceBounds, Color.FromArgb(75, Color.White),
|
||||
Color.Transparent, LinearGradientMode.Vertical))
|
||||
{
|
||||
g.FillPath(lgb, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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)(KnobIndicatorBounds.Width * .25f);
|
||||
|
||||
double rad0 = GetRadians(degrees - 10);
|
||||
double rad1 = GetRadians(degrees);
|
||||
double rad2 = GetRadians(degrees + 10);
|
||||
|
||||
int dx = KnobIndicatorBounds.X + KnobIndicatorBounds.Width / 2 + 1;
|
||||
int dy = KnobIndicatorBounds.Y + KnobIndicatorBounds.Height / 2 + 1;
|
||||
int h = KnobIndicatorBounds.Width / 2 + 4;
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user