Archive for July, 2005

Nothing duplicated

I am a strong believer in reusing code and thereby minimizing the amount of code I need to write. Every time I write some new functionality I double check to make sure I have not already done something very similar already. There are two very good reasons for this.

First of all I want to get maximum benefit from each hour spent in front of the compiler. Working on this project only in my spare time means I don’t have the luxury of doing anything not crucial.

Second, and even more important, is the principle of object orientated programming. If I’m writing code that is the same, or very similar, to something elsewhere in the project then something has gone wrong. It’s a clear indication that something is going amiss with my design.

That being the case I need to investigate the problem and fix the architecture. The fix should negate the need for the duplicated code.

From small steps…

A result of this approach is that a new project should feel like evolution on a small scale. You start off by writing the simple elements of the project. As you then build upwards you create more complex structures that reuse many of the existing components. You’re constantly moving up the evolutionary ladder.

Each step upwards only involves adding a small and reasonable set of features and feels quite manageable in itself. But after a few weeks have passed you look back and notice that all the small steps have evolved your design into an elegant and sophisticated structure. Well, that’s the hope anyway!

If you’ve been following my coding updates then you should have been able to see this taking place. Let’s quickly follow how the project has evolved so far.

In the beginning…

The first control created was about as simple and boring as can be imagined. We created a simple Panel component that is mostly going to be used to fill the client area of a window and give it the appropriate appearance.

Below you can see the control in use and it has the Microsoft Office 2003 look and feel. This is the only rendering class I have coded at the moment and so all the example pictures have this look and feel.

Let there be light…

Actually a more appropriate phrase would be Let there be a border… because out second control is the Group component. This consists of adding a border drawing ability with the existing background capability.

This was quick and easy to create because all of the infrastructure from the existing Panel was reused and extended. Although not obvious from this picture the components are much more flexible than they appear. You can use alpha blending, rounded corners, tiled images and so forth.

The Holy Trinity

Component number three took a little longer to construct because it involves drawing and positioning text. This is the Header control and it reuses the background and border functionality from the previous controls and then extends it.

This is an important landmark because the Header represents completion of the holy trinity of rendering. Almost all controls use a combination of background, border and content for display. If this sounds hard to believe then check out the next section which shows a good example of this in practice.

Add another dimension

What is the difference between a Button control and our previously completed Header component? Not a lot. In fact the only difference is that a Header has only a single palette and a Button has several.

Let’s define what I mean by a palette. A palette is the triple combination of background, border and content settings. And by settings I mean the colors, font and other drawing styles you can specify.

So when the button is drawn normally we use one palette. When the user moves the mouse over the button area we switch to drawing with a different palette. On pressing the mouse down on the button we use yet another palette.

So the button really is the same as the header but instead of having one palette we have several, one for each of the states it can be in. Now you can see how we are reusing the existing infrastructure to get maximum benefit for adding a minimum of new code.

Our final picture below has two button instances, the left in the hovering over state and the right in the normal state.

To Infinity and beyond…

So what is our next step up the evolutionary ladder? The next control is going to be called the HeaderGroup and, as the name implies, it will combine the Group and Header capabilities into a useful little control. This might not sound like much of an advance, but trust me, it will turn out to be quite a handy little control.

So the next time you’re coding…just think how much you owe to Darwin.

The Matrix Connection

Despite the headline this blog entry has absolutely nothing to do with the Matrix set of films. In fact it is about using the ColorMatrix capability of the ImageAttributes class for drawing images.

Not only does that description not fit into the title but there is no chance you would have read the entry without the Reloaded part of the name. A marketing guy would call this technique a Teaser. The rest of us call this very sneaky.

If I was selling fish fingers, or any other food, then this would be called a breach of the trade descriptions act and the local council would be onto me. In fact they would already have closed me down. Luckily no one cares about accurate descriptions in the software industry and so we will continue without fear.

Drawing a Disabled Image

I am in the closing stages of writing a Button control and want to make it look good when it was disabled. There are two ways to handle this issue. The easiest solution for me is to get the developer to provide two images, one for when the control is disabled and another for when it is enabled.

Not only is this lazy but it demands extra work from the developer to use my control. The whole point of our library is to make the developers application look good with a minimum of effort from the developer himself. So the alternative solution, and the one I am taking, is to take the enabled image and then draw it in a disabled appearance.

In the past I have used the ControlPaint.DrawImageDisabled method provided by the framework but I am no longer happy with that solution. I want to provide more flexibility in the appearance and so let the developer choose a variety of different ways the image could be manipulated.

Enter The ColorMatrix

This is where the ColorMatrix comes into play because it can be used to modify the colors of the image when it is being drawn. So now my button control allows the developer to specify an enumeration of different ColorMatrix settings to be applied.

Here is a picture with three buttons. The name of the enumeration value is used as the button text and the image is drawn in the named style.

The first is called normal and has no color modification applied. In the second the matrix is used to convert from color to a black and white scale. Last of all the disabled appearance is achieved by using a gray scale but also making the colors 10% brighter than normal. This gives a more subtle look and feel.

GrayScale Matrix Code

