using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DesktopClockWidget
{
/// <summary>
/// Utility class for drawing clock
/// </summary>
public class ClockDrawings
{
#region Public section.
/// <summary>
/// Set graphics quality
/// </summary>
/// <param name="graphics">graphics object</param>
public static void SetGraphicsQuality(Graphics graphics)
{
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
}
/// <summary>
/// Draw the clock
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="hour">current hour - from 0 to 11</param>
/// <param name="minute">current minute - from 0 to 59</param>
/// <param name="font">font for drawing reference digits</param>
/// <param name="graphics">graphics object</param>
public static void DrawClock(Rectangle clockRectangle, float hour, float minute, Font font, Graphics graphics)
{
SetGraphicsQuality(graphics);
DrawClockBackground (clockRectangle, graphics);
DrawClockBorder (clockRectangle, graphics);
DrawReferenceDigits (clockRectangle, font, graphics);
DrawMinuteArrow (clockRectangle, minute, graphics);
DrawHourArrow (clockRectangle, hour % 12, minute, graphics);
DrawHourBullets (clockRectangle, graphics);
}
#endregion Public section.
#region Local section.
/// <summary>
/// Draws the clock background
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="graphics">graphics object</param>
private static void DrawClockBackground(Rectangle clockRectangle, Graphics graphics)
{
using (HatchBrush background = new HatchBrush(HatchStyle.Sphere, Color.Black, Color.FromArgb(40, 40, 40)))
{
graphics.FillEllipse(background, clockRectangle);
}
}
/// <summary>
/// Draw clock border
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="graphics">graphics</param>
private static void DrawClockBorder(Rectangle clockRectangle, Graphics graphics)
{
using (Pen outerBorderPen = new Pen(Color.FromArgb(70, 70, 70), 3))
{
graphics.DrawEllipse(outerBorderPen, clockRectangle);
}
using (Pen outerBorderPen = new Pen(Color.FromArgb(20, 20, 20), 7))
{
graphics.DrawEllipse(outerBorderPen, 5, 5, clockRectangle.Width - 9, clockRectangle.Height - 9);
}
graphics.DrawEllipse(Pens.Gray, 7, 7, clockRectangle.Width - 14, clockRectangle.Height - 15);
using (Pen outerBorderPen = new Pen(Color.FromArgb(1, 1, 1), 3))
{
graphics.DrawEllipse(outerBorderPen, 7, 7, clockRectangle.Width - 14, clockRectangle.Height - 12);
}
}
/// <summary>
/// Draw reference digits: 12, 3, 6, 9
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="font">font for drawing reference digits</param>
/// <param name="graphics">graphics object</param>
private static void DrawReferenceDigits(Rectangle clockRectangle, Font font, Graphics graphics)
{
int centerX = clockRectangle.Width / 2;
int centerY = clockRectangle.Height / 2;
float digitX = centerX + clockRectangle.Width / 2 - 25;
float digitY = centerY - 7;
float starX = centerX + clockRectangle.Width / 2 - 14;
float starY = centerY - 1;
graphics.DrawString("3", font, Brushes.LightBlue, digitX, digitY);
graphics.DrawEllipse(Pens.LightSteelBlue, starX, starY, 2, 2);
digitX = centerX - clockRectangle.Width / 2 + 16;
digitY = centerY - 7;
starX = centerX - clockRectangle.Width / 2 + 12;
starY = centerY - 1;
graphics.DrawString("9", font, Brushes.LightBlue, digitX, digitY);
graphics.DrawEllipse(Pens.LightSteelBlue, starX, starY, 2, 2);
digitX = centerX - 8;
digitY = centerY - clockRectangle.Width / 2 + 16;
starX = centerX - 1;
starY = centerY - clockRectangle.Width / 2 + 12;
graphics.DrawString("12", font, Brushes.LightBlue, digitX, digitY);
graphics.DrawEllipse(Pens.LightSteelBlue, starX, starY, 2, 2);
digitX = centerX - 4;
digitY = centerY + clockRectangle.Width / 2 - 29;
starX = centerX - 1;
starY = centerY + clockRectangle.Width / 2 - 14;
graphics.DrawString("6", font, Brushes.LightBlue, digitX, digitY);
graphics.DrawEllipse(Pens.LightSteelBlue, starX, starY, 2, 2);
}
/// <summary>
/// Draw minute arrow
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="minute">current minute - from 0 to 59</param>
/// <param name="graphics">graphics object</param>
private static void DrawMinuteArrow(Rectangle clockRectangle, float minute, Graphics graphics)
{
int centerX = clockRectangle.Width / 2;
int centerY = clockRectangle.Height / 2;
float minPos = minute / 60.0F;
graphics.TranslateTransform(centerX, centerY);
graphics.RotateTransform(270.0F + 360.0F * minPos);
graphics.DrawLine(Pens.DarkBlue, -8, -1, 0 + clockRectangle.Width / 2 - 21, -1);
graphics.DrawLine(Pens.LightSteelBlue, -8, 0, 0 + clockRectangle.Width / 2 - 17, 0);
graphics.DrawLine(Pens.DarkBlue, -8, 1, 0 + clockRectangle.Width / 2 - 21, 1);
graphics.ResetTransform();
}
/// <summary>
/// Draw hour arrow
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="hour">current hour - from 0 to 11</param>
/// <param name="minute">current minute - from 0 to 59</param>
/// <param name="graphics">graphics object</param>
private static void DrawHourArrow(Rectangle clockRectangle, float hour, float minute, Graphics graphics)
{
int centerX = clockRectangle.Width / 2;
int centerY = clockRectangle.Height / 2;
hour = hour % 12;
float hourPos = (hour * 60 + minute) / 720.0F;
graphics.TranslateTransform(centerX, centerY);
graphics.RotateTransform(270.0F + 360.0F * hourPos);
graphics.DrawLine(Pens.DarkBlue, -8, -1, 0 + clockRectangle.Width / 2 - 34, -1);
graphics.DrawLine(Pens.LightSteelBlue, -8, 0, 0 + clockRectangle.Width / 2 - 30, 0);
graphics.DrawLine(Pens.DarkBlue, -8, 1, 0 + clockRectangle.Width / 2 - 34, 1);
graphics.ResetTransform();
}
/// <summary>
/// Draw hour bullets
/// </summary>
/// <param name="clockRectangle">clock rectangle</param>
/// <param name="graphics">graphics object</param>
private static void DrawHourBullets(Rectangle clockRectangle, Graphics graphics)
{
int centerX = clockRectangle.Width / 2;
int centerY = clockRectangle.Height / 2;
graphics.FillEllipse(Brushes.LightSteelBlue, centerX - 2, centerY - 2, 4, 4);
for (int hPos = 0; hPos < 12; hPos++)
{
if (hPos % 3 == 0)
{
continue;
}
graphics.TranslateTransform(centerX, centerY);
graphics.RotateTransform(270.0F + 360.0F * (float)hPos / 12.0F);
graphics.DrawEllipse(Pens.DarkGray, clockRectangle.Width / 2 - 15, -1, 2, 2);
graphics.ResetTransform();
}
}
#endregion Local section.
}
}