Saturday, March 19, 2011

Complex dialogs with wxWidgets

Most RAD tools, like the venerable Visual Basic, let users put controls in a dialog using a fixed layout: just drag each control where you want to see it. This is a very simple approach, but it has some shortcomings, especially for applications that will run on different operating systems.
The problem is that the layout is fixed and it does not adapt to the size of the contained text. Widows uses a default font that is smaller than the one used in Linux or OS X, and even in Windows users can set larger fonts.
This means that if a dialog has been designed in Windows with default fonts then the text will no be completely visible if the used font is larger.
The same happens with translations: if the translated text is longer it will not be completely visible.

To solve these problems wxWidgets (like other frameworks) uses sizers for dialogs layout. Sizers change dynamically the size of controls so that their content will always be visible. This is very useful but it look rather complicated at first: you need some time to become used to sizers if you are used to fixed layouts.

Accounting programs often need to show many controls in a dialog, so it is important to use the available space in the best possible way. This sometimes means arranging controls in an irregular way to avoid wasting space.
Sizers can cause troubles in this situation: one of the more powerful sizer ix wxFlexGridSizer: it arranges controls in a regular grid, with rows and columns of different sizes to accommodate controls. This works reasonably well, but each column (for example) has the width of the widest control so if it contains a very wide and a very narrow control a lot of space will be wasted, and the dialog will not look very well.

A few days ago I had a similar situation, so I tried wxGridBagSizer: there is not much information about it but it looked promising. This is very complicated to use at the source code level, but I discovered that DialogBlocks has great support for this sizer. wxGridBagSizer arranges controls in a layout that is similar to HTML tables: controls lie in a grid, but a grid cell can span over more than one row or column. This solves most of the problems and the resulting dialog looks much better and uses the available space very well.

Here is an example of a dialog using wxGridBagSizer in DialogBlocks: you can see how some controls span over more than one row or column:

No comments:

Post a Comment