new ColorMatrix(new float[][]{

new float[]{0.3f,0.3f,0.3f,0,0},
new float[]{0.59f,0.59f,0.59f,0,0},
new float[]{0.11f,0.11f,0.11f,0,0},
new float[]{0,0,0,1,0},
new float[]{0,0,0,0,1}

});

The first three lines of the matrix are used to convert the Red, Green and Blue colors of the pixel in that order. The fourth line is used to convert the alpha channel and the fifth line for adding/subtracting values.

So in this example the fourth and fifth lines use a value of 1 to show they are leaving the alpha channel alone and not applying any addition/subtraction.

The values in column 0, 1 and 2 of the first three lines are the same because in order to convert to a grayscale we need to ensure that the RGB values are the same for the R, G and B. Notice that the 0.3, 0.59 and 0.11 values add up to exactly 1.

These three relative factors are used because the eye has better acuity in the green range than in the red and the red is better than the blue. Hence we want to take more account of the green (0.59) than the red (0.3) than the blue (0.11).

Color Intensity

There is no limit to the color manipulation you can achieve and so I also added some extra enumeration values for making the image lighter or darker in appearance. These might prove useful in many different situations. Here they are in operation.

Breaking Point

As an experiment I tried converting just two of the colors to grayscale and leaving the third alone. In the example below you can see GrayScale R where the blue and green have been gray scaled but the red left alone. Below that are the other two versions for blue and green variations.

The reason they are not coming out perfectly is that the three circles are not filled with pure red, pure green and pure blue. Hence the conversion is not achieving the exact effect I was intending. I have decided to leave these enumeration options in the code although they will not be used very often.

Pain Points

By providing these different effects out of the box the developer has more options in presenting the button image. They might decide to have the button appear gray scaled normally but become full color when the mouse tracks over it. Alternatively they might want to use a darker version of the image normally and only use the normal image on hot tracking.

The important point is the developer provides just a single image and can then apply different effects without needing to create them using a separate package, such as Paint Shop Pro. To use a really stupid management style phrase, we are removing a Pain Point for the developer.

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.

.NET Framework 2

Version 2 of the .NET Framework is a great improvement for Windows.Forms developers. Each time I investigate a new area I find some cool new feature that makes life so much easier than before.

Control.DisplayRect

My previous technical entry has already mentioned use of the DisplayRect property as a way of controlling the child space available for positioning children. This is a great feature and without this it would be a real pain to achieve the same effect.

Control.AutoSize

Now I have noticed another great addition that will save developers time. There is a new Control property called AutoSize that does exactly what it says. When defined it will automatically resize the control appropriately.

For instance, if you create a Button control instance then the control will size itself to fit the Text content. Now this might not sound very exciting, but in the past you had a real pain getting a control such as a Button to size properly.

For a start you would have to get the Font used by the Control and then measure the size of the Text for that Font. Then you need to add on a sensible spacing gap around the text and finally add the border allocation. Not rocket science but still a pain to have to write the code.

Header and Button

Knowing this great new property is available means I want my own controls to provide the same functionality. If a user can take advantage of AutoSize on a standard windows Button then they will, quite reasonably, expect my own controls to provide the same functionality.

As the image from a previous post show, I have completed the simple Header control for the library. I am now into the process of creating a Button control that reuses the same rendering process.

After a little investigation I worked out how to hook into the auto sizing process. It turns out to be really easy and I recommend that anyone else writing a custom control also adds the capability.

GetPreferredSize

All you need to do is override the virtual method called GetPreferredSize and return from it a Size instance the is the preferred size you would like your control to be. That’s it. Just override that one method and your done.

This is so simple there is no excuse for not adding it to your own controls.

Feedback

Thanks for the great feedback comments.

Do we need a strapline?

kris makes a good point by asking if a strapline is actually necessary? I assumed that just because most other companies have one that I should as well. Obviously that is not a good reason, but having thought about this more carefully I have come to the conclusion that actually it is a good idea. It’s a good way to get across a simple fundamental message about the company.

When visiting a website I tend to notice the logo and associated strapline first of all. Then my eyes scan downwards to the actual content of the page, skinning over the headlines to see what the content is all about.

So in the worst case people just ignore the strapline, in which case it has caused no harm by being present. In the best case it gets across a simple message I want to convey. This is a no lose situation.

What is the message?

So I guess I need to ask myself what is the message I want to get across to the website visitor. Well I am very clear on what I would like to say. We produce a premium set of visual components that will save your business time and money.

But we need to be careful about putting ideas like saving money or time in the strapline. Just about every company is going to claim they save time and money with their product and so the message is too generic. It needs to be specific.

Looking at the suggestions and working from the ones I like, my new list of candidates comes out like this…

Component Factory
Making you look good.

Component Factory
We build components. You build solutions.

Component Factory
Passionate about your looks.

Component Factory
Creating components so you don’t have to.

Component Factory
Tools that extend your potential.

My current favorite is the second one, because it indicates our position in the value chain. We create the components, the building blocks that the customers use to create a full solution.

If you have any more ideas or better variations then let me know!