Creating Glow Button






4.86/5 (22 votes)
Apr 24, 2007
3 min read

131107

5837
An article of how to make a button that can glow
Introduction
This is my very first article to any open source site. Since I've gotten a lot useful article from this site, I'll be glad if I can to contribute to this great site.
This article will explain how to make a button that has a glow feature.
Background (optional)
When I installed Windows Vista, I was amazed by it's appearance. It had a very nice user interface and so many eye candy controls. That make me think about making something just like that. I've created some fancy controls that look like Vista components since that day. Also, I've always thought about making an article or tutorial to share my knowledge. Finally, while creating this glow button control, I've decided to make an article for it too.
So why Glow Button? I've been interested in this control since I played with Vista Windows, especially with its Minimize, Maximize and Close Buttons. They have some fancy glow affects. And thanks to .NET Framework 2.0, it's easier to create them.
Using the code
Basically, to create the glow effect, you have to make a "Layer" that will create the glow with GDI+. Unfortunately, .NET Framework 2.0 doesn't allow a control that can make other controls mid-transparent. Or rather, when you place a control above another control, you can't see the control below, even you set full transparency at the upper control. The trick for this button is to request from another button that surrounds it to make a glow layer for that control.
Since we want to ask other glow controls to make glow effects, we need a layer status for the control:
Public Enum LayerStatus
None = 0
Self = 1
TopLeft = 2
Top = 3
TopRight = 4
Left = 5
Right = 6
BottomLeft = 7
Bottom = 8
BottomRight = 9
End Enum
Now we have a status for the control to make layer as requested. If we must ask another surrounding button to make glow effect, how can we do that if the button is at the edge, side, top, bottom etc? For this problem, we need a special container for our control, so the control at edge or side can ask this container to make the glow effect. Let's name it "Grid".
Another feature that we will add is the ability to change themes dynamically. For this,
we will use a colortable class called GlassColorTable
and some defined colors
for our control. Let's name it ColorSet
. Also remember that a button
has four default states, which is: Normal, Highlighted (Mouse Over), Pressed and Disabled.
For the moment, I'm not including Disabled state, due to to the fact that I don't have enough
time to experiment with it. I'll include it when I update my article.
Public Interface IGlassColor
Enum States
Normal = 0
Highlighted = 1
Pressed = 2
Disabled = 3
End Enum
Sub NormalState()
Sub HighlightState()
Sub PressedState()
Sub DisabledState()
End Interface
Public Class ColorSet
'Normal State
Public BackgroundHigh As Color
'.
'.
'.
Public TextColor As Color
'Highlight State
Public BackgroundHighFocus As Color
'.
'.
'.
Public TextColorFocus As Color
'Glow Set
Public GlowCenter As Color
End Class
Public Class GlassColorTable
Implements IGlassColor
Protected _BackgroundHigh As Color
Protected _BackgroundLow As Color
Protected _ShineHigh As Color
Protected _ShineLow As Color
Protected _BorderLeft As Color
Protected _BorderRight As Color
Protected _BorderTop As Color
Protected _BorderBottom As Color
Protected _TextColor As Color
Protected _GlowCenter As Color
Private _State As IGlassColor.States
Private _cSet As ColorSet
Public Overridable ReadOnly Property BackgroundLow() As Color
Get
Return _BackgroundHigh
End Get
End Property
'.
'.
'.
End Class
To change themes dynamically, we must create a property.
<Browsable(False)> _
Public Property Renderer() As ColorSet
Get
Return _ColorTable.Renderer
End Get
Set(ByVal value As ColorSet)
_ColorTable.Renderer = value
_ColorTable.State = IGlassColor.States.Normal
Me.Refresh()
End Set
End Property
Since we now have the ability to change themes for the button, we must let the button know which color we want to be layered from another control.
<Browsable(False)> _
Public Property LayerColor() As Color
Get
Return _ColorTable.GlowCenter
End Get
Set(ByVal value As Color)
_LayerColor = value
End Set
End Property
So, the most important part is done. It's time to use them for our application. Since we must ask help from another control to make the glow effect, we must set up in each control events which are "mouse enter" and "mouse leave" events.
Private Sub GlowButton1_MouseEnter(ByVal sender As Object,
ByVal e As System.EventArgs) Handles GlowButton1.MouseEnter
GlowButton2.Layer = GlowingButton.GlowButton.LayerStatus.Left
GlowButton4.Layer = GlowingButton.GlowButton.LayerStatus.Top
GlowButton5.Layer = GlowingButton.GlowButton.LayerStatus.TopLeft
GlowButton2.LayerColor = GlowButton1.LayerColor
GlowButton4.LayerColor = GlowButton1.LayerColor
GlowButton5.LayerColor = GlowButton1.LayerColor
Grid1.GlowColor = GlowButton1.LayerColor
Grid1.GlowStartPoint = New Point(GlowButton1.Location.X - 7,
GlowButton1.Location.Y - 7)
Grid1.GlowStyle = GlowingButton.Grid.GlowStyles.TopLeft
End Sub
Private Sub GlowButton1_MouseLeave(ByVal sender As Object,
ByVal e As System.EventArgs) Handles GlowButton1.MouseLeave
GlowButton2.Layer = GlowingButton.GlowButton.LayerStatus.None
GlowButton4.Layer = GlowingButton.GlowButton.LayerStatus.None
GlowButton5.Layer = GlowingButton.GlowButton.LayerStatus.None
Grid1.GlowStyle = GlowingButton.Grid.GlowStyles.None
End Sub
To change themes dynamically, use the Renderer
property.
For Each g As GlowingButton.GlowButton In Grid1.Controls
g.Renderer = New GlowingButton.DiamondRed
Next
Points of Interest
Since we need to ask other controls to apply effects, we have to setup
every control we have in the application. It will take time to setup everything,
especially when we work with many buttons. To solve this problem, I suggest you
make a class that inherits Grid control, place all glow buttons in the grid, and perform the required setup automatically
with AddHandler
methods. When I have more spare time, I'll explain in separate
articles about this.
Additional notes about the demo: did some of you notice my other reason for creating this control? Yes, it's a Sudoku puzzle! My original motive with this control was for creating a Sudoku Puzzle Solver that can apply customized regions (that's why it needed themes or colorsets). The solver itself is still a long way to go because I've include it with many useful features.
That's all.
History
April 20th, 2007: Original Article.