Les widgets de type List


Table des matières :


Introduction :


Les widgets de type List permettent à l'utilisateur de choisir un ou plusieurs éléments appartenant à... une liste d'éléments!

Nous avons déjà rencontré inconsciemment des widgets de type List, par exemple lors de l'étude des FileSelectionDialog. Les deux boîtes contenant les noms des répertoires et les noms des fichiers d'un FileSelectionDialog sont des widgets de type List.

La manipulation des List est similaire à celle des PulldownMenus. Cependant, avec un widget de type List :

Voici un exemple de widget de type List:


Modes de sélection des éléments d'une liste


Quatre modes de sélection sont disponibles, on choisit l'un des modes en positionnant la ressource XmNselectionPolicy avec l'une de ces valeurs :

XmSINGLE_SELECT
Un seul item de la liste peut être sélectionné.

XmBROWSE_SELECT
Similaire à XmSINGLE_SELECT sauf qu'une valeur par défaut peut être choisie. L'interaction avec l'utilisateur est par conséquent légèrement différente.

XmMULTIPLE_SELECT
Plusieurs sélections sont possibles. Un élément est choisi en clickant dessus. Si on clicke à nouveau sur un élément déjà choisi, on annule sa sélection.

XmEXTENDED_SELECT
Similaire au mode précédent sauf que l'on peut sélectionner plusieurs éléments contigus en clickant avec la souris sur un élément puis en faisant glisser la souris sur d'autres éléments en maintenant le bouton enfoncé.


Principes de base d'utilisation des List widgets


Création widgets de type List ou ScrolledList :

Pour créer un List widget on utilisera les fonctions habituelles
XmCreateList() ou XtVaCreateManagedWidget() avec comme classe xmListWidgetClass.

Le plus souvent on désire créer des listes possèdant des barres de scrolling. On utilisera alors la fonction XmCreateScrolledList().

Principales ressources :

XmNitemCount
Nombre d'éléments dans la liste.

XmNitems
La liste des éléments. Elle doit être de type XmStringTable, qui est un type correspondant à un tableau unidimmensionnel d'objets de type XmString.

XmNselectionPolicy
Mode de sélection des éléments. Voir plus haut.

XmNvisibleItemCount
Nombre d'éléments visibles dans la fenêtre du widget de type List. Cette ressource détermine en fait la hauteur du widget.

XmNdisplayScrollBarPolicy
Cette ressource permet de sélectionner l'apparition de la barre de scrolling. Deux valeurs sont possibles :
  1. XmSTATIC : une barre de scrolling verticale sera toujours présente sur le bord de la boîte contenant les éléments de la liste.
  2. XmAS_NEEDED : la barre de scrolling ne sera affichée que si tous les éléments ne contiennent pas dans la boîte d'affichage.

XmNlistSizePolicy
Cette ressource permet de sélectionner les différents modes de retaillage du widget de type List. Trois valeurs sont possibles :

  1. XmCONSTANT : la taille est constante.
  2. XmRESIZE_IF_POSSIBLE : la taille peut varier si possible, c'est-à-dire si le widget parent le permet.
  3. XmVARIABLE :

XmNselectedItemCount
Nombre d'éléments séléctionnés par défaut.

XmNselectedItems
La liste des éléments séléctionnés.

Ajout et retrait d'éléments :

Pour ajouter un élément dans un List widget, on utilise la fonction MOTIF XmListAddItem(), qui accepte trois arguments :

