12.3.6 CheckBoxes
A CheckBox is similar to a RadioBox, except that there is no restriction on how many items may be selected at once.
A word processing program might use a CheckBox for non-exclusive settings, such as whether font smoothing,
bitmap smoothing, or both, should be applied.
Like RadioBoxes, CheckBoxes are implemented using RowColumn widgets and ToggleButton children. To allow
multiple items to be selected, the XmNradioBehavior resource is set to False. The convenience routine
XmVaCreateSimpleCheckBox() works just like the radio box creation routine, except that it turns off the
XmNradioBehavior resource. Rather than using this function, we can simply create a common RowColumn
widget without the aid of convenience functions and add ToggleButton children. With this technique, we have more
direct control over the resources that are set in the RowColumn, since we can specify exactly which ones we want
using the varargs interface for creating the widget.
the source code demonstrates how to create a CheckBox with a regular RowColumn widget.
XtSetLanguageProc() is only available in X11R5; there is no corresponding function in X11R4.
/* toggle_box.c −− demonstrate a homebrew ToggleBox. A static
* list of strings is used as the basis for a list of toggles.
* The callback routine toggled() is set for each toggle item.
* The client data for this routine is set to the enumerated
* value of the item with respect to the entire list. This value
* is treated as a bit which is toggled in "toggles_set" −− a
* mask that contains a complete list of all the selected items.
* This list is printed when the PushButton is selected.
*/
#include <Xm/ToggleBG.h>
#include <Xm/PushBG.h>
#include <Xm/SeparatoG.h>
#include <Xm/RowColumn.h>
unsigned long toggles_set; /* has the bits of which toggles are set */
char *strings[] = {
"One", "Two", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Ten",
};
/* A RowColumn is used to manage a ToggleBox (also a RowColumn) and
* a PushButton with a separator gadget in between.
*/
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, rowcol, toggle_box, w;
XtAppContext app;
void toggled(), check_bits();
int i;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
rowcol = XtVaCreateManagedWidget ("rowcolumn",
xmRowColumnWidgetClass, toplevel,
12 Labels and Buttons 12.3.6 CheckBoxes
328
NULL);
toggle_box = XtVaCreateWidget ("togglebox",
xmRowColumnWidgetClass, rowcol,
XmNpacking, XmPACK_COLUMN,
XmNnumColumns, 2,
NULL);
/* simply loop thru the strings creating a widget for each one */
for (i = 0; i < XtNumber (strings); i++) {
w = XtVaCreateManagedWidget (strings[i],
xmToggleButtonGadgetClass, toggle_box, NULL);
XtAddCallback (w, XmNvalueChangedCallback, toggled, i);
}
XtVaCreateManagedWidget ("sep",
xmSeparatorGadgetClass, rowcol, NULL);
w = XtVaCreateManagedWidget ("Check Toggles",
xmPushButtonGadgetClass, rowcol, NULL);
XtAddCallback (w, XmNactivateCallback, check_bits, NULL);
XtManageChild (rowcol);
XtManageChild (toggle_box);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* callback for all ToggleButtons. */
void
toggled(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
int bit = (int) client_data;
XmToggleButtonCallbackStruct *toggle_data =
(XmToggleButtonCallbackStruct *) call_data;
if (toggle_data−>set) /* if the toggle button is set, flip its bit */
toggles_set |= (1 << bit);
else /* if the toggle is "off", turn off the bit. */
toggles_set &= ~(1 << bit);
}
void
check_bits(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
int i;
printf ("Toggles set:");
for (i = 0; i < XtNumber (strings); i++)
if (toggles_set & (1<<i))
printf (" %s", strings[i]);
putchar ('0);
}
The output of this program is shown in the figure.
12 Labels and Buttons 12.3.6 CheckBoxes
329
Output of toggle_box.c
This example is similar to the previous RadioBox examples, except that since more than one of the buttons may be set
at a time in a CheckBox, we can no longer use toggle_item_set the way we did in the previous examples.
Instead, we are going to change its name to toggles_set and its type to unsigned long. This time we are going
to use the variable as a mask, which means that its individual bits have meaning, rather than the combined value of the
variable. The bits indicate which of the ToggleButtons have been set. Each time a ToggleButton changes its value, the
callback routine flips the corresponding bit in the mask. We can therefore determine at any given time which buttons
are set and which are not. The unsigned long type can only represent up to 32 ToggleButtons. If more buttons are
used within the CheckBox, a new mechanism is needed, although the basic design presented here can still be used.
The PushButton in the program provides a way to check the state of all of the ToggleButtons. The callback routine for
the PushButton prints the strings of those buttons that are selected by looping through the toggles_set variable
and checking for bits that have been set.
One interesting aspect of this program is that it works just as well if the CheckBox is a RadioBox. To test this
statement, we can run the program again with the radioBehavior resource set to True via the −xrm
command−line option:
toggle_box −xrm "*radioBehavior: True"
The result is shown in the figure.
12 Labels and Buttons 12.3.6 CheckBoxes
330

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.