Phil Wright : Component Factory

Friday, July 15, 2005

microISV, Text For Australians

Header Control Revisited

At last the simple heading control is finished. No doubt changes will need to be made in the future to mirror alterations in the overall architecture but the basic implementation is there and working. The last feature I added, and quite a useful one, is the Orientation property.

As you can see in the picture below, you can define the orientation so that text is drawn in one of four positions. The Top, Left and Right positions are easy to imagine being of use in various ways. But the Bottom orientation is a little harder to justify.

My first excuse for adding upside down text is a feeling of completeness. If you add the other three positions it just does not feel right to miss out the fourth one. The second, and more flimsy excuse, is that my wife is from Oz and so she needs that format to use my library.

(No doubt you will haved spotted the flaw in my argument; the chances of a programmers wife writing any code must be pretty slim. Although one of her Australian relations is bound to find this blog and send me an abusive email)

You probably didn't notice on first inspection but the heading control is actually showing multi-line text. This could be really useful in many applications and when you combine this capability with the Orientation and AutoSize properties it turns into a handy little control.

Think of it as a traditional Label control on steroids.

Creating a Button

After creating three simple controls (Panel, Group and Heading) we need to move onto something a little more difficult and certainly more interesting. The one control that everyone loves to create for themselves, the Button.

Browse any programmers code site such as Code Project or Code Guru and you will find a zillion different button implementations. I guess this is the starting place for any new user interface programmer in the same way your first console application is the canonical Hello World!.

One of great advantages of thinking about the design before coding is that I can reuse almost everything written so far. The separation of Palette, Renderer, View, Control and Controller into separate abstractions makes for great reuse possibilities.

So my Button control will use exactly the same specification for content as the Heading control, i.e. an image and two text strings. So creating the basic control outline was quick and easy.

It was also the first time we needed to add a Controller to the framework code as this is the first active control that needs to respond to mouse or keyboard input. The ButtonController implementation just takes the mouse input and decides which palette entries should be used for drawing.

Here you can see the button in three states.

The left image is the normal button state, the second image the mouse over and finally the far right image is where the mouse is pressing down the button. You cannot see the actual mouse pointer because I used a naff screen capture utility that does not capture it, but you get the idea.

Hidden Depths

You might think that the control was pretty much down by the look of it. Sadly that is not the case. Although a Button control sounds very simple it actually has a fair amount of functionality that needs adding that most people don't event think about.

So now I have to flesh it out by correct handling keyboard support for mnemonics. Provide correct feedback for when it has the focus or when it is the default button on a Form. Plus it has to implement the standard IButtonControl interface so it interacts correctly with the rest of the Windows.Forms implementation. And of course it needs to automatically update the DialogResult of the parent Form when the user clicks the button.

Luckily none of these is hard to implement but it does take a little time to knock out the code and test it works as anticipated in the common usage scenarios.

Well, that is my next few days taken care of.


  • Phil, this may be geekier than you want to get in this blog, but I would love to learn a bit about how you test your components. UI testing is jone of those things that, so far, I just can't grok. I can write tests that get data from a db, tests that write those data into a tree, but tests that validate the correct behavior when a user drags a tree node just don't seem realistic enough because, invariably, the state of some data point at runtime is just not what I expect it to be at test time.

    That, and perhaps it might make me a better user of your components.

    Hey, that would be a selling point: components that come with test stubs (and examples) that allow the application programmer to more easily test the code that uses your compoenents.

    By Anonymous flipdoubt, at 2:11 am  

Post a Comment

<< Home