Using GDI+ to create an LED

Blake81

Well-known member
Joined
Feb 23, 2006
Messages
304
Location
Georgia, USA
Programming Experience
1-3
I'm really new to GDI+, in fact I just started looking into it today. I want to create a custom control (LED) to use on my forms. I found an example of using the gradient brush, and I think that would probably work to give me the lighting effect I want on the LED. I just don't know how to use it properly. Basically, I want to draw a circle and use the gradient brush on it with the colors red and white. If at all possible, I'd like it also to have a beveled edge around the circle, like the picture below (I know it won't look that good). Could someone also give me a quick pointer about where to put the code to redraw the LED with a different color depending on it it is "lit" or "unlit"? Thanks. I really appreciate any help.

red.jpg
 
Excuse me if I'm wrong Blake81, but it sounds as you have created three LEDs with hardcoded red/green/blue colors for lit/unlit. Why not use the controls Forecolor that is already there for Lit state color and just calculate a darker color from the selected one for Unlit state? This way you can easily test any color without changing any code and recompiling, and the Lit/Unlit colors are always in proportion. A method used to darken that looks good is to adjust brightness by 100 like this:
VB.NET:
Private Function darken(ByVal col As Color) As Color
  Dim r, g, b As Integer
  r = Math.Max(0, col.R - 100)
  g = Math.Max(0, col.G - 100)
  b = Math.Max(0, col.B - 100)
  Return Color.FromArgb(255, r, g, b)
End Function
And in the LED controls OnPaint method simply change to:
VB.NET:
If Me.LState = LEDState.Lit Then
  LCol = Me.ForeColor
Else
  LCol = darken(Me.ForeColor)
End If
 
optimization

This is not a big deal in this case one would think, but the calculation above occurs every time the control is repainted, which is unnecessary, the darker color could be calculated only once when the Forecolor is changed by overriding the base property and adding the calculated dark value as private:
VB.NET:
Private darker As Color
Public Overrides Property ForeColor() As System.Drawing.Color
Get
  Return MyBase.ForeColor
End Get
Set(ByVal Value As System.Drawing.Color)
  MyBase.ForeColor = Value
  darker = darken(Value)
End Set
End Property
and then use the pre-calculated value instead:
VB.NET:
If Me.LState = LEDState.Lit Then
  LCol = Me.ForeColor
Else
  LCol = darker
End If


 
Just FYI, but the 'ControlPaint' class has a couple of methods to darken and brighten colors. I personally dont like them because they are a bit 'over the top' but you may like to check them out. The code would go something like this..


ControlPaint.Dark('Color', percenatge to darken as single)

Or

ControlPaint.Light('color', percentage of color to lighten as single)
 
Also just as an added side note, you don't have to drop it onto a windows form to see it. Add a new control to the library project and inherit your LED Class and you will be able to see it in the designer.
 
JohnH, I am just trying to add your code now to see how it works, and I get "Name 'darken' is not declared." At this point, I've just added this to the end of the code:
VB.NET:
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] darker [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Color
[/SIZE][SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Overrides[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Property[/COLOR][/SIZE][SIZE=2] ForeColor() [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Drawing.Color
[/SIZE][SIZE=2][COLOR=#0000ff]Get
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Return[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]MyBase[/COLOR][/SIZE][SIZE=2].ForeColor
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Get
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Set[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] Value [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Drawing.Color)
[/SIZE][SIZE=2][COLOR=#0000ff]MyBase[/COLOR][/SIZE][SIZE=2].ForeColor = Value
darker = darken(Value)
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Set
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Property
End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE]

Oops, forgot a section. Never mind the error.
 
Just a quick question for JohnH, probably pretty simple. How would I change your code to make the difference between lit and unlit a little more noticeable? It looks pretty good this way, but if I choose red for example, the difference isn't as noticeable as if I choose some other colors. Thanks for your help.
 
Sorry for putting so many posts on this thread, but I have another question for vis781. I just realized that I can resize the LED control, so I made it round just to see what it looks like. I noticed something that doesn't look quite right when it's round as opposed to its original shape. Is there a way to fix this? Look at the bottom center of the area surrounding the LED where it looks indented. There's a darker section there.
ledcolor.jpg
 
That is caused by the linear gradient brush used to fill the outer ellipse. What is happening is the linear gradient is starting to wrap, it's beginning again from the bottom. In code where the linear gradient brush is used, the first argument passed in is the rectangle/ellipse that the brush uses to define the bounds of the gradient. You need to inflate this rectangle slightly to stop that from happening.
 
Back
Top