Subsections

List Widgets

   

The List widget allows selection from a variety of specified items. The List widget is actually one of the component widgets in the FileSelectionBox widget(Chapter 9).

The use of a List is similar to that of a Menu, but is a little more flexible:

An example of a List Widget is shown in Fig. 11.1.

 

Fig. 11.1 Output of list.c

List basics

To create a simple list use: XtVaCreateManagedWidget(), and specify
xmListWidgetClass as the widget type (or use XmCreateList(). The header file <Xm/List.h> must be included. We will usually want to create a ScrolledList. To do this use: XmCreateScrolledList().

There are a number of useful resources:

XmNitemCount
-- The number of items in the list.
XmNitems
-- The item list. The item list is a XmStringTable data type. This is basically a 1D array of XmStrings.

XmNselectionPolicy
  -- Controls how items are chosen (see Section 11.1.1 below).
XmNvisibleItemCount
  -- The number of items shown in the list. This determines height of widget.
XmNscrollBarDisplayPolicy
  -- Either XmAS_NEEDED or XmSTATIC. XmSTATIC will always show (vertical) scroll even if all items are visible.
XmNlistSizePolicy
  -- XmCONSTANT, XmRESIZE_IF_POSSIBLE or XmVARIABLE. Controls horizontal scrolling.
XmNselectedItemCount
  -- The number of selected items.
XmNselectedItems
  -- The selected items from the list. These can be set at list initialisation to enable a default choice to be specified.

List selection modes

    One primary distinction between a list and menu is in the methods of selection available. Four types of selection are available. The List resource XmNselectionPolicy  must be set accordingly:
Single
-- XmSINGLE_SELECT (defined in <Xm/List.h>). Only one item may be selected.
Browse
-- XmBROWSE_SELECT. Similar to Single selection, except a default selection can be provided and user interaction may vary.
Multiple
-- XmMULTIPLE_SELECT. More than one item may be selected. A mouse click on a item will select it. If you click on an already selected item it will be deselected.
Extended
-- XmEXTENDED_SELECT. Like Multiple selection. Here you can drag the mouse over a number of items to select them.

Adding and removing list items

 

As the name of this widget implies, the List is a dynamic structure that can grow or shrink as items are added or deleted.

To add an item to a list, use the function XmListAddItem() , which takes 3 arguments:

The List Widget
-- The widget we add items to,
Item
-- An (XmString) list item we wish to add,
Position
-- The (int) position. Note: List indexing Starts at index 1 (Die hard C programmers take note). Position 0 in the list is used to specify the last position in the list. If you specify a 0 position items will get appended to the end of the List.

Another function XmListAddItemUnselected()  has exactly the same syntax as XmListAddItem(), above. This function will guarantee that an item is not selected when it is added. This is not always the case with the XmListAddItem(), since selection will be dependent on the currently selected list index.

To remove a single named (XmString) item, str, from a List widget, use the
XmListDeleteItem(Widget List, XmString str)  function.

To remove a number of named (XmString) items, use the
XmListDeleteItems(Widget List, XmString *del_items)  function where the second argument, del_items, is an array of XmStrings that contain the names of items being deleted.

If you know the position of item(s) in a List, as opposed to their names, you can use the following functions:

XmListDeletePos(Widget wid, int pos)
  where the second pos argument specifies the deletion position.
XmListDeleteItemsPos(Widget wid, int num, int pos)
  where num items are deleted starting from position pos.

To delete all items form a list, use XmListDeleteAllItems(Widget wid).

Selecting and Deselecting items

 

Two functions XmListSelectItem(Widget, XmString, Boolean) and
XmListSelectPos(Widget, int, Boolean) may be used to select an item from within a program.

The Boolean value, if set to True, will call the callback function associated with the particular List.

To deselect items use XmListDeselectItem(Widget, XmString),
XmListDeselectPos(Widget, int) or XmListDeselectAllItems(Widget). The operation of which is similar to corresponding delete functions.

List Enquiry

 

Since the List is dynamic we may need to know how long the list is, and which items are currently selected etc.. Some of these values can be obtained from the callback structure of a list (see Section11.3 below). However, if no callback has been invoked the programmer may sometimes still need to access this information.

The List resources are updated automatically (by default callback resources) so all we need to do is to XtGetValues()  (or something similar) for the resource we want. For example:

Recall that the use of XtGetValue() is similar to that of XtSetValue() (Chapter[*]).

List Callbacks

  

Default List callback functions facilitate common interaction with a List such as selection of an item (or multiple items) and addition or deletion of items. More importantly, related resource information is automatically updated ( e.g. the current List size, XmNitemCount). There is a List callback resource for each of the selection types (e.g. XmNsingleSelectionCallback ) and also a XmNdefaultActionCallback . The application programmer is free to add his own callback functions in the usual manner. In this case, the selection policy callback will be called first and then the default.

The Callback function has the usual form:



list_cbk(Widget w, XtPointer data, XmListCallbackStruct *cbk)  



Elements of the XmListCallbackStruct include:

item
-- the XmString of the selection.
item_position
-- position in the List.
selected_items
-- the List of XmStrings in multiple selections.
selected_item_count
-- number of multiple selections.
selected_item_positions
-- positions in the List.

An example of the use of a List callback is given in the following list.c example program.

The list.c program

   An example of a List in action is given in list.c.

We create a simple list that shows a selection of colours. Selection of these colours changes the background colour[*] of the List widget.

#include <Xm/Xm.h>
#include <Xm/List.h>


/* Prototype Callback */

void list_cbk(Widget , XtPointer , 
              XmListCallbackStruct *);

String colours[] = { "Black",  "Red", "Green", 
                     "Blue", "Grey"};

Display *display; /* xlib id of display */
Colormap cmap;
 
main(int argc, char *argv[])
 
{
    Widget           top_wid, list;
    XtAppContext     app;
    int              i, n = XtNumber(colours);
    XColor           back, fore, spare;
    XmStringTable    str_list;
    Arg              args[4];
    

    top_wid = XtVaAppInitialize(&app, "List_top", NULL, 0,
        &argc, argv, NULL, NULL);

    str_list = 
      (XmStringTable) XtMalloc(n * sizeof (XmString *));

    for (i = 0; i < n; i++)
        str_list[i] = XmStringCreateSimple(colours[i]);

    list = XtVaCreateManagedWidget("List",
        xmListWidgetClass,     top_wid,
        XmNvisibleItemCount,   n,
        XmNitemCount,          n,
        XmNitems,              str_list,
        XmNwidth,               300,
        XmNheight,              300,
        NULL);
 
    for (i = 0; i < n; i++)
        XmStringFree(str_list[i]);
    XtFree(str_list);
        
    /* background pixel to black foreground to white */
    
    cmap = DefaultColormapOfScreen(XtScreen(list));
    display = XtDisplay(list);
    
    XAllocNamedColor(display, cmap, colours[0], &back, 
                     &spare);
    XAllocNamedColor(display, cmap, "white", &fore, &spare);
   
    n = 0;
    XtSetArg(args[n],XmNbackground, back.pixel);      
    ++n;
    XtSetArg(args[n],XmNforeground, fore.pixel);      
    ++n;
    XtSetValues(list, args, n);
    
    XtAddCallback(list, XmNdefaultActionCallback, list_cbk, 
                  NULL);

    XtRealizeWidget(top_wid);
    XtAppMainLoop(app);
}
 
/* called from any of the "Colour" list items.  
   Change the color of the list widget. 
   Note: we have to use dynamic setting with XtSetValues()..
 */
void list_cbk(Widget w, XtPointer data, 
         XmListCallbackStruct *list_cbs)

{   int n =0;
    Arg args[1];
    String selection;
    XColor xcolour, spare; /* xlib color struct */
        
    /* list->cbs holds XmString of selected list item */
    /* map this to "ordinary" string */
   
    XmStringGetLtoR(list_cbs->item, XmSTRING_DEFAULT_CHARSET, 
                    &selection);
       
    if (XAllocNamedColor(display, cmap, selection, 
                         &xcolour, &spare) == 0)
       return;
           
    XtSetArg(args[n],XmNbackground, xcolour.pixel);      
    ++n;
    /* w id of list widget passed in */
    XtSetValues(w, args, n); 
  
}

Exercises

Needs SOME


Dave Marshall
1/5/1999