[C#] Modern Glow Button - Release

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Here's a new button concept I've started working on this morning (early morning). It combines a glow animation with a very basic Windows 8 Design style feel. The glow point is set to follow the cursor on the hover events. It also has the properties to act as a State button or a Checkstate button if you want to call it that...

All caps or regular text is a property for customization as well. Below is a quick preview I thrown together, and the source code.

Preview: *Note: Looks better in reality than in this GIF. The GIF format has a bad gradient and transparency tolerancy level.
C0iIVQF.gif


Source Code:
Code:
// Name: Modern Glow Button
// Author: AceInfinity
// Copyright: Tech.Reboot.Pro - 2013

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class ModernGlowButton : Button
{
	// Fields & Nested Types
	private Timer timer = new Timer();

	private bool _IsStateButton = false;
	public bool IsStateButton
	{
		get
		{
			return _IsStateButton;
		}
		set
		{
			_IsStateButton = value;
			Invalidate();
		}
	}

	private bool _AllCapsText = true;
	public bool AllCapsText
	{
		get
		{
			return _AllCapsText;
		}
		set
		{
			_AllCapsText = value;
			Invalidate();
		}
	}

	private string _StateNormalText = "On";
	public string StateNormalText
	{
		get
		{
			return _StateNormalText;
		}
		set
		{
			_StateNormalText = value;
		}
	}

	private string _StatePressedText = "Off";
	public string StatePressedText
	{
		get
		{
			return _StatePressedText;
		}
		set
		{
			_StatePressedText = value;
		}
	}

	private Point _GlowPoint = Point.Empty;
	private const int _GlowAnimationSpeed = 1;
	private ushort _GlowIntensity = 0;
	private ushort GlowIntensity
	{
		get
		{
			return _GlowIntensity;
		}
		set
		{
			if (value < _GlowLowerbound)
			{
				_GlowIntensity = _GlowLowerbound;
			}
			else if (value > _GlowUpperbound)
			{
				value = _GlowUpperbound;
			}
			else
			{
				_GlowIntensity = value;
			}
		}
	}

	private const ushort _GlowUpperbound = 30;
	private const ushort _GlowLowerbound = 0;

	private State _CurrentState = State.Off;
	public State CurrentState
	{
		get
		{
			return _CurrentState;
		}
	}

	public enum State
	{
		On, Off
	}

	ButtonState _ButtonState = ButtonState.Normal;
	enum ButtonState
	{
		Normal, Pressed
	}

	private bool _GlowAnimation = false;
	GlowState _GlowState = GlowState.None;
	enum GlowState
	{
		None, FadeIn, FadeOut
	}

	// Constructor
	public ModernGlowButton()
	{
		timer.Enabled = true;
		timer.Interval = _GlowAnimationSpeed;
		timer.Tick += Timer_Tick;
	}

	// Method Overrides
	protected override void OnPaint(PaintEventArgs e)
	{
		base.OnPaint(e);
		e.Graphics.Clear(Color.FromArgb(45, 45, 45));
		e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

		if (_ButtonState == ButtonState.Normal)
		{
			DrawButton(e.Graphics, _ButtonState);
			DrawGlow(e.Graphics);
		}
		else
		{
			DrawButton(e.Graphics, _ButtonState);
		}
	}

	protected override void OnMouseDown(MouseEventArgs e)
	{
		base.OnMouseDown(e);
		if (IsStateButton)
		{
			if (_ButtonState == ButtonState.Normal)
			{
				_ButtonState = ButtonState.Pressed;
				_CurrentState = State.Off;
			}
			else
			{
				_ButtonState = ButtonState.Normal;
				_CurrentState = State.On;
			}
		}
		else
		{
			_ButtonState = ButtonState.Pressed;
		}

		timer.Stop();
		GlowIntensity = 0;

		Invalidate();
	}

	protected override void OnMouseUp(MouseEventArgs e)
	{
		base.OnMouseUp(e);
		if (!IsStateButton)
		{
			_ButtonState = ButtonState.Normal;
		}
		Invalidate();
	}

	protected override void OnMouseMove(MouseEventArgs e)
	{
		base.OnMouseMove(e);
		_GlowState = GlowState.FadeIn;
		if (GlowIntensity < _GlowUpperbound)
		{
			_GlowAnimation = true;
			timer.Start();
		}
		_GlowPoint = e.Location;
		Invalidate();
	}

	protected override void OnMouseLeave(EventArgs e)
	{
		base.OnMouseLeave(e);
		_GlowState = GlowState.FadeOut;
		if (GlowIntensity > _GlowLowerbound)
		{
			_GlowAnimation = true;
			timer.Start();
		}
		Invalidate();
	}

	// Methods
	private void Timer_Tick(object sender, EventArgs e)
	{
		if (_GlowAnimation)
		{
			switch (_GlowState)
			{
				case GlowState.FadeIn:
					if ((GlowIntensity += 3) >= _GlowUpperbound)
					{
						_GlowAnimation = false;
					}
					break;
				case GlowState.FadeOut:
					if ((GlowIntensity -= 1) <= _GlowLowerbound)
					{
						_GlowAnimation = false;
					}
					break;
			}
		}
		else
		{
			timer.Stop();
		}

		Invalidate();
	}

	private void DrawButton(Graphics g, ButtonState state)
	{
		Rectangle rect = Rectangle.FromLTRB(0, 0, this.Width - 1, this.Height - 1);
		Rectangle elipseRect = new Rectangle(rect.X - rect.Width * 2, rect.Y - rect.Height * 2, rect.Width * 4, rect.Height * 4);

		switch (state)
		{
			case ButtonState.Normal:
				using (GraphicsPath graphicsPath = new GraphicsPath(FillMode.Alternate))
				{
					graphicsPath.AddEllipse(elipseRect);
					using (PathGradientBrush pgb = new PathGradientBrush(graphicsPath))
					{
						pgb.CenterPoint = _GlowPoint;
						pgb.CenterColor = Color.FromArgb(GlowIntensity, 255, 255, 255);
						pgb.SurroundColors = new[] { Color.Transparent };
						pgb.FocusScales = new PointF(0, 0);
						g.FillRectangle(pgb, elipseRect);
					}
				}
				break;
			case ButtonState.Pressed:
				using (GraphicsPath graphicsPath = new GraphicsPath(FillMode.Alternate))
				{
					graphicsPath.AddEllipse(elipseRect);
					using (PathGradientBrush pgb = new PathGradientBrush(graphicsPath))
					{
						pgb.CenterPoint = _GlowPoint;
						pgb.CenterColor = Color.FromArgb(60, 60, 60);
						pgb.SurroundColors = new[] { Color.FromArgb(5, 5, 5) };
						pgb.FocusScales = new PointF(0, 0);
						g.FillRectangle(pgb, elipseRect);
					}
				}
				break;
		}
		DrawText(g);
	}

	private void DrawGlow(Graphics g)
	{
		using (SolidBrush sb = new SolidBrush(Color.FromArgb(GlowIntensity, Color.White)))
		{
			g.FillRectangle(sb, this.DisplayRectangle);
		}
	}

	private void DrawText(Graphics g)
	{
		string text = string.Empty;
		if (IsStateButton)
		{
			text = _ButtonState == ButtonState.Normal ? _StateNormalText : _StatePressedText;
		}
		else
		{
			text = this.Text;
		}

		if (_AllCapsText)
		{
			text = text.ToUpper();
		}

		SizeF strSize = g.MeasureString(text, this.Font);
		g.DrawString(text, this.Font, Brushes.LightGray, new PointF(this.Width / 2 - strSize.Width / 2, this.Height / 2 - strSize.Height / 2));

	}
}

I'm good with the way it is currently. Add anything or modify anything to suit your needs.

:thumbsup2:
 
It's almost like I'm inventing the style for Windows 9 :lol:

Glow and the Windows 8 style put together. I actually like it though... It feels simple but more futuristic than just the regular plane style that Windows 8 has with a constant flat highlight color.
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top