Sizers
The layout algorithm used by sizers in wxWidgets is closely related to layout systems in other GUI toolkits, such as Java's AWT, the GTK+ toolkit, or the Qt toolkit. It is based upon the idea of individual windows reporting their minimal required size and their ability to be stretched if the size of the parent window has changed. This will most often mean that the programmer does not set the initial size of a dialog; instead, the dialog will be assigned a sizer, which will be queried about the recommended size. This sizer in turn will query its children (which can be windows, empty space, or other sizers) and further descendants. Note that wxSizer does not derive from wxWindow and thus does not interfere with tab ordering and requires very few resources compared to a real window. Sizers form a containment hierarchy parallel to the actual window hierarchy: the sizer hierarchy for a complex dialog may be many deep, but the controls themselves will probably all be siblings with the dialog as their parent.Chapter 9, "Creating Custom Dialogs." A red border in the editor pane surrounds the currently selected element, and its immediate parent is shown with a blue border. The tree you see on the left represents the sizer view of the hierarchy, but all controls are still parented directly on the dialog as far as the window hierarchy is concerned.
Figure 7-1. Viewing a sizer hierarchy in a dialog editor
[View full size image]

Figure 7-2. A schematic view of the sizers for PersonalRecordDialog

Common Features of Sizers
All sizers are containersthat is, they are used to lay out one or more elements, which they contain. No matter how the individual sizers lay out their children, all children have certain features in common.A minimal size:
The minimal size of a control is calculated from the control's notion of its "best size" (supplied by implementing DoGetBestSize for each control). This is the control's natural size. For example, the best size of a check box comprises the space taken up by the check box graphic and the label. However, if you want the initial window size (as passed to the window's constructor) to be used as the minimal size instead, you can use the wxFIXED_MINSIZE style when adding the control to a sizer. Note that only some windows can calculate their size (such as a check box), whereas others (such as a list box) don't have any natural width or height and thus require an explicit size. Some windows can calculate their height, but not their widthfor example, a single-line text control. Figure 7-3 shows three controls on their own in a dialog, showing how they expand the dialog to fit their own minimal size.
Figure 7-3. Windows reporting their minimal size



The border is just empty space that is used to separate elements. This border can be all around, or it can be at any combination of sides, such as only above and below the control. The thickness of this border must be set explicitly, typically 5 pixels. Figure 7-4 shows dialogs with only one control (a button) and a border of 0, 5, and 10 pixels around the button, respectively.
Figure 7-4. Different border sizes



An element can be moved to the center of the available space, or to either side of the space. Figure 7-5 shows a horizontal box sizer containing a list box and three buttons. One button is centered, one is aligned at the top, and one is aligned at the bottom. Alignment can be specified in horizontal or vertical orientations, but for most sizers, only one of these will have an effect. For example, in Figure 7-5, we have specified alignment in the vertical orientation, but horizontal alignment isn't possible because of the way space is distributed among children of the sizer. (To achieve the effect of horizontal alignment, we would need to insert a stretching spacer, which we will look at shortly.)
Figure 7-5. Sizer alignment

If a sizer contains more than one child and is offered more space than its children and their borders need, the surplus space needs to be distributed among the children. For this purpose, a stretch factor may be assigned to each child, where the default value of zero indicates that the child will not get more space than its requested minimal size. A value of more than zero is interpreted in relation to the sum of all stretch factors in the children of the respective sizer, so if two children get a stretch factor of 1, they will each get half the extra space, independent of their minimal size. Figure 7-6 shows a dialog with three buttons, at the initial size and after resizing. The first button has a stretch factor of 1 and thus gets stretched, whereas the other two buttons have a stretch factor of zero and keep their initial width.
Figure 7-6. Stretch factor

