Archive for 2006

Although the Office guidelines make no mention of support for MDI I think it is essential to support it. And now we do.

It was actually much easier than I thought it would be. The hard part was working out how to prevent the system menu line from appearing when an MDI child window is maximized. After a hour of playing around it turns out to be just a single platform invoke call to the Win32 SetMenu call.

Here is the ribbon inside an MDI container with the child in restored state.

And now when the child is maximized I show the three pendant buttons allowing the child to be minimized, restored or closed. (The screen capture didn’t pick up the mouse that was over the restore button, it does not usually shine yellow by itself!)

The official guidelines indicate a defined method for handling the tabs when there is not enough room to show them fully. This is how it works.

Below are a set of tabs with plenty of room to draw fully. As you can see there is alot of space between each tab which makes it easy to scan and find what you’re looking for.

Once you shrink the space smaller than this the guidelines indicate you can reduce the spacing between each tab until you reach the minimum needed to draw the text without clipping. Here is the width reduced to just before clipping would occur…

From this point onwards any shrinkage is going to cause some of the text to be truncated. So now the guidelines say you must show separators between the tabs so that the user can see this is happening. It also indicates that space be taken from the widest tab until it is equal in width to the second widest, and so forth. Here is the result…

Now we have reached the point where each tab is exactly as wide as the minimum allowed (approx enough for 3 characters). After this point you need to show scrolling buttons so the user and scroll back and forth along the tabs. Like this…

In practice you should rarely see the need for scrolling buttons because unless you are using a large number of tabs and have a slim application window. But the ribbon can handle the scenario should it happen.

And you thought that drawing the tabs was a trivial process!

Here is my first milestone. Adding the tabs.

The tabs highlight when tracking over them and the selected one has the bold appearance that you see. I used Paint Shop Prop to take screen dumps of Office 2007 Excel and work out the correct color values to use for each of the three color schemes.

Notice how the black scheme uses a different way of painting the tracking tab. It has a more glassy feel than either blue or silver. Takes extra time to duplicate both of the drawing techniques but it is worth the effort to try and get the Krypton version as close as possible to the original.

After a refreshing two week break I am back at the wheel and working on the KryptonForm custom chrome functionality.

Actually I’ve been back for a week and after spending a couple of days catching up with emails am now hard at work on KryptonForm. Adding the custom chrome capability is proving trickier than I anticipated. , Each time I think I’ve figured something out a couple unexpected side effects appear and cause a rework of the code.

Code that works fine with a static border size and display in my prototype application fails once you add the dynamic customization ability that Krypton exposes. Instead of always having a fixed width on the border the developer can alter the border width at any time using the StateCommon and other instance properties. This flexibility is great for the user of the library but exposes gotchas in the implementation.

For example, I thought I had the sizing of the window border working nicely until I noticed that minimizing and restoring the window caused its size to change. Not because of anything I was doing, but there must be some windows code that is making assumptions about the border size and it applies changes during the min/restore process. Sadly these assumed changes do not play nicely with my code and so it took several hours to find a way to work around the issue.

At the moment I have the custom chrome working with a simple border around the client area. There is no caption bar or any caption buttons. Here is the window when active….

…and when inactive.

Not very exciting but it respects changes you make on the fly to the StateActive, StateInactive and StateCommon properties.

Now, I need to sort out getting it to work when you have rounding for the border or when you specify only a subset of the borders be drawn. So that it acts exactly like a border you can customize for a KryptonButton, KryptonGroup or other such control.

Building a ribbon control looks quite a daunting task. I signed up to licence the Office 2007 User Interface Design Guidelines which weigh in at a hefty 119 pages; using up most of the blue ink in my printer because of all the screen shots. The guidelines are excellent and provide the perfect design specification. Certainly better than any actual spec I have ever received when working for a company.

I am going to adopt the same approach I always use when faced with a large chunk of work. Break it down into bite sized pieces and just nibble away. The biggest danger in my experience is trying to solve the entire problem in your head right at the start. But its just too big, your never going to manage it and even if you did the solution will have to change and evolve as you go along anyway. Unless you have written this sort of control before you just cannot anticipate all the little snags your will come across.
No, much better in my experience to combine the benefits of small chunks of work and refactoring. This is the development cycle I always use.

1) Identity a small unit of work, no more than 1 days effort.
2) Implement and refactor the code as needed.
3) Test and fix until the control is fully working.

I always give myself small milestones that take at most 1 day and often much less. Sometimes I will achieve the above cycle several times in a day. I cannot think of a time when I have not been able to break down a task into smaller and smaller chunks until they are less than a day each.

Remember these units of work might not do anything useful as far as users or other developers are concerned, they are for your use only. Knowing that I am hitting my milestones on a daily basis is great for keeping my motivation high and feeling like I am making progress towards a very distant finish line. This approach works especially well for user interface development as you actually get to see something happening on the screen!

The second step is to remember to refactor your design when implementing. This is so important I cannot stress it enough. So I’m going to say it again, refactor your design! At the end of each implementation cycle the code should look as if the entire control was designed that way from the start. It should be impossible for an outsider to look at the code and notice that it was written piece meal and not designed in its entirety up front.

This is tough to achieve because it means you often revisit and rework the same code several times. Resist the temptation to break your own architecture! If you break your own architecture before you finish the first release what chance have you of maintaining and improving it in the future? Not much.

Last up is the testing and fixing of all bugs before starting another cycle of work. Because your completing a work cycle most days it means your control is always in a buildable and even shippable state. Sure, it might not have much functionality after the first week but what you have should be production quality. Your aim is to ensure your code and design is gold standard all the time. Sounds impossible but actually is very easy it you adopt that approach from the outset.

In order to show this in practice and get feedback during developement I will blog regularly about development of the ribbon control. Starting tomorrow you can follow progress as it happens.