//
// Animation CheckProgressBox
// Author : Kyung DuckHyun
// E-Mail : cyberkdh@hotmail.com
//
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
namespace KDHLib.Controls
{
public class AnimationCheckBox : System.Windows.Forms.Control
{
private System.Windows.Forms.Timer m_timer;
private System.ComponentModel.IContainer components;
public AnimationCheckBox() : base()
{
// Set the control styles
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
// Setting the default property
AdjustTextFormat(ContentAlignment.MiddleLeft);
this.Left = 0;
this.Top = 0;
this.Width = DEF_WIDTH;
this.Height = DEF_HEIGHT;
m_col1 = Color.Black;
m_col2 = Color.LightBlue;
// Adjust the points of clip region for animation of checkbox
m_Points = new Point[7];
m_Points[0] = new Point(0, 6);
m_Points[1] = new Point(5, 10);
m_Points[2] = new Point(15, 0);
m_Points[3] = new Point(15, 4);
m_Points[4] = new Point(5, 15);
m_Points[5] = new Point(0, 10);
m_Points[6] = new Point(0, 6);
// makes gradient image of checkbox
MakeGradientCheckBoxBrush();
// makes clip region by the points
AdjustCheckImageRegion();
InitializeComponent();
m_timer.Enabled = true;
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.m_timer = new System.Windows.Forms.Timer(this.components);
//
// m_timer
//
this.m_timer.Tick += new System.EventHandler(this.m_timer_Tick);
}
#region Variables
public enum CHECKBOXALIGN
{
TopLeft = 0,
MiddleLeft,
BottomLeft,
TopRight,
MiddleRight,
BottomRight
};
public enum ANICHECKSTATE
{
UNCHECKED = 0,
CHECKING,
CHECKED
};
const int DEF_WIDTH = 30;
const int DEF_HEIGHT = 18;
const int DEF_CHECKBOXSIZEX = 16;
const int DEF_CHECKBOXSIZEY = 16;
private ANICHECKSTATE m_curState = ANICHECKSTATE.UNCHECKED;
private int xloc = 0;
private Size m_szAnimationCheckBox = new Size(16, 16);
private Color m_col1, m_col2;
private Bitmap m_bmCheckBox = null;
private Region m_clipCheckBoxRegion = null;
private StringFormat m_fmtText = new StringFormat();
private CHECKBOXALIGN m_alignCheckBox = CHECKBOXALIGN.MiddleLeft;
private ContentAlignment m_alignText = ContentAlignment.MiddleLeft;
private Rectangle m_rtCheckBox = new Rectangle();
private Rectangle m_rtText = new Rectangle();
private Point[] m_Points = null;
#endregion
#region Properties
[System.ComponentModel.Description("Gets or sets state of Ani-Checkbox"),
System.ComponentModel.Category("Ani-Progress Checkbox Property")]
public ANICHECKSTATE CHECKSTATE
{
get
{
return m_curState;
}
set
{
m_curState = value;
if(m_curState == ANICHECKSTATE.CHECKING)
m_timer.Enabled = true;
else
{
m_timer.Enabled = false;
Invalidate();
}
}
}
[System.ComponentModel.Description("Gets or sets size of Ani-Propgress Checkbox"),
System.ComponentModel.Category("Ani-Progress Checkbox Property")]
public Size CheckBitmapSize
{
get
{
return m_szAnimationCheckBox;
}
set
{
m_szAnimationCheckBox = value;
AdjustAnimationCheckBoxRect_TextRect();
AdjustCheckImageRegion();
MakeGradientCheckBoxBrush();
Invalidate();
}
}
[System.ComponentModel.Description("Gets or sets the location of checkbox"),
System.ComponentModel.Category("Ani-Progress Checkbox Property")]
public CHECKBOXALIGN CheckBoxAlign
{
get
{
return m_alignCheckBox;
}
set
{
m_alignCheckBox = value;
AdjustAnimationCheckBoxRect_TextRect();
Invalidate();
}
}
[System.ComponentModel.Description("Gets or sets the Align of Text in the Ani-Progress check box"),
System.ComponentModel.Category("Ani-Progress Checkbox Property")]
public ContentAlignment TextAlign
{
get
{
return m_alignText;
}
set
{
m_alignText = value;
AdjustTextFormat(m_alignText);
Invalidate();
}
}
[System.ComponentModel.Description("Gets or sets the starting color of the gradient for Animation CheckBox"),
System.ComponentModel.Category("Animcation Checkbox Property")]
public Color BeginGradientColor
{
get
{
return m_col1;
}
set
{
m_col1 = value;
MakeGradientCheckBoxBrush();
Invalidate();
}
}
[System.ComponentModel.Description("Gets or sets the ending color of the gradient for Animation CheckBox"),
System.ComponentModel.Category("Animcation Checkbox Property")]
public Color EndGradientColor
{
get
{
return m_col2;
}
set
{
m_col2 = value;
MakeGradientCheckBoxBrush();
Invalidate();
}
}
#endregion
#region override functions
protected override void OnTextChanged(EventArgs e)
{
Invalidate();
base.OnTextChanged (e);
}
protected override void OnSizeChanged(EventArgs e)
{
AdjustAnimationCheckBoxRect_TextRect();
base.OnSizeChanged (e);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
Rectangle rt = this.ClientRectangle;
Rectangle rtText, rtCheck;
Graphics g = e.Graphics;
rtCheck = m_rtCheckBox;
rtText = m_rtText;
SolidBrush br = new SolidBrush(this.ForeColor);
g.DrawString(this.Text, this.Font, br, rtText, m_fmtText);
// if the control's state is UNCHECKED, control do not draw the ani-checkbox image
if(m_curState == ANICHECKSTATE.UNCHECKED)
return;
// clone the original region
Region r = m_clipCheckBoxRegion.Clone();
// locate the region on the control
r.Translate(rtCheck.Left, rtCheck.Top);
Region backr = g.Clip;
// set the clip area
g.Clip = r;
Rectangle bm, bm2;
bm = new Rectangle(0, 0, rtCheck.Width, rtCheck.Height);
bm2 = bm;
bm2.X = bm2.Width - xloc;
bm2.Width = xloc;
g.DrawImage(m_bmCheckBox, rtCheck.Left + xloc, rtCheck.Top, bm, GraphicsUnit.Pixel);
g.DrawImage(m_bmCheckBox, rtCheck.Left, rtCheck.Top, bm2, GraphicsUnit.Pixel);
// restore the clip area by original clip area
g.Clip = backr;
}
#endregion
#region "Local Methods"
// Convert the ContentAlignment struct to StringFormat for DrawString API
private void AdjustTextFormat(ContentAlignment ca)
{
if(ca == ContentAlignment.TopLeft || ca == ContentAlignment.TopCenter || ca == ContentAlignment.TopRight)
{
m_fmtText.LineAlignment = StringAlignment.Near;
}
if(ca == ContentAlignment.MiddleLeft || ca == ContentAlignment.MiddleCenter || ca == ContentAlignment.MiddleRight)
{
m_fmtText.LineAlignment = StringAlignment.Center;
}
if(ca == ContentAlignment.BottomLeft || ca == ContentAlignment.BottomCenter || ca == ContentAlignment.BottomRight)
{
m_fmtText.LineAlignment = StringAlignment.Far;
}
if(ca == ContentAlignment.TopLeft || ca == ContentAlignment.MiddleLeft || ca == ContentAlignment.BottomLeft)
{
m_fmtText.Alignment = StringAlignment.Near;
}
if(ca == ContentAlignment.TopCenter || ca == ContentAlignment.MiddleCenter || ca == ContentAlignment.BottomCenter)
{
m_fmtText.Alignment = StringAlignment.Center;
}
if(ca == ContentAlignment.TopRight || ca == ContentAlignment.MiddleRight || ca == ContentAlignment.BottomRight)
{
m_fmtText.Alignment = StringAlignment.Far;
}
}
// On resizing, changing attributes of this control, recalculate the Rectangle for Text and CheckBox
private void AdjustAnimationCheckBoxRect_TextRect()
{
Rectangle rt = this.ClientRectangle;
Rectangle retRT = new Rectangle(0, 0, DEF_CHECKBOXSIZEX, DEF_CHECKBOXSIZEY);
retRT.Width = m_szAnimationCheckBox.Width;
retRT.Height = m_szAnimationCheckBox.Height;
Rectangle retTxt = new Rectangle(0, 0, rt.Width - retRT.Width, rt.Height);
if(this.m_alignCheckBox == CHECKBOXALIGN.MiddleLeft ||
this.m_alignCheckBox == CHECKBOXALIGN.TopLeft ||
this.m_alignCheckBox == CHECKBOXALIGN.BottomLeft)
{
retRT.X = 0;
retTxt.X = retRT.Width;
}
else
{
retRT.X = rt.Width - retRT.Width;
}
if(this.m_alignCheckBox == CHECKBOXALIGN.MiddleLeft ||
this.m_alignCheckBox == CHECKBOXALIGN.MiddleRight)
{
retRT.Y = rt.Height / 2 - retRT.Height / 2;
}
if(this.m_alignCheckBox == CHECKBOXALIGN.BottomLeft || this.m_alignCheckBox == CHECKBOXALIGN.BottomRight)
{
retRT.Y = rt.Height - retRT.Height;
}
m_rtCheckBox = retRT;
m_rtText = retTxt;
}
// Makes the Checkbox clip region
private void AdjustCheckImageRegion()
{
GraphicsPath gp = new GraphicsPath();
Point[] pt = new Point[m_Points.Length];
m_Points.CopyTo(pt, 0);
for(int i=0;i<pt.Length;i++)
{
pt[i].X = pt[i].X * m_szAnimationCheckBox.Width / DEF_CHECKBOXSIZEX;
pt[i].Y = pt[i].Y * m_szAnimationCheckBox.Height / DEF_CHECKBOXSIZEY;
}
gp.AddLines(pt);
m_clipCheckBoxRegion = new Region(gp);
}
// Makes the Checkbox Gradient brush
private void MakeGradientCheckBoxBrush()
{
if(m_bmCheckBox != null)
m_bmCheckBox.Dispose();
Graphics gImage = null, gWnd = null;
Rectangle rtCheckBox;
AdjustAnimationCheckBoxRect_TextRect();
rtCheckBox = m_rtCheckBox;
Rectangle rtLeft = new Rectangle(0, 0, rtCheckBox.Width/2 + 1, rtCheckBox.Height);
Rectangle rtRight = new Rectangle(rtCheckBox.Width/2, 0, rtCheckBox.Width/2 + 1, rtCheckBox.Height);
LinearGradientBrush br1 = new LinearGradientBrush(rtLeft, m_col1, m_col2, LinearGradientMode.Horizontal);
LinearGradientBrush br2 = new LinearGradientBrush(rtRight, m_col2, m_col1, LinearGradientMode.Horizontal);
// Get temporary DC and make a compatible bitmap with current Windows.
gWnd = Graphics.FromHwnd(this.Handle);
m_bmCheckBox = new Bitmap(rtCheckBox.Width, rtCheckBox.Height, gWnd);
gWnd.Dispose();
// make a new bitmap
gImage = Graphics.FromImage(m_bmCheckBox);
gImage.FillRectangle(br2, rtRight);
gImage.FillRectangle(br1, rtLeft);
gImage.Dispose();
br1.Dispose();
br2.Dispose();
}
#endregion
private void m_timer_Tick(object sender, System.EventArgs e)
{
xloc++;
if(xloc >= m_rtCheckBox.Width)
{
xloc = 0;
}
Invalidate(m_rtCheckBox);
}
}
}