[GUI] Dynamic sizing.

Glynn Clements glynn.clements@virgin.net
Sat, 26 Apr 2003 21:29:33 +0100


Wolfgang Thaller wrote:

> Question to all: Who is not familiar either with Java's GridBagLayout=
=20
> or with Tcl's "grid" geometry manager?  (BTW: Is XmRowColumn the same=
=20
> thing or something different?)

Well, XmRowColumn is a widget class, whereas the other two are
"standalone" geometry managers.

Apart from that, XmRowColumn isn't as flexible the other two case; it
won't suffice as a general-purpose container. It's mostly used where
you want to arrange all of the children in a single row or column
(e.g. menu bars, menus).

Motif's "generic" container widget is XmForm. This allows you to place
the children arbitrarily, with the edges positioned using attachments.

Each child of an XmForm has four constraint resources for each of the
four edges (i.e. sixteen resources in total). E.g. the placement of
the bottom edge is controlled by:

=09XmNbottomAttachment
=09XmNbottomOffset
=09XmNbottomPosition
=09XmNbottomWidget

The attachment resource is set to one of the following:

=09XmATTACH_NONE
=09=09Do not attach the bottom side  of  the
=09=09child.
=09
=09XmATTACH_FORM
=09=09Attach the bottom side of the child to
=09=09the bottom side of the Form.
=09
=09XmATTACH_OPPOSITE_FORM
=09=09Attach the bottom side of the child to
=09=09the  top  side of the Form.  XmNbotto=AD
=09=09mOffset can be used to  determine  the
=09=09visibility of the child.
=09
=09XmATTACH_WIDGET
=09=09Attach the bottom side of the child to
=09=09the top side of the widget  or  gadget
=09=09specified   in   the   XmNbottomWidget
=09=09resource.  If XmNbottomWidget is NULL,
=09=09XmATTACH_WIDGET  is  replaced by XmAT=AD
=09=09TACH_FORM, and the child  is  attached
=09=09to the bottom side of the Form.
=09
=09XmATTACH_OPPOSITE_WIDGET
=09=09Attach the bottom side of the child to
=09=09the bottom side of the widget or  gad=AD
=09=09get  specified  in the XmNbottomWidget
=09=09resource.
=09
=09XmATTACH_POSITION
=09=09Attach the bottom side of the child to
=09=09a position that is relative to the top
=09=09side of the Form and in proportion  to
=09=09the height of the Form.  This position
=09=09is determined by the XmNbottomPosition
=09=09and XmNfractionBase resources.
=09
=09XmATTACH_SELF
=09=09Attach the bottom side of the child to
=09=09a position that is proportional to the
=09=09current  y  value of the bottom of the
=09=09child divided by  the  height  of  the
=09=09Form.   This position is determined by
=09=09the XmNbottomPosition and XmNfraction=AD
=09=09Base  resources.  XmNbottomPosition is
=09=09set to a  value  proportional  to  the
=09=09current  y  value of the bottom of the
=09=09child divided by  the  height  of  the
=09=09Form.

Similarly for the other three edges.

Also, you can choose whether to specify attachments for both edges of
an opposing pair (top/bottom, left/right), or only one edge; in the
latter case, the position of the other edge is determined by the
widget's preferred size.

Consider a specific example. A dialog has a label across the top, a
list in the middle with a scrollbar to its right, and some buttons
across the bottom.

The label has its top, left and right edges attached to the top, left
and right edges of the form, and its bottom edge unattached.

The buttons have their bottom edges attached to the bottom of the
form. The first button has its left edge attached to the left of the
form; the other buttons have their left edges attached to the right
edge of the previous button. Their right and top edges are unattached.

The scrollbar has its top edge attached to the bottom of the label,
its bottom edge attached to the top of one of the buttons, its right
edge attached to the right edge of the form, and its left edge
unattached.

The list has its top and bottom edges attached to the top and bottom
of the scrollbar, its right edge attached to the left edge of the
scrollbar, and its left edge attached to the left edge of the form.

If the dialog is resized vertically, the label and buttons will retain
their sizes and their positions relative to their associated edges,
while the list and scrollbar will grow or shrink accordingly.=20

Similarly, if the dialog is resized horizontally, the buttons and
scrollbar will retain their sizes and relative positions, while the
label and list will grow or shrink accordingly.

> That's the best way of managing dynamic layouts that I know. Any=20
> reasons for not using something like that?

I find that the mechanisms used by Java and Tcl tend to be a bit too
explicit in the actual placement and sizing of widgets. Motif prefers
to allow widgets to size themselves, with the size and layout of the
parent adjusting accordingly.

This simplifies i18n; you don't have to manually create separate
layouts for e.g. English ("medium" sized words, "normal" font height),
German/Scandanavian (often longer words) and Japanese/Chinese (shorter
words, taller font).

For more complex layouts, it's common to create a hierarchy of nested
containers.

E.g., for a situation which XmForm's layout strategy doesn't handle,
consider the situation with the above example if the buttons at the
bottom of the dialog had differing preferred heights. You would
probably want to have the other buttons enlarged to match the tallest,
or at least align the bottom of the list and scrollbar with the top of
the tallest button.

To allow for that, the typical solution would be to place the buttons
inside their own container (either XmRowColumn, or XmForm with all
buttons having their top and bottom edges attached to the matching
edge of the form); the container's preferred size will be as tall as
the tallest child.

Nesting may also be used for stylistic reasons, i.e. to group together
sets of related widgets; Windows dialogs often do this, although it
isn't necessary for layout purposes (fixed placement).

--=20
Glynn Clements <glynn.clements@virgin.net>