Click here to Skip to main content
15,898,035 members
Articles / Programming Languages / C#

Gradient-Animation check progress bar control

Rate me:
Please Sign up or sign in to vote.
4.40/5 (29 votes)
6 Oct 20041 min read 80.5K   1.2K   61  
Animating gradient-check-image control. When processing is taking a long time, this control is very useful for informing the user.
//
// 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);
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Korea (Republic of) Korea (Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions