Because the implementation of the UI Engine varies with operating environment, specifying widget layout such that the result is visually appealing can be a challenge. Explicit placement of widgets does not work very well in this situation because widget sizes are not known in advance. Moreover, the precise horizontal and vertical alignment of widgets and the specification of resize behavior is a tedious task even with the help of the Composition Editor. This led to the integration of layout management in ULC, based on a hierarchical and high-level layout description rather than on the explicit placement of widgets, which handles resize behavior automatically.
The ULC layout widgets employ three basic layout types:
All widgets that use the first two layout types incorporate the notions of
cell and cell alignment. A cell is a space which
can be empty or can accommodate a single widget. The size of a cell is
always equal to or larger than the minimum size of the enclosed widget (if
any). If the cell is larger than the minimum size, the cell alignment
specifies what to do with the extra space. Possible options are to
expand the widget until it fills the cell completely or to align the widget
within its cell. The following illustration shows all possible cell
alignments:
The simplest example for a cell is the GroupBox widget. GroupBox has
a single cell and draws a border line and title around it. The size of
the cell is determined based on the natural size of the enclosed
widget. If GroupBox is made larger, the alignment is used to determine
how to align the content widget.
Shell and Page also use Border layout to create a margin around their content areas.
Box lays out cells in a two-dimensional grid separated by horizontal and
vertical gaps. The width of a column is determined by the maximum width
of all widgets in the corresponding column. The height of a row is
determined by the maximum height of all widgets in that row.
If the box is made larger than its minimal size, any extra space is distributed evenly among expandable rows or columns. A row or column is expandable if at least one cell attribute in that row (or column) is set to expand. If expandable rows or columns do not exist, the box is centered within its cell bounds.
Box cells can span multiple columns or rows. In this case, the cell
alignment applies just as for the spanning cell. If the spanning
specification results in overlapping cells, the (visual) result is
undefined.
Notebook piles tabbed Page widgets on top of each other and shows only the
topmost page. By selecting a tab, users can switch between pages
interactively. The size of Notebook is determined by the maximum size
of all pages.
Like Notebook, Pagebook piles Page widgets, but Pagebook pages have no tabs. Page switching is completely under program control. Pagebook is used to implement dynamic layout, that is, to switch between different widget subtrees programmatically.