Output of rowcol.c with a horizontal orientation
If you use a RowColumn widget to manage more objects than can be arranged in a single row or column, you can
specify that the widgets should be arranged in both rows and columns. You can also specify whether the widgets
should be packed together tightly, so that the rows and columns are not necessarily the same size, or whether the
objects should be placed in identically−sized boxes. As with the Form and BulletinBoard widgets, objects can also be
placed at specific x, y locations in a RowColumn widget. The RowColumn widget does not provide a
three−dimensional border, so if you want to provide a visual border for the widget, you should create it as a child of a
Frame widget.
9.5.1 Rows and Columns
The RowColumn widget can be quite flexible in terms of how it lays out its children. The advantage of this flexibility
is that all of its child widgets are arranged in an organized fashion, regardless of their widget types. The widgets
remain organized when the RowColumn is resized and in spite of constraints imposed by other widgets or by
resources. One disadvantage of the flexibility is that sometimes the children need to be arranged in a specific layout so
that the user interface is intuitive.
the source code shows how to lay out widgets in a spreadsheet−style format using a RowColumn. This layout requires
that each of the widgets be the same size and be spaced equally in a predetermined number of rows and columns.
XtSetLanguageProc() is only available in X11R5; there is no corresponding function in X11R4.
/* spreadsheet.c −− This demo shows the most basic use of the RowColumn
* It displays a table of widgets in a row−column format similar to a
* spreadsheet. This is accomplished by setting the number ROWS and
* COLS and setting the appropriate resources correctly.
*/
#include <Xm/LabelG.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#define ROWS 8
#define COLS 10
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, parent;
XtAppContext app;
char buf[16];
9 Manager Widgets 9.5.1 Rows and Columns
226
int i, j;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
parent = XtVaCreateManagedWidget ("rowcolumn",
xmRowColumnWidgetClass, toplevel,
XmNpacking, XmPACK_COLUMN,
XmNnumColumns, COLS,
XmNorientation, XmVERTICAL,
NULL);
/* simply loop thru the strings creating a widget for each one */
for (i = 0; i < COLS; i++)
for (j = 0; j < ROWS; j++) {
sprintf (buf, "%d−%d", i+1, j+1);
if (i == 0 || j == 0)
XtVaCreateManagedWidget (buf,
xmLabelGadgetClass, parent, NULL);
else
XtVaCreateManagedWidget ("",
xmPushButtonWidgetClass, parent, NULL);
}
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
The output of this example is shown in the figure.
Output of spreadsheet.c
The number of rows is specified by the ROWS definition and the number of columns is specified by COLS. In order to
force the RowColumn to lay out its children in the spreadsheet format, we set the XmNpacking, XmNnumColumns,
and XmNorientation resources.
The value for XmNpacking is set to XmPACK_COLUMN, which specifies that each of the cells should be the same
size. The heights and widths of the widgets are evaluated and the largest height and width are used to determine the
size of the rows and columns. All of the widgets are resized to this size. If you are mixing different widget types in a
9 Manager Widgets 9.5.1 Rows and Columns
227
RowColumn, you may not want to use XmPACK_COLUMN because of size variations. XmPACK_COLUMN is typically
used when the widgets are exactly the same, or at least similar in nature. The default value of XmPACK_TIGHT for
XmNpacking allows each widget to keep its specified size and packs the widgets into rows and columns based on
the size of the RowColumn widget.
Since we are packing the widgets in a row/column format, we need to specify how many columns (or rows) we are
using by setting the value of XmNnumColumns to the number of columns. In this case, the program defines COLS to
be 10, which indicates that the RowColumn should pack its children such that there are 10 columns. The widget
creates as many rows as necessary to provide enough space for all of the child widgets.
Whether XmNnumColumns specifies the number of columns or the number of rows depends on the orientation of the
RowColumn. In this program, XmNorientation is set to XmVERTICAL to indicate that the value of
XmNnumColumns specifies the number of columns to use. If XmNorientation is set to XmHORIZONTAL,
XmNnumColumns indicates the number of rows. If we wanted to use a horizontal orientation in our example, we
would set XmNnumColumns to ROWS and XmNorientation to XmHORIZONTAL. The orientation also dictates
how children are added to the RowColumn; when the orientation is vertical, children are added vertically so that each
column is filled up before the next one is started. If you need to insert a child in the middle of an existing RowColumn
layout, you can use the XmNpositionIndex constraint resource to specify the position of the child. Since this
resource is used most often with menus, it is discussed in Chapter 15, Menus.
In our example, we explicitly set the value of XmNorientation to the default value of XmVERTICAL. If we do not
hard−code this resource, an external resource specification can reset it. Since the orientation and the value for
XmNnumColumns need to be consistent, you should always specify these resources together. Whether you choose to
hard−code the resources, to use the fallback mechanism, or to use a specification in a resource file, you should be sure
that both of the resources are specified in the same place.
In the spreadsheet example, we can use either a horizontal or vertical orientation. However, orientation may be
significant in other situations, since it affects how the RowColumn adds its children. For example, if we want to
implement the text−entry form from the source code using a RowColumn, the order of the widgets is important. In this
case, there are two columns and the number of rows depends on the number of text entry fields provided by the
application. We specify the orientation of the RowColumn as XmHORIZONTAL and set -XmNnumColumns to the
number of entries provided by the application, as shown in the source code XtSetLanguageProc() is only
available in X11R5; there is no corresponding function in X11R4.
/* text_entry.c −− This demo shows how the RowColumn widget can be
* configured to build a text entry form. It displays a table of
* right−justified Labels and Text widgets that extend to the right
* edge of the Form.
*/
#include <Xm/LabelG.h>
#include <Xm/RowColumn.h>
#include <Xm/Text.h>
char *text_labels[] = {
"Name:", "Phone:", "Address:", "City:", "State:", "Zip Code:",
};
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, rowcol;
XtAppContext app;
char buf[8];
9 Manager Widgets 9.5.1 Rows and Columns
228
int i;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
rowcol = XtVaCreateWidget ("rowcolumn",
xmRowColumnWidgetClass, toplevel,
XmNpacking, XmPACK_COLUMN,
XmNnumColumns, XtNumber (text_labels),
XmNorientation, XmHORIZONTAL,
XmNisAligned, True,
XmNentryAlignment, XmALIGNMENT_END,
NULL);
/* simply loop thru the strings creating a widget for each one */
for (i = 0; i < XtNumber (text_labels); i++) {
XtVaCreateManagedWidget (text_labels[i],
xmLabelGadgetClass, rowcol,
NULL);
sprintf (buf, "text_%d", i);
XtVaCreateManagedWidget (buf,
xmTextWidgetClass, rowcol,
NULL);
}
XtManageChild (rowcol);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
The output of this example is shown in the figure.
Output of text_entry.c
9 Manager Widgets 9.5.1 Rows and Columns
229

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.