corrade-vassal – Blame information for rev 12

Subversion Repositories:
Rev:
Rev Author Line No. Line
12 zed 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Text;
7 using System.Windows.Forms;
8 using System.Drawing.Drawing2D;
9  
10 namespace AquaControls
11 {
12 /// <summary>
13 /// Aqua Gauge Control - A Windows User Control.
14 /// Author : Ambalavanar Thirugnanam
15 /// Date : 24th August 2007
16 /// email : ambalavanar.thiru@gmail.com
17 /// This is control is for free. You can use for any commercial or non-commercial purposes.
18 /// [Please do no remove this header when using this control in your application.]
19 /// </summary>
20 public partial class AquaGauge : UserControl
21 {
22 #region Private Attributes
23 private float minValue;
24 private float maxValue;
25 private float threshold;
26 private float currentValue;
27 private float recommendedValue;
28 private int noOfDivisions;
29 private int noOfSubDivisions;
30 private string dialText;
31 private Color dialColor = Color.Lavender;
32 private float glossinessAlpha = 25;
33 private int oldWidth, oldHeight;
34 int x, y, width, height;
35 float fromAngle = 135F;
36 float toAngle = 405F;
37 private bool enableTransparentBackground;
38 private bool requiresRedraw;
39 private Image backgroundImg;
40 private Rectangle rectImg;
41 #endregion
42  
43 public AquaGauge()
44 {
45 InitializeComponent();
46 x = 5;
47 y = 5;
48 width = this.Width - 10;
49 height = this.Height - 10;
50 this.noOfDivisions = 10;
51 this.noOfSubDivisions = 3;
52 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
53 this.SetStyle(ControlStyles.ResizeRedraw, true);
54 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
55 this.SetStyle(ControlStyles.UserPaint, true);
56 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
57 this.BackColor = Color.Transparent;
58 this.Resize += new EventHandler(AquaGauge_Resize);
59 this.requiresRedraw = true;
60 }
61  
62 #region Public Properties
63 /// <summary>
64 /// Mininum value on the scale
65 /// </summary>
66 [DefaultValue(0)]
67 [Description("Mininum value on the scale")]
68 public float MinValue
69 {
70 get { return minValue; }
71 set
72 {
73 if (value < maxValue)
74 {
75 minValue = value;
76 if (currentValue < minValue)
77 currentValue = minValue;
78 if (recommendedValue < minValue)
79 recommendedValue = minValue;
80 requiresRedraw = true;
81 this.Invalidate();
82 }
83 }
84 }
85  
86 /// <summary>
87 /// Maximum value on the scale
88 /// </summary>
89 [DefaultValue(100)]
90 [Description("Maximum value on the scale")]
91 public float MaxValue
92 {
93 get { return maxValue; }
94 set
95 {
96 if (value > minValue)
97 {
98 maxValue = value;
99 if (currentValue > maxValue)
100 currentValue = maxValue;
101 if (recommendedValue > maxValue)
102 recommendedValue = maxValue;
103 requiresRedraw = true;
104 this.Invalidate();
105 }
106 }
107 }
108  
109 /// <summary>
110 /// Gets or Sets the Threshold area from the Recommended Value. (1-99%)
111 /// </summary>
112 [DefaultValue(25)]
113 [Description("Gets or Sets the Threshold area from the Recommended Value. (1-99%)")]
114 public float ThresholdPercent
115 {
116 get { return threshold; }
117 set
118 {
119 if (value > 0 && value < 100)
120 {
121 threshold = value;
122 requiresRedraw = true;
123 this.Invalidate();
124 }
125 }
126 }
127  
128 /// <summary>
129 /// Threshold value from which green area will be marked.
130 /// </summary>
131 [DefaultValue(25)]
132 [Description("Threshold value from which green area will be marked.")]
133 public float RecommendedValue
134 {
135 get { return recommendedValue; }
136 set
137 {
138 if (value > minValue && value < maxValue)
139 {
140 recommendedValue = value;
141 requiresRedraw = true;
142 this.Invalidate();
143 }
144 }
145 }
146  
147 /// <summary>
148 /// Value where the pointer will point to.
149 /// </summary>
150 [DefaultValue(0)]
151 [Description("Value where the pointer will point to.")]
152 public float Value
153 {
154 get { return currentValue; }
155 set
156 {
157 if (value >= minValue && value <= maxValue)
158 {
159 currentValue = value;
160 this.Refresh();
161 }
162 }
163 }
164  
165 /// <summary>
166 /// Background color of the dial
167 /// </summary>
168 [Description("Background color of the dial")]
169 public Color DialColor
170 {
171 get { return dialColor; }
172 set
173 {
174 dialColor = value;
175 requiresRedraw = true;
176 this.Invalidate();
177 }
178 }
179  
180 /// <summary>
181 /// Glossiness strength. Range: 0-100
182 /// </summary>
183 [DefaultValue(72)]
184 [Description("Glossiness strength. Range: 0-100")]
185 public float Glossiness
186 {
187 get
188 {
189 return (glossinessAlpha * 100) / 220;
190 }
191 set
192 {
193 float val = value;
194 if(val > 100)
195 value = 100;
196 if(val < 0)
197 value = 0;
198 glossinessAlpha = (value * 220) / 100;
199 this.Refresh();
200 }
201 }
202  
203 /// <summary>
204 /// Get or Sets the number of Divisions in the dial scale.
205 /// </summary>
206 [DefaultValue(10)]
207 [Description("Get or Sets the number of Divisions in the dial scale.")]
208 public int NoOfDivisions
209 {
210 get { return this.noOfDivisions; }
211 set
212 {
213 if (value > 1 && value < 25)
214 {
215 this.noOfDivisions = value;
216 requiresRedraw = true;
217 this.Invalidate();
218 }
219 }
220 }
221  
222 /// <summary>
223 /// Gets or Sets the number of Sub Divisions in the scale per Division.
224 /// </summary>
225 [DefaultValue(3)]
226 [Description("Gets or Sets the number of Sub Divisions in the scale per Division.")]
227 public int NoOfSubDivisions
228 {
229 get { return this.noOfSubDivisions; }
230 set
231 {
232 if (value > 0 && value <= 10)
233 {
234 this.noOfSubDivisions = value;
235 requiresRedraw = true;
236 this.Invalidate();
237 }
238 }
239 }
240  
241 /// <summary>
242 /// Gets or Sets the Text to be displayed in the dial
243 /// </summary>
244 [Description("Gets or Sets the Text to be displayed in the dial")]
245 public string DialText
246 {
247 get { return this.dialText; }
248 set
249 {
250 this.dialText = value;
251 requiresRedraw = true;
252 this.Invalidate();
253 }
254 }
255  
256 /// <summary>
257 /// Enables or Disables Transparent Background color.
258 /// Note: Enabling this will reduce the performance and may make the control flicker.
259 /// </summary>
260 [DefaultValue(false)]
261 [Description("Enables or Disables Transparent Background color. Note: Enabling this will reduce the performance and may make the control flicker.")]
262 public bool EnableTransparentBackground
263 {
264 get { return this.enableTransparentBackground; }
265 set
266 {
267 this.enableTransparentBackground = value;
268 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, !enableTransparentBackground);
269 requiresRedraw = true;
270 this.Refresh();
271 }
272 }
273 #endregion
274  
275 #region Overriden Control methods
276 /// <summary>
277 /// Draws the pointer.
278 /// </summary>
279 /// <param name="e"></param>
280 protected override void OnPaint(PaintEventArgs e)
281 {
282 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
283 width = this.Width - x*2;
284 height = this.Height - y*2;
285 DrawPointer(e.Graphics, ((width) / 2) + x, ((height) / 2) + y);
286 }
287  
288 /// <summary>
289 /// Draws the dial background.
290 /// </summary>
291 /// <param name="e"></param>
292 protected override void OnPaintBackground(PaintEventArgs e)
293 {
294 if (!enableTransparentBackground)
295 {
296 base.OnPaintBackground(e);
297 }
298  
299 e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
300 e.Graphics.FillRectangle(new SolidBrush(Color.Transparent), new Rectangle(0,0,Width,Height));
301 if (backgroundImg == null || requiresRedraw)
302 {
303 backgroundImg = new Bitmap(this.Width, this.Height);
304 Graphics g = Graphics.FromImage(backgroundImg);
305 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
306 width = this.Width - x * 2;
307 height = this.Height - y * 2;
308 rectImg = new Rectangle(x, y, width, height);
309  
310 //Draw background color
311 Brush backGroundBrush = new SolidBrush(Color.FromArgb(120, dialColor));
312 if (enableTransparentBackground && this.Parent != null)
313 {
314 float gg = width / 60;
315 //g.FillEllipse(new SolidBrush(this.Parent.BackColor), -gg, -gg, this.Width+gg*2, this.Height+gg*2);
316 }
317 g.FillEllipse(backGroundBrush, x, y, width, height);
318  
319 //Draw Rim
320 SolidBrush outlineBrush = new SolidBrush(Color.FromArgb(100, Color.SlateGray));
321 Pen outline = new Pen(outlineBrush, (float)(width * .03));
322 g.DrawEllipse(outline, rectImg);
323 Pen darkRim = new Pen(Color.SlateGray);
324 g.DrawEllipse(darkRim, x, y, width, height);
325  
326 //Draw Callibration
327 DrawCalibration(g, rectImg, ((width) / 2) + x, ((height) / 2) + y);
328  
329 //Draw Colored Rim
330 Pen colorPen = new Pen(Color.FromArgb(190, Color.Gainsboro), this.Width / 40);
331 Pen blackPen = new Pen(Color.FromArgb(250, Color.Black), this.Width / 200);
332 int gap = (int)(this.Width * 0.03F);
333 Rectangle rectg = new Rectangle(rectImg.X + gap, rectImg.Y + gap, rectImg.Width - gap * 2, rectImg.Height - gap * 2);
334 g.DrawArc(colorPen, rectg, 135, 270);
335  
336 //Draw Threshold
337 colorPen = new Pen(Color.FromArgb(200, Color.LawnGreen), this.Width / 50);
338 rectg = new Rectangle(rectImg.X + gap, rectImg.Y + gap, rectImg.Width - gap * 2, rectImg.Height - gap * 2);
339 float val = MaxValue - MinValue;
340 val = (100 * (this.recommendedValue - MinValue)) / val;
341 val = ((toAngle - fromAngle) * val) / 100;
342 val += fromAngle;
343 float stAngle = val - ((270 * threshold) / 200);
344 if (stAngle <= 135) stAngle = 135;
345 float sweepAngle = ((270 * threshold) / 100);
346 if (stAngle + sweepAngle > 405) sweepAngle = 405 - stAngle;
347 g.DrawArc(colorPen, rectg, stAngle, sweepAngle);
348  
349 //Draw Digital Value
350 /* RectangleF digiRect = new RectangleF((float)this.Width / 2F - (float)this.width / 5F, (float)this.height / 1.2F, (float)this.width / 2.5F, (float)this.Height / 9F);
351 RectangleF digiFRect = new RectangleF(this.Width / 2 - this.width / 7, (int)(this.height / 1.18), this.width / 4, this.Height / 12);
352 g.FillRectangle(new SolidBrush(Color.FromArgb(30, Color.Gray)), digiRect);
353 DisplayNumber(g, this.currentValue, digiFRect); */
354  
355 SizeF textSize = g.MeasureString(this.dialText, this.Font);
356 RectangleF digiFRectText = new RectangleF(this.Width / 2 - textSize.Width / 2, (int)(this.height / 1.5), textSize.Width, textSize.Height);
357 g.DrawString(dialText, this.Font, new SolidBrush(this.ForeColor), digiFRectText);
358 requiresRedraw = false;
359 }
360 e.Graphics.DrawImage(backgroundImg, rectImg);
361 }
362  
363 protected override CreateParams CreateParams
364 {
365 get
366 {
367 CreateParams cp = base.CreateParams;
368 cp.ExStyle |= 0x20;
369 return cp;
370 }
371 }
372 #endregion
373  
374 #region Private methods
375 /// <summary>
376 /// Draws the Pointer.
377 /// </summary>
378 /// <param name="gr"></param>
379 /// <param name="cx"></param>
380 /// <param name="cy"></param>
381 private void DrawPointer(Graphics gr, int cx, int cy)
382 {
383 float radius = this.Width / 2 - (this.Width * .12F);
384 float val = MaxValue - MinValue;
385  
386 Image img = new Bitmap(this.Width, this.Height);
387 Graphics g = Graphics.FromImage(img);
388 g.SmoothingMode = SmoothingMode.AntiAlias;
389  
390 val = (100 * (this.currentValue - MinValue)) / val;
391 val = ((toAngle - fromAngle) * val) / 100;
392 val += fromAngle;
393  
394 float angle = GetRadian(val);
395 float gradientAngle = angle;
396  
397 PointF[] pts = new PointF[5];
398  
399 pts[0].X = (float)(cx + radius * Math.Cos(angle));
400 pts[0].Y = (float)(cy + radius * Math.Sin(angle));
401  
402 pts[4].X = (float)(cx + radius * Math.Cos(angle - 0.02));
403 pts[4].Y = (float)(cy + radius * Math.Sin(angle - 0.02));
404  
405 angle = GetRadian((val + 20));
406 pts[1].X = (float)(cx + (this.Width * .09F) * Math.Cos(angle));
407 pts[1].Y = (float)(cy + (this.Width * .09F) * Math.Sin(angle));
408  
409 pts[2].X = cx;
410 pts[2].Y = cy;
411  
412 angle = GetRadian((val - 20));
413 pts[3].X = (float)(cx + (this.Width * .09F) * Math.Cos(angle));
414 pts[3].Y = (float)(cy + (this.Width * .09F) * Math.Sin(angle));
415  
416 Brush pointer = new SolidBrush(Color.Black);
417 g.FillPolygon(pointer, pts);
418  
419 PointF[] shinePts = new PointF[3];
420 angle = GetRadian(val);
421 shinePts[0].X = (float)(cx + radius * Math.Cos(angle));
422 shinePts[0].Y = (float)(cy + radius * Math.Sin(angle));
423  
424 angle = GetRadian(val + 20);
425 shinePts[1].X = (float)(cx + (this.Width * .09F) * Math.Cos(angle));
426 shinePts[1].Y = (float)(cy + (this.Width * .09F) * Math.Sin(angle));
427  
428 shinePts[2].X = cx;
429 shinePts[2].Y = cy;
430  
431 LinearGradientBrush gpointer = new LinearGradientBrush(shinePts[0], shinePts[2], Color.SlateGray, Color.Black);
432 g.FillPolygon(gpointer, shinePts);
433  
434 Rectangle rect = new Rectangle(x, y, width, height);
435 DrawCenterPoint(g, rect, ((width) / 2) + x, ((height) / 2) + y);
436  
437 DrawGloss(g);
438  
439 gr.DrawImage(img, 0, 0);
440 }
441  
442 /// <summary>
443 /// Draws the glossiness.
444 /// </summary>
445 /// <param name="g"></param>
446 private void DrawGloss(Graphics g)
447 {
448 RectangleF glossRect = new RectangleF(
449 x + (float)(width * 0.10),
450 y + (float)(height * 0.07),
451 (float)(width * 0.80),
452 (float)(height * 0.7));
453 LinearGradientBrush gradientBrush =
454 new LinearGradientBrush(glossRect,
455 Color.FromArgb((int)glossinessAlpha, Color.White),
456 Color.Transparent,
457 LinearGradientMode.Vertical);
458 g.FillEllipse(gradientBrush, glossRect);
459  
460 //TODO: Gradient from bottom
461 glossRect = new RectangleF(
462 x + (float)(width * 0.25),
463 y + (float)(height * 0.77),
464 (float)(width * 0.50),
465 (float)(height * 0.2));
466 int gloss = (int)(glossinessAlpha / 3);
467 gradientBrush =
468 new LinearGradientBrush(glossRect,
469 Color.Transparent, Color.FromArgb(gloss, this.BackColor),
470 LinearGradientMode.Vertical);
471 g.FillEllipse(gradientBrush, glossRect);
472 }
473  
474 /// <summary>
475 /// Draws the center point.
476 /// </summary>
477 /// <param name="g"></param>
478 /// <param name="rect"></param>
479 /// <param name="cX"></param>
480 /// <param name="cY"></param>
481 private void DrawCenterPoint(Graphics g, Rectangle rect, int cX, int cY)
482 {
483 float shift = Width / 5;
484 RectangleF rectangle = new RectangleF(cX - (shift / 2), cY - (shift / 2), shift, shift);
485 LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Black, Color.FromArgb(100,this.dialColor), LinearGradientMode.Vertical);
486 g.FillEllipse(brush, rectangle);
487  
488 shift = Width / 7;
489 rectangle = new RectangleF(cX - (shift / 2), cY - (shift / 2), shift, shift);
490 brush = new LinearGradientBrush(rect, Color.SlateGray, Color.Black, LinearGradientMode.ForwardDiagonal);
491 g.FillEllipse(brush, rectangle);
492 }
493  
494 /// <summary>
495 /// Draws the Ruler
496 /// </summary>
497 /// <param name="g"></param>
498 /// <param name="rect"></param>
499 /// <param name="cX"></param>
500 /// <param name="cY"></param>
501 private void DrawCalibration(Graphics g, Rectangle rect, int cX, int cY)
502 {
503 int noOfParts = this.noOfDivisions + 1;
504 int noOfIntermediates = this.noOfSubDivisions;
505 float currentAngle = GetRadian(fromAngle);
506 int gap = (int)(this.Width * 0.01F);
507 float shift = this.Width / 25;
508 Rectangle rectangle = new Rectangle(rect.Left + gap, rect.Top + gap, rect.Width - gap, rect.Height - gap);
509  
510 float x,y,x1,y1,tx,ty,radius;
511 radius = rectangle.Width/2 - gap*5;
512 float totalAngle = toAngle - fromAngle;
513 float incr = GetRadian(((totalAngle) / ((noOfParts - 1) * (noOfIntermediates + 1))));
514  
515 Pen thickPen = new Pen(Color.Black, Width/50);
516 Pen thinPen = new Pen(Color.Black, Width/100);
517 float rulerValue = MinValue;
518 for (int i = 0; i <= noOfParts; i++)
519 {
520 //Draw Thick Line
521 x = (float)(cX + radius * Math.Cos(currentAngle));
522 y = (float)(cY + radius * Math.Sin(currentAngle));
523 x1 = (float)(cX + (radius - Width/20) * Math.Cos(currentAngle));
524 y1 = (float)(cY + (radius - Width/20) * Math.Sin(currentAngle));
525 g.DrawLine(thickPen, x, y, x1, y1);
526  
527 //Draw Strings
528 StringFormat format = new StringFormat();
529 tx = (float)(cX + (radius - Width / 10) * Math.Cos(currentAngle));
530 ty = (float)(cY-shift + (radius - Width / 10) * Math.Sin(currentAngle));
531 Brush stringPen = new SolidBrush(this.ForeColor);
532 StringFormat strFormat = new StringFormat(StringFormatFlags.NoClip);
533 strFormat.Alignment = StringAlignment.Center;
534 Font f = new Font(this.Font.FontFamily, (float)(this.Width / 23), this.Font.Style);
535 g.DrawString(rulerValue.ToString() + "", f, stringPen, new PointF(tx, ty), strFormat);
536 rulerValue += (float)((MaxValue - MinValue) / (noOfParts - 1));
537 rulerValue = (float)Math.Round(rulerValue, 2);
538  
539 //currentAngle += incr;
540 if (i == noOfParts -1)
541 break;
542 for (int j = 0; j <= noOfIntermediates; j++)
543 {
544 //Draw thin lines
545 currentAngle += incr;
546 x = (float)(cX + radius * Math.Cos(currentAngle));
547 y = (float)(cY + radius * Math.Sin(currentAngle));
548 x1 = (float)(cX + (radius - Width/50) * Math.Cos(currentAngle));
549 y1 = (float)(cY + (radius - Width/50) * Math.Sin(currentAngle));
550 g.DrawLine(thinPen, x, y, x1, y1);
551 }
552 }
553 }
554  
555 /// <summary>
556 /// Converts the given degree to radian.
557 /// </summary>
558 /// <param name="theta"></param>
559 /// <returns></returns>
560 public float GetRadian(float theta)
561 {
562 return theta * (float)Math.PI / 180F;
563 }
564  
565 /// <summary>
566 /// Displays the given number in the 7-Segement format.
567 /// </summary>
568 /// <param name="g"></param>
569 /// <param name="number"></param>
570 /// <param name="drect"></param>
571 private void DisplayNumber(Graphics g, float number, RectangleF drect)
572 {
573 try
574 {
575 string num = number.ToString("000.00");
576 num.PadLeft(3, '0');
577 float shift = 0;
578 if (number < 0)
579 {
580 shift -= width/17;
581 }
582 bool drawDPS = false;
583 char[] chars = num.ToCharArray();
584 for (int i = 0; i < chars.Length; i++)
585 {
586 char c = chars[i];
587 if (i < chars.Length - 1 && chars[i + 1] == '.')
588 drawDPS = true;
589 else
590 drawDPS = false;
591 if (c != '.')
592 {
593 if (c == '-')
594 {
595 DrawDigit(g, -1, new PointF(drect.X + shift, drect.Y), drawDPS, drect.Height);
596 }
597 else
598 {
599 DrawDigit(g, int.Parse(c.ToString()), new PointF(drect.X + shift, drect.Y), drawDPS, drect.Height);
600 }
601 shift += 15 * this.width / 250f;
602 }
603 else
604 {
605 shift += 2 * this.width / 250f;
606 }
607 }
608 }
609 catch (Exception)
610 {
611 }
612 }
613  
614 /// <summary>
615 /// Draws a digit in 7-Segement format.
616 /// </summary>
617 /// <param name="g"></param>
618 /// <param name="number"></param>
619 /// <param name="position"></param>
620 /// <param name="dp"></param>
621 /// <param name="height"></param>
622 private void DrawDigit(Graphics g, int number, PointF position, bool dp, float height)
623 {
624 float width;
625 width = 10F * height/13;
626  
627 Pen outline = new Pen(Color.FromArgb(40, this.dialColor));
628 Pen fillPen = new Pen(Color.Black);
629  
630 #region Form Polygon Points
631 //Segment A
632 PointF[] segmentA = new PointF[5];
633 segmentA[0] = segmentA[4] = new PointF(position.X + GetX(2.8F, width), position.Y + GetY(1F, height));
634 segmentA[1] = new PointF(position.X + GetX(10, width), position.Y + GetY(1F, height));
635 segmentA[2] = new PointF(position.X + GetX(8.8F, width), position.Y + GetY(2F, height));
636 segmentA[3] = new PointF(position.X + GetX(3.8F, width), position.Y + GetY(2F, height));
637  
638 //Segment B
639 PointF[] segmentB = new PointF[5];
640 segmentB[0] = segmentB[4] = new PointF(position.X + GetX(10, width), position.Y + GetY(1.4F, height));
641 segmentB[1] = new PointF(position.X + GetX(9.3F, width), position.Y + GetY(6.8F, height));
642 segmentB[2] = new PointF(position.X + GetX(8.4F, width), position.Y + GetY(6.4F, height));
643 segmentB[3] = new PointF(position.X + GetX(9F, width), position.Y + GetY(2.2F, height));
644  
645 //Segment C
646 PointF[] segmentC = new PointF[5];
647 segmentC[0] = segmentC[4] = new PointF(position.X + GetX(9.2F, width), position.Y + GetY(7.2F, height));
648 segmentC[1] = new PointF(position.X + GetX(8.7F, width), position.Y + GetY(12.7F, height));
649 segmentC[2] = new PointF(position.X + GetX(7.6F, width), position.Y + GetY(11.9F, height));
650 segmentC[3] = new PointF(position.X + GetX(8.2F, width), position.Y + GetY(7.7F, height));
651  
652 //Segment D
653 PointF[] segmentD = new PointF[5];
654 segmentD[0] = segmentD[4] = new PointF(position.X + GetX(7.4F, width), position.Y + GetY(12.1F, height));
655 segmentD[1] = new PointF(position.X + GetX(8.4F, width), position.Y + GetY(13F, height));
656 segmentD[2] = new PointF(position.X + GetX(1.3F, width), position.Y + GetY(13F, height));
657 segmentD[3] = new PointF(position.X + GetX(2.2F, width), position.Y + GetY(12.1F, height));
658  
659 //Segment E
660 PointF[] segmentE = new PointF[5];
661 segmentE[0] = segmentE[4] = new PointF(position.X + GetX(2.2F, width), position.Y + GetY(11.8F, height));
662 segmentE[1] = new PointF(position.X + GetX(1F, width), position.Y + GetY(12.7F, height));
663 segmentE[2] = new PointF(position.X + GetX(1.7F, width), position.Y + GetY(7.2F, height));
664 segmentE[3] = new PointF(position.X + GetX(2.8F, width), position.Y + GetY(7.7F, height));
665  
666 //Segment F
667 PointF[] segmentF = new PointF[5];
668 segmentF[0] = segmentF[4] = new PointF(position.X + GetX(3F, width), position.Y + GetY(6.4F, height));
669 segmentF[1] = new PointF(position.X + GetX(1.8F, width), position.Y + GetY(6.8F, height));
670 segmentF[2] = new PointF(position.X + GetX(2.6F, width), position.Y + GetY(1.3F, height));
671 segmentF[3] = new PointF(position.X + GetX(3.6F, width), position.Y + GetY(2.2F, height));
672  
673 //Segment G
674 PointF[] segmentG = new PointF[7];
675 segmentG[0] = segmentG[6] = new PointF(position.X + GetX(2F, width), position.Y + GetY(7F, height));
676 segmentG[1] = new PointF(position.X + GetX(3.1F, width), position.Y + GetY(6.5F, height));
677 segmentG[2] = new PointF(position.X + GetX(8.3F, width), position.Y + GetY(6.5F, height));
678 segmentG[3] = new PointF(position.X + GetX(9F, width), position.Y + GetY(7F, height));
679 segmentG[4] = new PointF(position.X + GetX(8.2F, width), position.Y + GetY(7.5F, height));
680 segmentG[5] = new PointF(position.X + GetX(2.9F, width), position.Y + GetY(7.5F, height));
681  
682 //Segment DP
683 #endregion
684  
685 #region Draw Segments Outline
686 g.FillPolygon(outline.Brush, segmentA);
687 g.FillPolygon(outline.Brush, segmentB);
688 g.FillPolygon(outline.Brush, segmentC);
689 g.FillPolygon(outline.Brush, segmentD);
690 g.FillPolygon(outline.Brush, segmentE);
691 g.FillPolygon(outline.Brush, segmentF);
692 g.FillPolygon(outline.Brush, segmentG);
693 #endregion
694  
695 #region Fill Segments
696 //Fill SegmentA
697 if (IsNumberAvailable(number, 0, 2, 3, 5, 6, 7, 8, 9))
698 {
699 g.FillPolygon(fillPen.Brush, segmentA);
700 }
701  
702 //Fill SegmentB
703 if (IsNumberAvailable(number, 0, 1, 2, 3, 4, 7, 8, 9))
704 {
705 g.FillPolygon(fillPen.Brush, segmentB);
706 }
707  
708 //Fill SegmentC
709 if (IsNumberAvailable(number, 0, 1, 3, 4, 5, 6, 7, 8, 9))
710 {
711 g.FillPolygon(fillPen.Brush, segmentC);
712 }
713  
714 //Fill SegmentD
715 if (IsNumberAvailable(number, 0, 2, 3, 5, 6, 8, 9))
716 {
717 g.FillPolygon(fillPen.Brush, segmentD);
718 }
719  
720 //Fill SegmentE
721 if (IsNumberAvailable(number, 0, 2, 6, 8))
722 {
723 g.FillPolygon(fillPen.Brush, segmentE);
724 }
725  
726 //Fill SegmentF
727 if (IsNumberAvailable(number, 0, 4, 5, 6, 7, 8, 9))
728 {
729 g.FillPolygon(fillPen.Brush, segmentF);
730 }
731  
732 //Fill SegmentG
733 if (IsNumberAvailable(number, 2, 3, 4, 5, 6, 8, 9, -1))
734 {
735 g.FillPolygon(fillPen.Brush, segmentG);
736 }
737 #endregion
738  
739 //Draw decimal point
740 if (dp)
741 {
742 g.FillEllipse(fillPen.Brush, new RectangleF(
743 position.X + GetX(10F, width),
744 position.Y + GetY(12F, height),
745 width/7,
746 width/7));
747 }
748 }
749  
750 /// <summary>
751 /// Gets Relative X for the given width to draw digit
752 /// </summary>
753 /// <param name="x"></param>
754 /// <param name="width"></param>
755 /// <returns></returns>
756 private float GetX(float x, float width)
757 {
758 return x * width / 12;
759 }
760  
761 /// <summary>
762 /// Gets relative Y for the given height to draw digit
763 /// </summary>
764 /// <param name="y"></param>
765 /// <param name="height"></param>
766 /// <returns></returns>
767 private float GetY(float y, float height)
768 {
769 return y * height / 15;
770 }
771  
772 /// <summary>
773 /// Returns true if a given number is available in the given list.
774 /// </summary>
775 /// <param name="number"></param>
776 /// <param name="listOfNumbers"></param>
777 /// <returns></returns>
778 private bool IsNumberAvailable(int number, params int[] listOfNumbers)
779 {
780 if (listOfNumbers.Length > 0)
781 {
782 foreach (int i in listOfNumbers)
783 {
784 if (i == number)
785 return true;
786 }
787 }
788 return false;
789 }
790  
791 /// <summary>
792 /// Restricts the size to make sure the height and width are always same.
793 /// </summary>
794 /// <param name="sender"></param>
795 /// <param name="e"></param>
796 private void AquaGauge_Resize(object sender, EventArgs e)
797 {
798 if (this.Width < 136)
799 {
800 this.Width = 136;
801 }
802 if (oldWidth != this.Width)
803 {
804 this.Height = this.Width;
805 oldHeight = this.Width;
806 }
807 if (oldHeight != this.Height)
808 {
809 this.Width = this.Height;
810 oldWidth = this.Width;
811 }
812 }
813 #endregion
814 }
815 }