Le widget GtkList sert de container vertical pour des widgets GtkListItem.
Un widget GtkList possède sa propre fenêtre pour recevoir les
événements et sa propre couleur de fond qui est habituellement
blanche. Comme il est directement dérivé de GtkContainer, il peut
être traité comme tel en utilisant la macro GTK_CONTAINER(List) :
voir le widget GtkContainer pour en savoir plus.
On doit d'abord connaître l'utilisation des GList et des
fonctions g_list_*() qui leur sont liées pour pouvoir utiliser
pleinement le widget GtkList.
Un champ de la structure d'un widget GtkList nous intéresse particulièrement :
Le champ selection d'un GtkList pointe sur une liste chaînée
de tous les items qui sont sélectionnés, ou vaut NULL si aucune
sélection n'est faite. Ainsi, pour connaître la sélection courante, on
consulte le champ GTK_LIST()->selection mais on ne doit pas le
modifier car ses champs internes sont gérés par les fonctions
gtk_list_*().
Le champ selection_mode détermine les options de sélection d'un
GtkList et donc le contenu du champ du
GTK_LIST()->selection :
selection_mode peut avoir l'une des valeurs suivantes :
GTK_SELECTION_SINGLE - selection vaut NULL ou contient un
pointeur vers un seul item sélectionné.
GTK_SELECTION_BROWSE - selection vaut NULL si la liste ne
contient aucun widget ou seulement des widgets non sensitifs. Sinon, ce
champ contient un pointeur vers une seule structure Glist, et donc
vers exactement un item.
GTK_SELECTION_MULTIPLE - selection vaut NULL si aucun item
n'est sélectionné ou pointe vers le premier item sélectionné. Ce
dernier point à son tour vers le second item, etc.
GTK_SELECTION_EXTENDED - selection vaut toujours NULL.
Ce signal sera invoqué à chaque fois que le champ sélection d'un
GtkList a changé. Cela arrive lorsqu'un fils d'un GtkList a été
sélectionné ou désélectionné.
Ce signal est invoqué lorsqu'un fils du GtkList va être
sélectionné. Ceci arrive principalement lors d'appels à
gtk_list_select_item(), gtk_list_select_child() et lors d'appuis
de boutons. Quelques fois, il est indirectement déclenché lorsque des
fils sont ajoutés ou supprimés du GtkList.
Ce signal est invoqué lorsqu'un fils du GtkList va être
désélectionné. Cela arrive principalement lors d'appels à
gtk_list_unselect_item(), gtk_list_unselect_child(), et lors
d'appuis de boutons. Quelques fois, il est indirectement déclenché
lorsque des fils sont ajoutés ou supprimés du GtkList.
Crée un nouvel objet « GtkList ». Le nouveau widget est retourné sous
la forme d'un pointeur vers un objet « GtkWidget ». NULL est retourné
en cas d'erreur.
Insère des items dans LIST, à partir de POSITION.
ITEMS est une liste doublement chaînée où chaque noeud doit
pointer vers un nouveau GtkListItem. Les noeuds GList de
ITEMS sont pris en charge par LIST.
Ôte des items de LIST. ITEMS est une liste doublement
chaînée dont chaque noeud pointe vers un fils direct de LIST. Il
est de la responsabilité de l'appelant de faire un appel à
g_list_free(ITEMS) après cela. L'appelant doit aussi détruire
lui-même les items.
Configure LIST dans le mode de sélection MODE qui peut être
GTK_SELECTION_SINGLE, GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE ou
GTK_SELECTION_EXTENDED.
GtkList* GTK_LIST (gpointer OBJ)
Convertit un pointeur générique en « <\em GtkList*\ ». Voir
Standard Macros::, pour plus d'informations.
GtkListClass* GTK_LIST_CLASS (gpointer CLASS)
Convertit un pointeur générique en « GtkListClass* ». Voir
Standard Macros::, pour plus d'informations.
gint GTK_IS_LIST (gpointer OBJ)
Détermine si un pointeur générique référence un objet « GtkList ». Voir
Standard Macros::, pour plus d'informations.
Voici un programme affichant les changements de sélection dans une
GtkList et permettant d'« emprisonner » des items en les
sélectionnant avec le bouton droit de la souris.
/* Compilez ce programme avec :
* $ gcc -L/usr/X11R6/lib/ -I/usr/local/include/ -lgtk -lgdk -lglib -lX11 -lm -Wall main.c
*/
#include <gtk/gtk.h>
#include <stdio.h>
/* Chaîne pour stocker les données dans les items de la liste. */
const gchar *list_item_data_key="list_item_data";
/* prototypes des gestionnaires de signaux que l'on connectera au widget GtkList. */
static void sigh_print_selection (GtkWidget *gtklist,
gpointer func_data);
static void sigh_button_event (GtkWidget *gtklist,
GdkEventButton *event,
GtkWidget *frame);
/* fonction principale pour configurer l'interface utilisateur */
gint main (int argc, gchar *argv[])
{
GtkWidget *separator;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *scrolled_window;
GtkWidget *frame;
GtkWidget *gtklist;
GtkWidget *button;
GtkWidget *list_item;
GList *dlist;
guint i;
gchar buffer[64];
/* initialise gtk (et donc gdk) */
gtk_init(&argc, &argv);
/* Création d'une fenêtre pour placer tous les widgets.
* Connexion de gtk_main_quit() à l'événement "destroy" de
* la fenêtre afin de prendre en charge les événements « fermeture d'une
* fenêtre » du gestionnaire de fenêtre. */
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Exemple de widget GtkList");
gtk_signal_connect(GTK_OBJECT(window),
"destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
/* À l'intérieur de la fenêtre, on a besoin d'une boîte pour placer
* verticalement les widgets. */
vbox=gtk_vbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(vbox), 5);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
/* Fenêtre à défilement pour placer le widget GtkList à l'intérieur. */
scrolled_window=gtk_scrolled_window_new(NULL, NULL);
gtk_widget_set_usize(scrolled_window, 250, 150);
gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
gtk_widget_show(scrolled_window);
/* Création du widget GtkList
* Connexion du gestionnaire de signal sigh_print_selection() au signal
* "selection_changed" du GtkList pour afficher les items sélectionnés
* à chaque fois que la sélection change. */
gtklist=gtk_list_new();
gtk_container_add(GTK_CONTAINER(scrolled_window), gtklist);
gtk_widget_show(gtklist);
gtk_signal_connect(GTK_OBJECT(gtklist),
"selection_changed",
GTK_SIGNAL_FUNC(sigh_print_selection),
NULL);
/* Création d'une « Prison » pour y mettre un item. */
frame=gtk_frame_new("Prison");
gtk_widget_set_usize(frame, 200, 50);
gtk_container_border_width(GTK_CONTAINER(frame), 5);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
gtk_container_add(GTK_CONTAINER(vbox), frame);
gtk_widget_show(frame);
/* Connexion du gestionnaire de signal sigh_button_event() au signal
* « mise au arrêts » des items du GtkList. */
gtk_signal_connect(GTK_OBJECT(gtklist),
"button_release_event",
GTK_SIGNAL_FUNC(sigh_button_event),
frame);
/* Création d'un séparateur. */
separator=gtk_hseparator_new();
gtk_container_add(GTK_CONTAINER(vbox), separator);
gtk_widget_show(separator);
/* Création d'un bouton et connexion de son signal "clicked" à la
* destruction de la fenêtre. */
button=gtk_button_new_with_label("Fermeture");
gtk_container_add(GTK_CONTAINER(vbox), button);
gtk_widget_show(button);
gtk_signal_connect_object(GTK_OBJECT(button),
"clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTK_OBJECT(window));
/* Création de 5 items, chacun ayant son propre label.
* Ajout de ceux-ci au GtkList en utilisant gtk_container_add().
* On interroge le texte du label et on l'associe avec
* list_item_data_key à chaque item. */
for (i=0; i<5; i++) {
GtkWidget *label;
gchar *string;
sprintf(buffer, "ListItemContainer avec Label #%d", i);
label=gtk_label_new(buffer);
list_item=gtk_list_item_new();
gtk_container_add(GTK_CONTAINER(list_item), label);
gtk_widget_show(label);
gtk_container_add(GTK_CONTAINER(gtklist), list_item);
gtk_widget_show(list_item);
gtk_label_get(GTK_LABEL(label), &string);
gtk_object_set_data(GTK_OBJECT(list_item),
list_item_data_key,
string);
}
/* Création de 5 autres labels. Cette fois-ci, on utilise
* gtk_list_item_new_with_label(). On ne peut interroger la chaîne
* des labels car on n'a pas les pointeurs de labels et on associe
* donc simplement le list_item_data_key de chaque item ayant la même
* chaîne de texte pour l'ajouter au items que l'on place dans une liste
* doublement chaînée (GList). On les ajoute alors par un simple appel à
* gtk_list_append_items().
* Comme on utilise g_list_prepend() pour mettre les items dans la liste
* doublement chaînée, leur ordre sera décroissant (au lieu d'être croissant si
* on utilisait g_list_append()). */
dlist=NULL;
for (; i<10; i++) {
sprintf(buffer, "Item avec le label %d", i);
list_item=gtk_list_item_new_with_label(buffer);
dlist=g_list_prepend(dlist, list_item);
gtk_widget_show(list_item);
gtk_object_set_data(GTK_OBJECT(list_item),
list_item_data_key,
"Item avec label intégré");
}
gtk_list_append_items(GTK_LIST(gtklist), dlist);
/* Enfin, on veut voir la fenêtre... */
gtk_widget_show(window);
/* Lancement de la boucle principale de gtk */
gtk_main();
/* On arrive ici après que gtk_main_quit() ait été appelée lorsque
* la fenêtre principale a été détruite. */
}
/* Gestionnaire de signal connecté aux événements boutons presser/relâcher
* du GtkList. */
void
sigh_button_event (GtkWidget *gtklist,
GdkEventButton *event,
GtkWidget *frame)
{
/* On ne fait quelque chose que si le troisième bouton (celui de droite) a été
* relâché. */
if (event->type==GDK_BUTTON_RELEASE &&
event->button==3) {
GList *dlist, *free_list;
GtkWidget *new_prisoner;
/* On recherche l'item sélectionné à ce moment précis.
* Ce sera notre prisonnier ! */
dlist=GTK_LIST(gtklist)->selection;
if (dlist)
new_prisoner=GTK_WIDGET(dlist->data);
else
new_prisoner=NULL;
/* On recherche les items déjà prisonniers et on les
* remet dans la liste.
* Il ne faut pas oublier de libérer la liste doublement
* chaînée que gtk_container_children() retourne. */
dlist=gtk_container_children(GTK_CONTAINER(frame));
free_list=dlist;
while (dlist) {
GtkWidget *list_item;
list_item=dlist->data;
gtk_widget_reparent(list_item, gtklist);
dlist=dlist->next;
}
g_list_free(free_list);
/* Si l'on a un nouveau prisonnier, on l'ôte du GtkList et on le place
* dans le cadre « Prison ». On doit désélectionner l'item avant.
if (new_prisoner) {
GList static_dlist;
static_dlist.data=new_prisoner;
static_dlist.next=NULL;
static_dlist.prev=NULL;
gtk_list_unselect_child(GTK_LIST(gtklist),
new_prisoner);
gtk_widget_reparent(new_prisoner, frame);
}
}
}
/* Gestionnaire de signal appelé lorsque le GtkList
* émet le signal "selection_changed". */
void
sigh_print_selection (GtkWidget *gtklist,
gpointer func_data)
{
GList *dlist;
/* Recherche dans la liste doublement chaînée des items sélectionnés
* du GtkList, à faire en lecture seulement ! */
dlist=GTK_LIST(gtklist)->selection;
/* S'il n'y a pas d'items sélectionné, il n'y a rien d'autre à faire que
* de le dire à l'utilisateur. */
if (!dlist) {
g_print("Sélection nettoyée\n");
return;
}
/* Ok, on a une sélection et on l'affiche. */
g_print("La sélection est ");
/* On récupère l'item dans la liste doublement chaînée
* puis on interroge la donnée associée par list_item_data_key
* et on l'affiche. */
while (dlist) {
GtkObject *list_item;
gchar *item_data_string;
list_item=GTK_OBJECT(dlist->data);
item_data_string=gtk_object_get_data(list_item,
list_item_data_key);
g_print("%s ", item_data_string);
dlist=dlist->next;
}
g_print("\n");
}
Le widget GtkListItem sert de container pour contenir un fils,
lui fournissant des fonctions de sélection/déséselection exactement
comme le widget GtkList les demande pour ses fils.
Un GtkListItem a sa propre fenêtre pour recevoir les événements et a
sa propre couleur de fond, habituellement blanche.
Comme il est directement dérivé d'un GtkItem, il peut être traité
comme tel en utilisant la macro GTK_ITEM(ListItem), reportez-vous à la
section sur le widget GtkItem pour plus de détail sur celui-ci.
Habituellement, un GtkListItem contient juste un label pour
identifier, par exemple, un nom de fichier dans un GtkList -- la
fonction appropriée gtk_list_item_new_with_label() est donc
fournie. Le même effet peut être obtenu en créant un GtkLabel à
part, en configurant son alignement avec xalign=0 et
yalign=0.5 suivi d'un ajout ultérieur au GtkListItem.
Tout comme on n'est pas forcé d'ajouter un GtkLabel à un
GtkListItem, on peut aussi ajouter un GtkVBox ou un
GtkArrow etc. à un GtkListItem.
Retourne l'identificateur du type « GtkListItem ».
GtkWidget* gtk_list_item_new (void)
Création d'un objet GtkListItem. Le nouveau widget est retourné
sous la forme d'un pointeur vers un objet GtkWidget. NULL est
retourné en cas d'erreur.
Création d'un objet GtkListItem ayant un simple GtkLabel
comme seul fils. Le nouveau widget est retourné sous la forme d'un
pointeur vers un objet GtkWidget. NULL est retourné en cas
d'erreur.
Cette fonction est surtout un emballage de gtk_item_select
(GTK_ITEM (list_item)) qui émettra le signal GtkItem::select.
Voir GtkItem::, pour plus d'informations.
Cette fonction est surtout un emballage de gtk_item_deselect
(GTK_ITEM (list_item)) qui émettra le signal
GtkItem::deselect. Voir GtkItem::, pour plus d'informations.
GtkListItem* GTK_LIST_ITEM (gpointer OBJ)
Convertit un pointeur générique en GtkListItem*. Voir
Standard Macros:: pour plus d'informations.