Une autre fonction, XmListAddItemUnselected() possède exactement la même syntaxe. Elle garantit qu`un élément n'est jamais séléctionné lorsqu'il est ajouté à la liste, ce qui n'est pas toujours le cas avec la fonction XmListAddItem().

Pour supprimer un seul élément d'une liste il faut utiliser la fonction XmListDeleteItem(Widget, XmString).

Pour supprimer plusieurs éléments d'une liste il faut utiliser la fonction XmListDeleteItems(Widget, XmString*).

Si la position du ou des éléments(s) à supprimer est connue, on peut utiliser également la fonction XmListDeletePos(Widget w, int num, int Pos). Elle permet de détruire num éléments à partir de la position pos.

Pour détruire tous les éléments d'une liste, on utilisera la fonction XmListDeleteAllItems(Widget)

Sélection d'éléments dans une liste:

Pour sélectionner des éléments dans une liste on utilisera les fonctions XmListSelectItem(Widget, XmString, Boolean) et XmListSelectPos(Widget, int, Boolean).

Si la valeur de type Boolean est égale à True, alors la fonction de callback de la liste sera appelée lors de la sélection (Les fonctions de callback sont détaillées dans la section suivante).

Pour désélectionner des éléments d'une liste, on utilisera une des fonctions : XmListDeselectItem(Widget, XmString), XmListDeselectPos(Widget, int) ou XmListDeselectAllItems(Widget).

Obtenir des informations sur une liste :

Etant donné que les widgets de type List évoluent dynamiquement (on ajoute et on enlève des éléments de la liste pendant l'exécution de l'application), il peut être nécessaire de connaître à un moment donné la valeur de certains attributs de la liste, par exemple le nombre d'éléments se trouvant dans la liste, l'ensemble des éléments sélectionnés, etc...

On obtient toutes ces informations à l'aide de la fonction XtGetValues(), déjà étudiée, qui permet de consulter la valeur des ressources d'un widget. En effet, les ressourrrces des List widgets sont mises à jour dynamiquement pendant l'exécution de l'application.

Les fonctions de callbacks :

Il existe une ressource de callback pour chaque mode de sélection :XmNsingleSelectionCallback, XmNmultipleSelectionCallback, XmNbrowseSelectionCallback et XmNextendedSelectionCallback; et une ressource de callback par default : XmNdefaultActionCallback.

La fonction de callback par défaut est toujours appelée après la fonction de callback correspondant à la sélection d'un ou plusieurs éléments.

Le callback de sélection est déclenché lors d'un double click sur un élément.

Les fonctions de callback pour les List widgets ont la forme suivante :



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


Les champs intéressants de la structureXmListCallbackStruct sont les suivants :

Vous pouvez vous référer à la doc MOTIF ou bien regarder le contenu de <XM/List.h> pour obtenir plus d'informations.


Petit programme d'exemple : list.c


Ce petit programme crée une liste de noms de couleurs. La sélection des différents éléments change la couleur de fond du List widget, en utilisant une méthode similaire à celle déjà étudiée avec le programme menu_pull.c

L'exécutable se trouve dans :

    /home/profs/cours/minfo/motif/list/list

Voici à quoi ressemble l'exécution de ce petit programme :



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

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

Display *display; /* xlib id of display */
Colormap cmap;

/*---------------*/ 
main(argc, argv)
/*---------------*/
char *argv[];
{
  Widget           top_wid, list;
  XtAppContext     app;
  int              i, nb_items = XtNumber(colours);
  XColor           back, fore, spare;
  XmStringTable    str_list;
  int              n = 0;
  Arg              args[10];
  void             list_cbk();

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


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

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

  n=0;
  XtSetArg(args[n], XmNvisibleItemCount, nb_items); n++;
  XtSetArg(args[n], XmNitemCount, nb_items); n++;
  XtSetArg(args[n], XmNitems, str_list); n++;
  /* The next ressources should be in a ressource file */
  XtSetArg(args[n], XmNwidth, 300); n++;
  XtSetArg(args[n], XmNheight, 300); n++;
  list = XmCreateList(top_wid, "list1", args, n);
  XtManageChild(list);

  for (i = 0; i < nb_items; i++)
    XmStringFree(str_list[i]);
  XtFree((char *) 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);
}

/*-----------------------------------------*/
void list_cbk(Widget w, XtPointer data, 
	      XmListCallbackStruct *list_cbs)
/*-----------------------------------------*/
/* called from any of the "Colour" list items.  
   Change the color of the list widget. 
   Note: we have to use dynamic setting with setargs()*/
{   
  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); 
}



michel.buffa@essi.fr