DotNet 4.8.1 build of DotNetBar

This commit is contained in:
2025-02-07 10:35:23 -05:00
parent 33439b63a0
commit 6b0a5d60f4
2609 changed files with 989814 additions and 7 deletions

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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