Hover Buttons with Automatic Drop-Shadow Generation and Antialiasing

Wednesday Oct 30th 2002 by Paul Nettle
Share:

[Update] Render a button in multiple ways, including soft drop-shadow generation, antialiasing with the window background, semi-transparency, and more. This class is an extension to the standard hover button. The new additions are: 1. Buttons in the dialog were not set to be ownerdrawn. This has been corrected. 2. The program now links with MFC 7.0 statically, so users without .NET installed can run the demo.



Click here for a larger image.

Environment: Visual Studio .NET, can be used with VC++ 6 with minor changes (for-loop scoping)

I've been working on a project that can be pretty UI-intensive. And, because it's a graphical environment (a 3D modeller), it only makes sense that the UI be graphically well designed. One of the UI elements that I'm particularly pleased with was the hover buttons.

I really didn't feel like creating a bunch of icons for each button (standard, hovering, clicked, checked, disabled, and so forth), so I decided to create a class that would "render" buttons rather than just plop them on the screen. The result is the buttons you see above. Each button is rendered from a single bitmap. All effects (shadow, disabled transparency, and so on) are automatically generated, rendered, and blended into the window by using the included code. You supply one bitmap image, and the UIButton class takes care of the rest for you. Your artists had better treat you to a free lunch for this one.

The button class itself is pretty simple to work with. However, to accomplish the rendering tasks, you (or your art staff) will need to provide the button with a 4-channel bitmap. This is an ARGB bitmap, where the first channel is the alpha channel. Here is an example:

I used Photoshop to generate these images, though I'm sure plenty of other lesser-expensive applications provide alpha-channel support. If you have access to Photoshop, I've included the master artwork for the sample icons in PSD format with the project source. Simply load these images and save them as RAW files.

The format you choose is up to you because you'll be passing in a memory buffer for the bitmap. I chose to use RAW files, which are simply the image pixels laid out in linear format (four bytes per pixel) without any header information.

The buttons also can automatically re-size themselves to half-sized (small) icons. This is done by using a box-filter, so the smaller image is created by blending pixels together, rather than simply removing them; this produces a nice-looking, reduced-size image. Optionally, you can set the buttons to display as text only. Each of these settings (including the bitmap itself) can be changed on the fly and the button can be told to resize itself automatically for its new icon.

The use of the alpha channel has a few other benefits, and the UIButton class takes advantage of them. First, an alpha channel can contain soft edges, which means that the buttons can be blended onto the window with antialiasing (no more jaggies). Also, the buttons can have holes in the artwork that allow you to see through to the window or shadow below, giving them a true sense of depth. The buttons can even be semi-transparent. And finally, the alpha channel is used to render the drop-shadow, so any soft and subtle details contained in the alpha channel will also be contributed to rendering the drop shadow.

Using the buttons is pretty simple... here's an example:

Automatic Soft Edges and Shadow Generation

  // For check-box like buttons, simply enable the dual-state flag,
  // like so:

  button.dualState() = true;

  // We'll need to load up the 4-channel (ARGB) image file.
  // The code to do this for RAW-format files is included with the
  // project. I use RAW files because they're simple to read (just
  // an array of DWORD values, one per pixel; no header
  // information).

  button.bitmap() = bitmapData;

  // Tooltip?

  button.tip() = "tip goes here";

  // If it's a text button, set the label

  button.label() = "OK";

  // For text buttons, turn this flag on...

  button.textOnly() = true;

  // Set the size of the button: LargeIcons or SmallIcons

button.iconSize() = UIButton::LargeIcons;

Because the buttons are derived from CButton, that's really all there is to it. For the full details on how to use the UIButton class, check out the project source.

Downloads

Download demo project - 113 Kb
Download source - 246 Kb
Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved