operations, such as adding items to the List, removing items, and locating items.
13.3.1 Adding Items
The entire list of choices may not always be available at the time the List is created. In fact, it is not uncommon to
have no items available for a new list. In these situations, items can be added to the list dynamically using the
following functions XmListAddItem(), XmListAddItemUnselected(), XmListAddItems(), and
XmListAddItemsUnselected(). XmListAddItemsUnselected() is a new routine in Motif 1.2. These
functions take the following form:
void
XmListAddItem(list_w, item, position)
Widget list_w;
XmString item;
int position;
void
XmListAddItemUnselected(list_w, item, position)
Widget list_w;
XmString item;
int position;
void
XmListAddItems(list_w, items, item_count, position)
Widget list_w;
XmString *items;
int item_count;
int position;
void
XmListAddItemsUnselected(list_w, items, item_count, position)
Widget list_w;
XmString *items;
int item_count;
int position;
These routines allow you to add one or more items to a List widget at a specified position. Remember that list
positions start at 1, not 0. The position 0 indicates the last position in the List; specifying this position appends the
item or items to the end of the list. If the new item(s) are added to the list in between existing items, the rest of the
items are moved down the list.
The difference between XmListAddItem() and XmListAddItemUnselected() is that
XmListAddItem() compares each new item to each of the existing items. If a new item matches an existing item
and if the existing item is selected, the new item is also selected. XmListAddItemUnselected() simply adds
the new item without performing this check. In most situations, it is clear which routine you should use. If you know
that the new item does not already exist, you should add it unselected. If the List is a single selection list, you should
add new items as unselected. The only time that you should really add new items to the list using
XmListAddItem() is when there could be duplicate entries, the list supports multiple selections, and you explicitly
want to select all new items whose duplicates are already selected. The same is true of the routines that add multiple
items.
the source code shows how items can be added to a ScrolledList dynamically using
XmListAddItemUnselected(). XtSetLanguageProc() is only available in X11R5; there is no
corresponding function in X11R4. XmStringCreateLocalized() is only available in Motif 1.2;
13 The List Widget 13.3.1 Adding Items
347
XmStringCreateSimple() is the corresponding function in Motif 1.1. XmFONTLIST_DEFAULT_TAG replaces
XmSTRING_DEFAULT_CHARSET in Motif 1.2.
/* alpha_list.c −− insert items into a list in alphabetical order. */
#include <Xm/List.h>
#include <Xm/RowColumn.h>
#include <Xm/TextF.h>
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, rowcol, list_w, text_w;
XtAppContext app;
Arg args[5];
int n = 0;
void add_item();
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
rowcol = XtVaCreateWidget ("rowcol",
xmRowColumnWidgetClass, toplevel, NULL);
XtSetArg (args[n], XmNvisibleItemCount, 5); n++;
list_w = XmCreateScrolledList (rowcol, "scrolled_list", args, n);
XtManageChild (list_w);
text_w = XtVaCreateManagedWidget ("text",
xmTextFieldWidgetClass, rowcol,
XmNcolumns, 25,
NULL);
XtAddCallback (text_w, XmNactivateCallback, add_item, list_w);
XtManageChild (rowcol);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* Add item to the list in alphabetical order. Perform binary
* search to find the correct location for the new item position.
* This is the callback routine for the TextField widget.
*/
void
add_item(text_w, client_data, call_data)
Widget text_w;
XtPointer client_data;
XtPointer call_data;
{
Widget list_w = (Widget) client_data;
char *text, *newtext = XmTextFieldGetString (text_w);
XmString str, *strlist;
int u_bound, l_bound = 0;
/* newtext is the text typed in the TextField widget */
if (!newtext || !*newtext) {
/* non−null strings must be entered */
13 The List Widget 13.3.1 Adding Items
348
XtFree (newtext); /* XtFree() checks for NULL */
return;
}
/* get the current entries (and number of entries) from the List */
XtVaGetValues (list_w,
XmNitemCount, &u_bound,
XmNitems, &strlist,
NULL);
u_bound−−;
/* perform binary search */
while (u_bound >= l_bound) {
int i = l_bound + (u_bound − l_bound) / 2;
/* convert the compound string into a regular C string */
if (!XmStringGetLtoR (strlist[i], XmFONTLIST_DEFAULT_TAG, &text))
break;
if (strcmp (text, newtext) > 0)
u_bound = i − 1; /* newtext comes before item */
else
l_bound = i + 1; /* newtext comes after item */
XtFree (text); /* XmStringGetLtoR() allocates memory ... yuk */
}
str = XmStringCreateLocalized (newtext);
XtFree (newtext);
/* positions indexes start at 1, so increment accordingly */
XmListAddItemUnselected (list_w, str, l_bound+1);
XmStringFree (str);
XmTextFieldSetString (text_w, "");
}
In the source code the ScrolledList is created with no items. However, we do specify XmN-visibleItemCount, in
anticipation of items being added to the list. A TextField widget is used to prompt for strings that are added to the list
using the add_item() callback. This function performs a binary search on the list to determine the position where
the new item is to be added. A binary search can save time, as it is expensive to scan an entire List widget and convert
each compound string into a C string. When the position for the new item is found, it is added using
XmListAddItemUnselected(). The output of this program is shown in the figure.
Output of alpha_list.c
13 The List Widget 13.3.1 Adding Items
349

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.