//-----------------------------------------------------------------------
//
// See below.
//
//-----------------------------------------------------------------------
namespace AquaControls
{
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Windows.Forms;
using global::SharedObjects;
///
/// Aqua Gauge Control - A Windows User Control.
/// Author : Ambalavanar Thirugnanam
/// Date : 24th August 2007
/// email : ambalavanar.thiru@gmail.com
/// This is control is for free. You can use for any commercial or non-commercial purposes.
/// [Please do no remove this header when using this control in your application.]
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1119:StatementMustNotUseUnnecessaryParenthesis", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1504:AllAccessorsMustBeSingleLineOrMultiLine", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:CurlyBracketsMustNotBeOmitted", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1400:AccessModifierMustBeDeclared", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1513:ClosingCurlyBracketMustBeFollowedByBlankLine", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:PartialElementsMustBeDocumented", Justification = "Tool Generated.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1623:PropertySummaryDocumentationMustMatchAccessors", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1504:AllAccessorsMustBeSingleLineOrMultiLine", Justification = "Reviewed.")]
public partial class AquaGauge : UserControl
{
#region Private Attributes
private float minValue;
private float maxValue;
private float currentValue;
private float currentDigitalValue;
private Color digitColor = Color.Black;
private float recommendedValueMin;
private float recommendedValueMax;
private float red1ValueMin;
private float red1ValueMax;
private float red2ValueMin;
private float red2ValueMax;
private float yellowValueMin;
private float yellowValueMax;
private float blueValueMin;
private float blueValueMax;
private uint noOfDivisions;
private uint noOfSubDivisions;
private string dialText;
private string digitalGaugeText;
private Color dialColor = Color.Lavender;
private float glossinessAlpha = 25;
private int oldWidth, oldHeight;
int x, y, width, height;
float fromAngle = 135F;
float toAngle = 405F;
private bool enableTransparentBackground;
private bool requiresRedraw;
private Image backgroundImg;
private Rectangle rectImg;
private string digitMask = "000.00";
#endregion
public AquaGauge()
{
this.InitializeComponent();
this.x = 5;
this.y = 5;
this.width = this.Width - 10;
this.height = this.Height - 10;
this.noOfDivisions = 10;
this.noOfSubDivisions = 3;
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.BackColor = Color.Transparent;
this.Resize += new EventHandler(this.AquaGauge_Resize);
this.requiresRedraw = true;
}
#region Public Properties
///
/// Event logging interface instance.
///
public ILogging iLogging { get; set; }
///
/// Color of digits.
///
public Color DigitColor
{
get
{
return this.digitColor;
}
set
{
this.digitColor = value;
}
}
///
/// Mask for formatting digital value.
///
public string DigitMask
{
get
{
return this.digitMask;
}
set
{
this.digitMask = value;
}
}
///
/// Gets or sets Mininum value on the scale
///
[DefaultValue(0)]
[Description("Mininum value on the scale")]
public float MinValue
{
get { return this.minValue; }
set
{
if (value < this.maxValue)
{
this.minValue = value;
if (this.currentValue < this.minValue)
this.currentValue = this.minValue;
if (this.recommendedValueMin < this.minValue)
this.recommendedValueMin = this.minValue;
if (this.recommendedValueMax < this.minValue)
this.recommendedValueMax = this.minValue;
if (this.red1ValueMin < this.minValue)
this.red1ValueMin = this.minValue;
if (this.red1ValueMax < this.minValue)
this.red1ValueMax = this.minValue;
if (this.red2ValueMin < this.minValue)
this.red2ValueMin = this.minValue;
if (this.red2ValueMax < this.minValue)
this.red2ValueMax = this.minValue;
if (this.yellowValueMin < this.minValue)
this.yellowValueMin = this.minValue;
if (this.yellowValueMax < this.minValue)
this.yellowValueMax = this.minValue;
if (this.blueValueMin < this.minValue)
this.blueValueMin = this.minValue;
if (this.blueValueMax < this.minValue)
this.blueValueMax = this.minValue;
this.requiresRedraw = true;
this.Invalidate();
}
}
}
///
/// Gets or sets Maximum value on the scale
///
[DefaultValue(100)]
[Description("Maximum value on the scale")]
public float MaxValue
{
get { return maxValue; }
set
{
if (value > minValue)
{
maxValue = value;
if (currentValue > maxValue)
currentValue = maxValue;
if (recommendedValueMin > maxValue)
recommendedValueMin = maxValue;
if (recommendedValueMax > maxValue)
recommendedValueMax = maxValue;
if (red1ValueMin > maxValue)
red1ValueMin = maxValue;
if (red1ValueMax > maxValue)
red1ValueMax = maxValue;
if (red2ValueMin > maxValue)
red2ValueMin = maxValue;
if (red2ValueMax > maxValue)
red2ValueMax = maxValue;
if (yellowValueMin > maxValue)
yellowValueMin = maxValue;
if (yellowValueMax > maxValue)
yellowValueMax = maxValue;
if (blueValueMin > maxValue)
blueValueMin = maxValue;
if (blueValueMax > maxValue)
blueValueMax = maxValue;
requiresRedraw = true;
this.Invalidate();
}
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(10.0)]
[Description("Threshold value from which green area will be marked.")]
public float RecommendedValueMin
{
get { return recommendedValueMin; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
recommendedValueMin = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(20.0)]
[Description("Threshold value from which green area will be marked.")]
public float RecommendedValueMax
{
get { return recommendedValueMax; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
recommendedValueMax = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(10.0)]
[Description("Threshold value from which green area will be marked.")]
public float Red1ValueMin
{
get { return red1ValueMin; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
red1ValueMin = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(20.0)]
[Description("Threshold value from which green area will be marked.")]
public float Red1ValueMax
{
get { return red1ValueMax; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
red1ValueMax = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(10.0)]
[Description("Threshold value from which green area will be marked.")]
public float Red2ValueMin
{
get { return red2ValueMin; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
red2ValueMin = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(20.0)]
[Description("Threshold value from which green area will be marked.")]
public float Red2ValueMax
{
get { return red2ValueMax; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
red2ValueMax = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(10.0)]
[Description("Threshold value from which green area will be marked.")]
public float YellowValueMin
{
get { return yellowValueMin; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
yellowValueMin = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(20.0)]
[Description("Threshold value from which green area will be marked.")]
public float YellowValueMax
{
get { return yellowValueMax; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
yellowValueMax = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(10.0)]
[Description("Threshold value from which green area will be marked.")]
public float BlueValueMin
{
get { return blueValueMin; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
blueValueMin = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Threshold value from which green area will be marked.
///
[DefaultValue(20.0)]
[Description("Threshold value from which green area will be marked.")]
public float BlueValueMax
{
get { return blueValueMax; }
set
{
float newValue = value;
if (newValue < minValue) newValue = minValue;
if (newValue > maxValue) newValue = maxValue;
blueValueMax = newValue;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Value where the pointer will point to.
///
[DefaultValue(0)]
[Description("Value where the pointer will point to.")]
public float Value
{
get { return currentValue; }
set
{
if (value >= minValue && value <= maxValue)
{
currentValue = value;
}
else
{
if (value < minValue)
{
currentValue = minValue;
}
else
{
currentValue = maxValue;
}
}
this.Refresh();
}
}
///
/// Gets or sets Value for digital display.
///
[DefaultValue(0)]
[Description("Value to display in digital display.")]
public float DigitalValue
{
get
{
return this.currentDigitalValue;
}
set
{
this.currentDigitalValue = value;
}
}
///
/// Gets or sets Background color of the dial
///
[Description("Background color of the dial")]
public Color DialColor
{
get { return dialColor; }
set
{
dialColor = value;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or sets Glossiness strength. Range: 0-100
///
[DefaultValue(72)]
[Description("Glossiness strength. Range: 0-100")]
public float Glossiness
{
get
{
return (glossinessAlpha * 100) / 220;
}
set
{
float val = value;
if (val > 100)
value = 100;
if (val < 0)
value = 0;
glossinessAlpha = (value * 220) / 100;
this.Refresh();
}
}
///
/// Get or sets the number of Divisions in the dial scale.
///
[DefaultValue(10)]
[Description("Get or Sets the number of Divisions in the dial scale.")]
public int NoOfDivisions
{
get { return (int)this.noOfDivisions; }
set
{
if (value > 1 && value < 25)
{
this.noOfDivisions = (uint)value;
requiresRedraw = true;
this.Invalidate();
}
}
}
///
/// Gets or Sets the number of Sub Divisions in the scale per Division.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SubDivisions", Justification = "Reviewed")]
[DefaultValue(3)]
[Description("Gets or Sets the number of Sub Divisions in the scale per Division.")]
public int NoOfSubDivisions
{
get { return (int)this.noOfSubDivisions; }
set
{
if (value > 0 && value <= 10)
{
this.noOfSubDivisions = (uint)value;
requiresRedraw = true;
this.Invalidate();
}
}
}
///
/// Gets or Sets the Text to be displayed in the dial
///
[Description("Gets or Sets the Text to be displayed in the dial")]
public string DialText
{
get { return this.dialText; }
set
{
this.dialText = value;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Gets or Sets the Text to be displayed in the dial
///
[Description("Gets or Sets the Text to be displayed for digital gauge in the dial")]
public string DigitalGaugeText
{
get { return this.digitalGaugeText; }
set
{
this.digitalGaugeText = value;
requiresRedraw = true;
this.Invalidate();
}
}
///
/// Enables or Disables Transparent Background color.
/// Note: Enabling this will reduce the performance and may make the control flicker.
///
[DefaultValue(false)]
[Description("Enables or Disables Transparent Background color. Note: Enabling this will reduce the performance and may make the control flicker.")]
public bool EnableTransparentBackground
{
get { return this.enableTransparentBackground; }
set
{
this.enableTransparentBackground = value;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, !enableTransparentBackground);
requiresRedraw = true;
this.Refresh();
}
}
#endregion
#region Overriden Control methods
///
/// Draws the pointer.
///
/// Event arguments.
protected override void OnPaint(PaintEventArgs e)
{
if (e != null)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
width = this.Width - (x * 2);
height = this.Height - (y * 2);
DrawPointer(e.Graphics, ((width) / 2) + x, ((height) / 2) + y);
RectangleF digiFRect = new RectangleF((this.Width / 2) - (this.width / 7), (int)(this.height / 1.2), this.width / 4, this.Height / 12);
DisplayNumber(e.Graphics, this.currentDigitalValue, digiFRect);
}
}
///
/// Draws the dial background.
///
/// Event arguments.
protected override void OnPaintBackground(PaintEventArgs e)
{
if (e != null)
{
if (!enableTransparentBackground)
{
base.OnPaintBackground(e);
}
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
using (SolidBrush brush = new SolidBrush(Color.Transparent))
{
e.Graphics.FillRectangle(brush, new Rectangle(0, 0, Width, Height));
}
if (backgroundImg == null || requiresRedraw)
{
backgroundImg = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(backgroundImg);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
width = this.Width - (x * 2);
height = this.Height - (y * 2);
rectImg = new Rectangle(x, y, width, height);
// Draw background color
// using (Brush backGroundBrush = new SolidBrush(Color.FromArgb(120, dialColor)))
using (Brush backGroundBrush = new SolidBrush(Color.FromArgb(255, dialColor)))
{
g.FillEllipse(backGroundBrush, x, y, width, height);
}
// Draw Rim
using (SolidBrush outlineBrush = new SolidBrush(Color.FromArgb(100, Color.SlateGray)))
{
using (Pen outline = new Pen(outlineBrush, (float)(width * .03)))
{
g.DrawEllipse(outline, rectImg);
}
}
using (Pen darkRim = new Pen(Color.SlateGray))
{
g.DrawEllipse(darkRim, x, y, width, height);
}
// Draw Callibration
DrawCalibration(g, rectImg, ((width) / 2) + x, ((height) / 2) + y);
// Draw Colored Rim
int gap = (int)(this.Width * 0.03F);
Rectangle rectg = new Rectangle(rectImg.X + gap, rectImg.Y + gap, rectImg.Width - (gap * 2), rectImg.Height - (gap * 2));
using (Pen colorPen = new Pen(Color.FromArgb(190, Color.Gainsboro), this.Width / 40))
{
g.DrawArc(colorPen, rectg, 135, 270);
}
// Drawing in opposite order of importance to allow the most important
// zones to overwrite the zones of lesser importance in case there
// is an overlap.
// Draw Recommended zone
using (Pen colorPen = new Pen(Color.FromArgb(200, Color.LawnGreen), this.Width / 50))
{
drawColorZone(g, gap, rectg, colorPen, this.recommendedValueMin, this.recommendedValueMax);
}
// Draw Blue zone
using (Pen colorPen = new Pen(Color.FromArgb(200, Color.Blue), this.Width / 50))
{
drawColorZone(g, gap, rectg, colorPen, this.blueValueMin, this.blueValueMax);
}
// Draw Yellow zone
using (Pen colorPen = new Pen(Color.FromArgb(200, Color.Yellow), this.Width / 50))
{
drawColorZone(g, gap, rectg, colorPen, this.yellowValueMin, this.yellowValueMax);
}
// Draw Red2 zone
using (Pen colorPen = new Pen(Color.FromArgb(200, Color.Red), this.Width / 50))
{
drawColorZone(g, gap, rectg, colorPen, this.red2ValueMin, this.red2ValueMax);
}
// Draw Red1 zone
using (Pen colorPen = new Pen(Color.FromArgb(200, Color.Red), this.Width / 50))
{
drawColorZone(g, gap, rectg, colorPen, this.red1ValueMin, this.red1ValueMax);
}
// Draw Digital Value
RectangleF digiRect = new RectangleF((float)(this.Width / 2F) - (float)(this.width / 5F), (float)this.height / 1.22F, (float)this.width / 2.5F, (float)this.Height / 9F);
using (SolidBrush digiBrush = new SolidBrush(Color.FromArgb(30, Color.Gray)))
{
g.FillRectangle(digiBrush, digiRect);
}
drawText(g, this.dialText, (int)(this.height / 1.5));
drawText(g, this.digitalGaugeText, (int)(this.height / 1.07));
requiresRedraw = false;
}
e.Graphics.DrawImage(backgroundImg, rectImg);
}
}
#endregion
#region Private methods
///
/// Converts the given degree to radian.
///
/// Degree value.
/// Radian value.
private static float GetRadian(float theta)
{
return theta * (float)Math.PI / 180F;
}
///
/// Gets Relative X for the given width to draw digit
///
/// X to convert.
/// Width value.
/// Converted value.
private static float GetX(float itemX, float itemWidth)
{
return itemX * itemWidth / 12;
}
///
/// Gets relative Y for the given height to draw digit
///
/// Y to convert.
/// Height value.
/// Converted value.
private static float GetY(float itemY, float itemHeight)
{
return itemY * itemHeight / 15;
}
///
/// Returns true if a given number is available in the given list.
///
/// Number to look for.
/// List to look in.
/// 'true' if number exists.
private static bool IsNumberAvailable(int number, params int[] listOfNumbers)
{
if (listOfNumbers.Length > 0)
{
foreach (int i in listOfNumbers)
{
if (i == number)
return true;
}
}
return false;
}
///
/// Draw text string.
///
/// Graphics instance.
/// Text to draw.
/// Y-position for text.
private void drawText(Graphics g, string text, int yText)
{
SizeF textSize = g.MeasureString(text, this.Font);
RectangleF digiFRectText = new RectangleF((this.Width / 2) - (textSize.Width / 2), yText, textSize.Width, textSize.Height);
using (SolidBrush digiFBrush = new SolidBrush(this.ForeColor))
{
g.DrawString(text, this.Font, digiFBrush, digiFRectText);
}
}
///
/// Draws zoning band.
///
/// Graphics instance.
/// Gap value.
/// Rectangle covered.
/// Color of band.
/// Value for start of band
/// Value for end of band
private void drawColorZone(Graphics g, int gap, Rectangle rectg, Pen colorPen, float minThreshValue, float maxThreshValue)
{
// Only go through the calculations if necessary.
if (maxThreshValue > minThreshValue)
{
rectg = new Rectangle(rectImg.X + gap, rectImg.Y + gap, rectImg.Width - (gap * 2), rectImg.Height - (gap * 2));
float val = MaxValue - MinValue;
float stAngle = (100 * (minThreshValue - MinValue)) / val;
stAngle = ((toAngle - fromAngle) * stAngle) / 100;
stAngle += fromAngle;
float endAngle = (100 * (maxThreshValue - MinValue)) / val;
endAngle = ((toAngle - fromAngle) * endAngle) / 100;
endAngle += fromAngle;
float sweepAngle = endAngle - stAngle;
g.DrawArc(colorPen, rectg, stAngle, sweepAngle);
}
}
///
/// Draws the Pointer.
///
/// Graphics instance.
/// X coordinate.
/// Y coordinate.
private void DrawPointer(Graphics gr, int cx, int cy)
{
float radius = (this.Width / 2) - (this.Width * .12F);
float val = MaxValue - MinValue;
using (Image img = new Bitmap(this.Width, this.Height))
{
Graphics g = Graphics.FromImage(img);
g.SmoothingMode = SmoothingMode.AntiAlias;
val = (100 * (this.currentValue - MinValue)) / val;
val = ((toAngle - fromAngle) * val) / 100;
val += fromAngle;
float angle = GetRadian(val);
PointF[] pts = new PointF[5];
pts[0].X = (float)(cx + (radius * Math.Cos(angle)));
pts[0].Y = (float)(cy + (radius * Math.Sin(angle)));
pts[4].X = (float)(cx + (radius * Math.Cos(angle - 0.02)));
pts[4].Y = (float)(cy + (radius * Math.Sin(angle - 0.02)));
angle = GetRadian((val + 20));
pts[1].X = (float)(cx + ((this.Width * .09F) * Math.Cos(angle)));
pts[1].Y = (float)(cy + ((this.Width * .09F) * Math.Sin(angle)));
pts[2].X = cx;
pts[2].Y = cy;
angle = GetRadian((val - 20));
pts[3].X = (float)(cx + ((this.Width * .09F) * Math.Cos(angle)));
pts[3].Y = (float)(cy + ((this.Width * .09F) * Math.Sin(angle)));
using (Brush pointer = new SolidBrush(Color.Black))
{
g.FillPolygon(pointer, pts);
}
PointF[] shinePts = new PointF[3];
angle = GetRadian(val);
shinePts[0].X = (float)(cx + (radius * Math.Cos(angle)));
shinePts[0].Y = (float)(cy + (radius * Math.Sin(angle)));
angle = GetRadian(val + 20);
shinePts[1].X = (float)(cx + ((this.Width * .09F) * Math.Cos(angle)));
shinePts[1].Y = (float)(cy + ((this.Width * .09F) * Math.Sin(angle)));
shinePts[2].X = cx;
shinePts[2].Y = cy;
using (LinearGradientBrush gpointer = new LinearGradientBrush(shinePts[0], shinePts[2], Color.SlateGray, Color.Black))
{
g.FillPolygon(gpointer, shinePts);
}
Rectangle rect = new Rectangle(x, y, width, height);
DrawCenterPoint(g, rect, ((width) / 2) + x, ((height) / 2) + y);
DrawGloss(g);
gr.DrawImage(img, 0, 0);
}
}
///
/// Draws the glossiness.
///
/// Graphics instance.
private void DrawGloss(Graphics g)
{
RectangleF glossRect = new RectangleF(
x + (float)(width * 0.10),
y + (float)(height * 0.07),
(float)(width * 0.80),
(float)(height * 0.7));
using (LinearGradientBrush gradientBrush =
new LinearGradientBrush(
glossRect,
Color.FromArgb((int)glossinessAlpha, Color.White),
Color.Transparent,
LinearGradientMode.Vertical))
{
g.FillEllipse(gradientBrush, glossRect);
}
glossRect = new RectangleF(
x + (float)(width * 0.25),
y + (float)(height * 0.77),
(float)(width * 0.50),
(float)(height * 0.2));
int gloss = (int)(glossinessAlpha / 3);
using (LinearGradientBrush gradientBrush =
new LinearGradientBrush(
glossRect,
Color.Transparent,
Color.FromArgb(gloss, this.BackColor),
LinearGradientMode.Vertical))
{
g.FillEllipse(gradientBrush, glossRect);
}
}
///
/// Draws the center point.
///
/// Graphics instance.
/// Drawing rectangle.
/// Center X.
/// Center Y.
private void DrawCenterPoint(Graphics g, Rectangle rect, int cX, int cY)
{
float shift = Width / 5;
RectangleF rectangle = new RectangleF(cX - (shift / 2), cY - (shift / 2), shift, shift);
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Black, Color.FromArgb(100, this.dialColor), LinearGradientMode.Vertical))
{
g.FillEllipse(brush, rectangle);
shift = Width / 7;
rectangle = new RectangleF(cX - (shift / 2), cY - (shift / 2), shift, shift);
}
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.SlateGray, Color.Black, LinearGradientMode.ForwardDiagonal))
{
g.FillEllipse(brush, rectangle);
}
}
///
/// Draws the Ruler
///
/// Graphics instance.
/// Drawing rectangle.
/// Center X.
/// Center Y.
private void DrawCalibration(Graphics g, Rectangle rect, int cX, int cY)
{
uint noOfParts = this.noOfDivisions + 1;
uint noOfIntermediates = this.noOfSubDivisions;
float currentAngle = GetRadian(fromAngle);
int gap = (int)(this.Width * 0.01F);
float shift = this.Width / 25;
Rectangle rectangle = new Rectangle(rect.Left + gap, rect.Top + gap, rect.Width - gap, rect.Height - gap);
float itemX, itemY, itemX1, itemY1, itemTX, itemTY, radius;
radius = (rectangle.Width / 2) - (gap * 5);
float totalAngle = toAngle - fromAngle;
float incr = GetRadian(((totalAngle) / ((noOfParts - 1) * (noOfIntermediates + 1))));
using (Pen thickPen = new Pen(Color.Black, Width / 50))
{
using (Pen thinPen = new Pen(Color.Black, Width / 100))
{
using (StringFormat strFormat = new StringFormat(StringFormatFlags.NoClip))
{
strFormat.Alignment = StringAlignment.Center;
using (Font f = new Font(this.Font.FontFamily, (float)(this.Width / 23), this.Font.Style))
{
using (Brush stringPen = new SolidBrush(this.ForeColor))
{
float rulerValue = MinValue;
for (int i = 0; i <= noOfParts; i++)
{
// Draw Thick Line
itemX = (float)(cX + (radius * Math.Cos(currentAngle)));
itemY = (float)(cY + (radius * Math.Sin(currentAngle)));
itemX1 = (float)(cX + ((radius - (Width / 20)) * Math.Cos(currentAngle)));
itemY1 = (float)(cY + ((radius - (Width / 20)) * Math.Sin(currentAngle)));
g.DrawLine(thickPen, itemX, itemY, itemX1, itemY1);
// Draw Strings
itemTX = (float)(cX + ((radius - (Width / 10)) * Math.Cos(currentAngle)));
itemTY = (float)(cY - shift + ((radius - (Width / 10)) * Math.Sin(currentAngle)));
g.DrawString(rulerValue.ToString(CultureInfo.CurrentCulture), f, stringPen, new PointF(itemTX, itemTY), strFormat);
rulerValue += (float)((MaxValue - MinValue) / (noOfParts - 1));
rulerValue = (float)Math.Round(rulerValue, 2);
// currentAngle += incr;
if (i == noOfParts - 1)
break;
for (int j = 0; j <= noOfIntermediates; j++)
{
// Draw thin lines
currentAngle += incr;
itemX = (float)(cX + (radius * Math.Cos(currentAngle)));
itemY = (float)(cY + (radius * Math.Sin(currentAngle)));
itemX1 = (float)(cX + ((radius - (Width / 50)) * Math.Cos(currentAngle)));
itemY1 = (float)(cY + ((radius - (Width / 50)) * Math.Sin(currentAngle)));
g.DrawLine(thinPen, itemX, itemY, itemX1, itemY1);
}
}
}
}
}
}
}
}
///
/// Displays the given number in the 7-Segement format.
///
/// Graphics instance.
/// Number to draw.
/// Containing Rectangle
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Windows.Forms.MessageBox.Show(System.String)", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")]
private void DisplayNumber(Graphics g, float number, RectangleF drect)
{
try
{
string num = number.ToString(this.digitMask, CultureInfo.InvariantCulture);
num = num.PadLeft(3, '0');
float shift = 0;
if (number < 0)
{
shift -= width / 17;
}
char[] chars = num.ToCharArray();
for (int i = 0; i < chars.Length; i++)
{
char c = chars[i];
bool drawDPS = (i < chars.Length - 1 && chars[i + 1] == '.');
if (c != '.')
{
if (c == '-')
{
DrawDigit(g, -1, new PointF(drect.X + shift, drect.Y), drawDPS, drect.Height);
}
else
{
if (c >= '0' && c <= '9')
{
int val = (int)c - '0';
DrawDigit(g, val, new PointF(drect.X + shift, drect.Y), drawDPS, drect.Height);
}
}
shift += 15 * this.width / 250;
}
else
{
shift += 2 * this.width / 250;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.GetType().ToString() + ": " + ex.Message);
}
}
///
/// Draws a digit in 7-Segement format.
///
/// Graphics instance.
/// Number to draw.
/// Position for item.
/// Decimal point.
/// Height of digit.
private void DrawDigit(Graphics g, int number, PointF position, bool dp, float digitHeight)
{
float digitWidth = 10F * digitHeight / 13;
// Segment A
PointF[] segmentA = new PointF[5];
segmentA[0] = segmentA[4] = new PointF(position.X + GetX(2.8F, digitWidth), position.Y + GetY(1F, digitHeight));
segmentA[1] = new PointF(position.X + GetX(10, digitWidth), position.Y + GetY(1F, digitHeight));
segmentA[2] = new PointF(position.X + GetX(8.8F, digitWidth), position.Y + GetY(2F, digitHeight));
segmentA[3] = new PointF(position.X + GetX(3.8F, digitWidth), position.Y + GetY(2F, digitHeight));
// Segment B
PointF[] segmentB = new PointF[5];
segmentB[0] = segmentB[4] = new PointF(position.X + GetX(10, digitWidth), position.Y + GetY(1.4F, digitHeight));
segmentB[1] = new PointF(position.X + GetX(9.3F, digitWidth), position.Y + GetY(6.8F, digitHeight));
segmentB[2] = new PointF(position.X + GetX(8.4F, digitWidth), position.Y + GetY(6.4F, digitHeight));
segmentB[3] = new PointF(position.X + GetX(9F, digitWidth), position.Y + GetY(2.2F, digitHeight));
// Segment C
PointF[] segmentC = new PointF[5];
segmentC[0] = segmentC[4] = new PointF(position.X + GetX(9.2F, digitWidth), position.Y + GetY(7.2F, digitHeight));
segmentC[1] = new PointF(position.X + GetX(8.7F, digitWidth), position.Y + GetY(12.7F, digitHeight));
segmentC[2] = new PointF(position.X + GetX(7.6F, digitWidth), position.Y + GetY(11.9F, digitHeight));
segmentC[3] = new PointF(position.X + GetX(8.2F, digitWidth), position.Y + GetY(7.7F, digitHeight));
// Segment D
PointF[] segmentD = new PointF[5];
segmentD[0] = segmentD[4] = new PointF(position.X + GetX(7.4F, digitWidth), position.Y + GetY(12.1F, digitHeight));
segmentD[1] = new PointF(position.X + GetX(8.4F, digitWidth), position.Y + GetY(13F, digitHeight));
segmentD[2] = new PointF(position.X + GetX(1.3F, digitWidth), position.Y + GetY(13F, digitHeight));
segmentD[3] = new PointF(position.X + GetX(2.2F, digitWidth), position.Y + GetY(12.1F, digitHeight));
// Segment E
PointF[] segmentE = new PointF[5];
segmentE[0] = segmentE[4] = new PointF(position.X + GetX(2.2F, digitWidth), position.Y + GetY(11.8F, digitHeight));
segmentE[1] = new PointF(position.X + GetX(1F, digitWidth), position.Y + GetY(12.7F, digitHeight));
segmentE[2] = new PointF(position.X + GetX(1.7F, digitWidth), position.Y + GetY(7.2F, digitHeight));
segmentE[3] = new PointF(position.X + GetX(2.8F, digitWidth), position.Y + GetY(7.7F, digitHeight));
// Segment F
PointF[] segmentF = new PointF[5];
segmentF[0] = segmentF[4] = new PointF(position.X + GetX(3F, digitWidth), position.Y + GetY(6.4F, digitHeight));
segmentF[1] = new PointF(position.X + GetX(1.8F, digitWidth), position.Y + GetY(6.8F, digitHeight));
segmentF[2] = new PointF(position.X + GetX(2.6F, digitWidth), position.Y + GetY(1.3F, digitHeight));
segmentF[3] = new PointF(position.X + GetX(3.6F, digitWidth), position.Y + GetY(2.2F, digitHeight));
// Segment G
PointF[] segmentG = new PointF[7];
segmentG[0] = segmentG[6] = new PointF(position.X + GetX(2F, digitWidth), position.Y + GetY(7F, digitHeight));
segmentG[1] = new PointF(position.X + GetX(3.1F, digitWidth), position.Y + GetY(6.5F, digitHeight));
segmentG[2] = new PointF(position.X + GetX(8.3F, digitWidth), position.Y + GetY(6.5F, digitHeight));
segmentG[3] = new PointF(position.X + GetX(9F, digitWidth), position.Y + GetY(7F, digitHeight));
segmentG[4] = new PointF(position.X + GetX(8.2F, digitWidth), position.Y + GetY(7.5F, digitHeight));
segmentG[5] = new PointF(position.X + GetX(2.9F, digitWidth), position.Y + GetY(7.5F, digitHeight));
using (Pen outline = new Pen(Color.FromArgb(40, this.dialColor)))
{
// Segment DP
g.FillPolygon(outline.Brush, segmentA);
g.FillPolygon(outline.Brush, segmentB);
g.FillPolygon(outline.Brush, segmentC);
g.FillPolygon(outline.Brush, segmentD);
g.FillPolygon(outline.Brush, segmentE);
g.FillPolygon(outline.Brush, segmentF);
g.FillPolygon(outline.Brush, segmentG);
}
using (Pen fillPen = new Pen(Color.Black))
{
// Fill SegmentA
if (IsNumberAvailable(number, 0, 2, 3, 5, 6, 7, 8, 9))
{
g.FillPolygon(fillPen.Brush, segmentA);
}
// Fill SegmentB
if (IsNumberAvailable(number, 0, 1, 2, 3, 4, 7, 8, 9))
{
g.FillPolygon(fillPen.Brush, segmentB);
}
// Fill SegmentC
if (IsNumberAvailable(number, 0, 1, 3, 4, 5, 6, 7, 8, 9))
{
g.FillPolygon(fillPen.Brush, segmentC);
}
// Fill SegmentD
if (IsNumberAvailable(number, 0, 2, 3, 5, 6, 8, 9))
{
g.FillPolygon(fillPen.Brush, segmentD);
}
// Fill SegmentE
if (IsNumberAvailable(number, 0, 2, 6, 8))
{
g.FillPolygon(fillPen.Brush, segmentE);
}
// Fill SegmentF
if (IsNumberAvailable(number, 0, 4, 5, 6, 7, 8, 9))
{
g.FillPolygon(fillPen.Brush, segmentF);
}
// Fill SegmentG
if (IsNumberAvailable(number, 2, 3, 4, 5, 6, 8, 9, -1))
{
g.FillPolygon(fillPen.Brush, segmentG);
}
// Draw decimal point
if (dp)
{
g.FillEllipse(
fillPen.Brush,
new RectangleF(
position.X + GetX(10F, digitWidth),
position.Y + GetY(12F, digitHeight),
digitWidth / 7,
digitWidth / 7));
}
}
}
///
/// Restricts the size to make sure the height and width are always same.
///
/// Sending object.
/// Event data.
private void AquaGauge_Resize(object sender, EventArgs e)
{
if (this.Width < 136)
{
this.Width = 136;
}
if (oldWidth != this.Width)
{
this.Height = this.Width;
oldHeight = this.Width;
}
if (oldHeight != this.Height)
{
this.Width = this.Height;
oldWidth = this.Width;
}
}
#endregion
}
}