XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg (args[n], XmNeditable, False); n++;
XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
XtSetArg (args[n], XmNwordWrap, True); n++;
XtSetArg (args[n], XmNvalue, buf); n++;
XtSetArg (args[n], XmNrows, 5); n++;
text_w = XmCreateScrolledText(form, "help_text", args, n);
XtVaSetValues (XtParent (text_w),
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, label,
XmNtopAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
NULL);
XtManageChild (text_w);
In order to use XmCreateScrolledText(), we must use the old−style XtSetArg() method of setting the
resources that are passed to the function. The routine actually creates two widgets that appear to be a single interface
object. A ScrolledWindow widget and a Text widget are created so that the Text widget is a child of the
ScrolledWindow. The toolkit returns a handle to the Text widget, but since the ScrolledWindow widget is the direct
child of the Form, we set the constraint resources on the ScrolledWindow, not the Text widget. The top, right, and
bottom sides of the ScrolledWindow are attached to the Form, while the left side is attached to the Label widget, so
that the two widgets are always positioned next to each other.
We could have passed these resource/value pairs in the args list, but then the resources would have been set on both
the ScrolledWindow widget and the Text widget. Since the attachment constraints would be ignored by the Text
widget, there would be no real harm in setting them on both widgets. However, it is better programming style to set
the resources directly on the ScrolledWindow. Details on the Text widget and the ScrolledText object can be found in
Chapter 14, Text Widgets. Chapter 9, ScrolledWindows and ScrollBars, discusses the ScrolledWindow widget and
its resources.
The text for the widget is set using the XmNvalue resource. The value for this resource is the appropriate help text
taken from the help_texts array declared at the beginning of the program. We set the XmNeditable resource to
False so that the user cannot edit the help text.
The Text and Label widgets are the only two items in the Form widget. Once these children are created and managed,
the Form can be managed using XtManageChild().
8.3.4 The Action Area
At this point, the control area of the dialog has been created, so it is time to create the action area. In our example, the
action area is pretty simple, as the only action needed is to close the dialog. We use the OK button for this action. For
completeness, we have also provided a More button to support additional or extended help. Since we don't provide
any additional help, we set this button insensitive (although you can extend this example by providing it).
The action area does not have to be contained in a separate widget, although it is generally much easier to do so. We
use a Form widget in order to position the buttons evenly across the width of the dialog. We create the Form as
follows:
form = XtVaCreateWidget ("form2", xmFormWidgetClass, pane,
XmNfractionBase, 5,
NULL);
8 Custom Dialogs 8.3.4 The Action Area
186
The XmNfractionBase resource of the Form widget is set to five, so that the Form is broked down into five equal
units, as shown in the figure.
The XmNfractionBase resource divides the Form into equal units
Position zero is the left edge of the form and position five is the right edge of the form. We chose five because it gave
us the best layout aesthetically. The region is divided up equally, so you can think of the sections as percentages of the
total width (or height) of the Form. By using this layout method, we don't have to be concerned with the width of the
Form or of the DialogShell itself, since we know that the placement of the buttons will always be proportional. We
create the OK button as shown in the following code fragment:
widget = XtVaCreateManagedWidget ("OK",
xmPushButtonGadgetClass, form,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 1,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 2,
XmNshowAsDefault, True,
XmNdefaultButtonShadowThickness, 1,
NULL);
The left and right sides of the button are placed at positions one and two, respectively. Since this button is the default
button for the dialog, we want the button to be displayed as such. We set XmNshowAsDefault to True and
XmNdefaultButtonShadowThickness to 1. The value for the latter resource is a pixel value that specifies the
width of an extra three−dimensional border that is placed around the default button to distinguish it from the other
buttons. If the value for XmNshowAsDefault is False, the button is not shown as the default, regardless of the
value of the default shadow thickness. The XmNshowAsDefault resource can also take a numeric value that
indicates the shadow thickness to use, but its value is only interpreted in this way if
XmNdefaultButtonShadowThickness is set to 0. This functionality is for backwards compatibility with Motif
1.0 and should not be used.
Because the dialog is not reused, we want the callback for the OK button to destroy the DialogShell. We use the
XmNactivateCallback of the PushButton to implement the functionality. The callback routine is
DestroyShell(), which is shown below:
static void
DestroyShell(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
8 Custom Dialogs 8.3.4 The Action Area
187
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.