Introduction
I'm presently in the design stage of a huge smart-client application, with tons of stunning UIs. Looking at the UI designs, it quickly became obvious that I'd have to spend a lot of time writing code to paint gradient fills, which seem to be quite hot among graphic designers these days. And it's not hard to understand why; the difference they make to a UI is quite spectacular.
So faced with the potential nightmare of having to paint everything from a simple Label
to a complex container control, I started on a small GUI library, which I code named Inferno. The idea was to build several controls inherited from the classes in System.Windows.Forms
, and to attach design-time configurable gradient fills. So for instance, instead of the usual BackColor
property, a Label
would have a BackGraident
property. Well hopefully, in the near future I'd be able to post the entire library here. Keep your fingers crossed�
So this article is about the very first widget I cooked up. Although, it was originally built to be used as a UITypeEditor
for my Gradient
class, I'm sure many people could find a use for it in any form of graphics applications that they maybe building.
How it ticks
The GradientBuidler
class is a custom painted control which is split horizontally into two rectangular areas, called the gradientBarRect
and the markerStrip
.
The marker strip area is where the user can insert new color steps on to the gradient. He could basically double click on any point right below the gradient preview, to insert a new marker (which defaults to the exact color of the gradient just above it). The markers, other than the start and end markers could be moved along the marker strip to fine tune the gradient.
The preview of the gradient is painted on to the gradientBarRect
in a discretionary manner. When the gradient is changed, the new gradient is painted on to a Bitmap
object which is then painted on to the gradient bar area. The Bitmap
object serves as a cached snapshot of the gradient, greatly improving the performance of the paint operation when the control has to repaint itself. Incidentally, this behavior was not present in my actual UITypeEditor
as it would only need to be displayed for a very short amount of time.
The code also includes the TypeEditor developed by Emmanuel Tissandier for displaying the color picker.
Using the gradient editor
The gradient editor is set to expose an object of type Gradient
. The Gradient
class contains several methods that you can use while performing common fill operations:
public void FillRectangle( Graphics g, Rectangle rect )
public void FillRegion( Graphics g, Region rgn )
public void FillPath( Graphics g, GraphicsPath path )
If on the other hand you require more flexibility, you can obtain a handle to either a LinearGradientBrush
or a PathGradientBrush
object by using,
public PathGradientBrush GetPathGradientBrush( GraphicsPath path )
public LinearGradientBrush GetLinearGradientBrush(Rectangle rect)
You would then of course be responsible for disposing of the brush once you're done. ;)
Handle the GradientChanged
event of the GradientEditor
to redraw your graphics when the user makes changes to the Gradient
. By setting the SilentMarkers
property to false
(default) you could make the control fire this event even as a marker is being dragged.
A word about the demo
The demo app I've included is perhaps too simple for anybody's liking. Painting on a Panel
by handling its Paint
event is not the most optimal way to go. I've only done it to keep things as simple as possible. If you are writing a real graphics app, I recommend that you use one of the many great canvas classes CodeProject seems to have.