Il widget GtkList serve come contenitore verticale per altri widget che devono essere di tipo GtkListItem.
Un widget GtkList possiede una sua propria finestra per ricevere eventi e un suo proprio colore di sfondo che di solito è bianco. Dal momento che è direttamente derivato dal widget GtkContainer, può essere trattato come tale usando la macro GTK_CONTAINER(List); si veda il widget GtkContainer per ulteriori dettagli. Per usare il widget GtkList in tutte le sue potenzialità, si dovrebbe essere già familiari con l'uso della GList e delle relative funzioni g_list_*().
All'interno della definizione della struttura del widget GtkList c'è un campo che sarà per noi di grande interesse, cioè:
struct _GtkList
{
...
GList *selection;
guint selection_mode;
...
};
Il campo ``selection'' in un GtkList punta a una lista collegata di tutti gli elementi che sono selezionati correntemente, oppure a NULL se la selezione è vuota. Quindi, per avere informazioni sulla selezione corrente, leggiamo il campo GTK_LIST()->selection, senza però modificarlo dal momento che i campi interni debbono essere gestiti dalle funzioni gtk_list_*().
Le modalità di selezione in una GtkList, e quindi il contenuto di GTK_LIST()->selection, sono determinate dal campo selection_mode:
selection_mode può assumere uno dei seguenti valori:
Il valore per difetto è GTK_SELECTION_MULTIPLE.
void selection_changed (GtkList *LIST)
Questo segnale verrà invocato ogni volta che il campo di selezione di una GtkList è cambiato. Questo accade quando un figlio della GtkList viene selezionato o deselezionato.
void select_child (GtkList *LIST, GtkWidget *CHILD)
Questo segnale viene invocato quando un fuglio di una GtkList sta per essere selezionato. Questo accade principalmente in occasione di chiamate a gtk_list_select_item() e gtk_list_select_child(), di pressioni di bottoni e a volte può venir fatto scattare indirettamente in altre occasioni, in cui vengono aggiunti o rimossi dei figli dalla GtkList.
void unselect_child (GtkList *LIST, GtkWidget *CHILD)
Questo segnale viene invocato quando un figlio della GtkList sta per essere deselezionato. Ciò accade principalmente in occasione di chiamate a gtk_list_unselect_item() e gtk_list_unselect_child(), di pressioni di bottoni, e a volte può venir fatto scattare indirettamente in altre occasioni, in cui vengono aggiunti o rimossi dei figli dalla GtkList.
guint gtk_list_get_type (void)
Restituisce l'identificatore di tipo `GtkList'.
GtkWidget* gtk_list_new (void)
Crea un nuovo oggetto `GtkList'. Il nuovo widget viene restituito sotto forma di un puntoatore ad un oggetto `GtkWidgetì'. In caso di fallimento, viene ritornato NULL.
void gtk_list_insert_items (GtkList *LIST, GList *ITEMS, gint POSITION)
Inserisce degli elementi di lista nella LIST, a partire da POSITION. ITEMS ITEMS è una lista doppiamente collegata, in cui ci si aspetta che i puntatori di ogni nodo puntino a un GtkListItem appena creato. I nodi GList di ITEMS vengono assunti dalla LIST.
void gtk_list_append_items (GtkList *LIST, GList *ITEMS)
Inserisce elementi di lista proprio come gtk_list_insert_items(), ma alla fine della LIST. I nodi GList di ITEMS vengono assunti dalla LIST.
void gtk_list_prepend_items (GtkList *LIST, GList *ITEMS)
Inserisce elementi di lista proprio come gtk_list_insert_items(), ma al principio della LIST. I nodi GList di ITEMS vengono assunti dalla LIST.
void gtk_list_remove_items (GtkList *LIST, GList *ITEMS)
Rimuove degli elementi di lista dalla LIST. ITEMS è una lista doppiamente collegata in cui ci si aspetta che i puntatori di ogni nodo puntino a un figlio diretto di LIST. E' poi responsabilità del chiamante di fare una chiamata a g_list_free(ITEMS). E' anche necessario che il chiamante distrugga lui stesso gli elementi della lista.
void gtk_list_clear_items (GtkList *LIST, gint START, gint END)
Rimuove e distrugge elementi di lista da LIST. Un widget ne è interessato se la sua posizione corrente all'interno di LIST è compreso fra START ed END.
void gtk_list_select_item (GtkList *LIST, gint ITEM)
Invoca il segnale select_child per un elemento di lista specificato dalla sua posizione corrente all'interno di LIST.
void gtk_list_unselect_item (GtkList *LIST, gint ITEM)
Invoca il segnale unselect_child per un elemento di lista specificato dalla sua posizione corrente all'interno di LIST.
void gtk_list_select_child (GtkList *LIST, GtkWidget *CHILD)
Invoca il segnale select_child per uno specifico CHILD.
void gtk_list_unselect_child (GtkList *LIST, GtkWidget *CHILD)
Invoca il segnale unselect_child per uno specifico CHILD.
gint gtk_list_child_position (GtkList *LIST, GtkWidget *CHILD)
Restituisce la posizione di CHILD all'interno di LIST. In caso di fallimento, viene restituito `-1'.
void gtk_list_set_selection_mode (GtkList *LIST, GtkSelectionMode MODE)
Assegna a LIST il modo di selezione MODE, che può essere uno fra GTK_SELECTION_SINGLE, GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE o GTK_SELECTION_EXTENDED.
GtkList* GTK_LIST (gpointer OBJ)
Fa il cast di un generico puntatore a `GtkList*'. Per maggiori informazioni vedere Standard Macros::.
GtkListClass* GTK_LIST_CLASS (gpointer CLASS)
Fa il cast di un generico puntatore a `GtkListClass*'. Per maggiori informazioni vedere Standard Macros::.
gint GTK_IS_LIST (gpointer OBJ)
Determina se un generico puntatore si riferisce ad un oggetto `GtkList'. Per maggiori informazioni vedere Standard Macros::.
Diamo di seguito un programma di esempio che stamperà i campbiamenti della selezione di una GtkList, e vi lascia ``imprigionare'' gli elementi di una lista selezionandoli con il pulsante destro del mouse:
/* list.c */
/* includiamo i file header di gtk+
* includiamo stdio.h, ne abbiamo bisogno per printf()
*/
#include <gtk/gtk.h>
#include <stdio.h>
/* Questa e' la nostra stringa di identificazione dei dati per assegnarli
* ad elementi di lista
*/
const gchar *list_item_data_key="list_item_data";
/* prototipi per i gestori di segnale che connetteremo
* al widget GtkList
*/
static void sigh_print_selection (GtkWidget *gtklist,
gpointer func_data);
static void sigh_button_event (GtkWidget *gtklist,
GdkEventButton *event,
GtkWidget *frame);
/* funzione main per predisporre l'interfaccia utente */
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];
/* inizializza gtk+ (e di conseguenza gdk) */
gtk_init(&argc, &argv);
/* crea una finestra in cui mettere tutti i widget
* connette gtk_main_quit() al segnale "destroy" della finestra
* per gestire le richieste di chiusura finestra del window manager
*/
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
gtk_signal_connect(GTK_OBJECT(window),
"destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
/* all'interno della finestra abbiamo bisogno di una scatola
* in cui mettere i widget verticalmente */
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);
/* questa è la finestra scorribile in cui mettere il widget GtkList */
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);
/* crea il widget GtkList
* connette il gestore di segnale sigh_print_selection()
* al segnale "selection_changed" della GtkList, per stampare
* gli elementi selezionati ogni volta che la selezione cambia
*/
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);
/* creiamo una "Prigione" (Prison) in cui mettere gli elementi di lista ;)
*/
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);
/* connette il gestore di segnale sigh_button_event() alla GtkList
* il quale gestira' l'"imprigionamento" degli elementi di lista
*/
gtk_signal_connect(GTK_OBJECT(gtklist),
"button_release_event",
GTK_SIGNAL_FUNC(sigh_button_event),
frame);
/* crea un separatore
*/
separator=gtk_hseparator_new();
gtk_container_add(GTK_CONTAINER(vbox), separator);
gtk_widget_show(separator);
/* infine creiamo un bottone e connettiamone il segnale "clicked"
* alla distruzione della finestra
*/
button=gtk_button_new_with_label("Close");
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));
/* a questo punto creiamo 5 elementi di lista, ognuno con la
* propria etichetta, e li aggiungiamo alla GtkList usando
* gtk_container_add(). Inoltre, recuperiamo la stringa di testo
* dall'etichetta e la associamo, per ogni elemento, a
* list_item_data_key
*/
for (i=0; i<5; i++) {
GtkWidget *label;
gchar *string;
sprintf(buffer, "ListItemContainer with 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);
}
/* qui creiamo altre 5 etichette, questa volta usando
* per la creazione gtk_list_item_new_with_label().
* Non possiamo recuperare la stringa di testo dall'etichetta
* dal momento che non disponiamo di puntatori alle etichette,
* quindi associamo semplicemente il list_item_data_key di ogni
* elemento di lista con la medesima stringa di testo.
* Per aggiungere elementi di lista, li mettiamo tutti in una lista
* doppiamente collegata (GList), e quindi li aggiungiamo con una
* unica chiamata a gtk_list_append_items().
* Dal momento che usiamo g_list_prepend() per mettere gli elementi
* nella lista doppiamente collegata, il loro ordine sara' discendente
* (invece che ascendente come sarebbe se usassimo g_list_append())
*/
dlist=NULL;
for (; i<10; i++) {
sprintf(buffer, "List Item with 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,
"ListItem with integrated Label");
}
gtk_list_append_items(GTK_LIST(gtklist), dlist);
/* e finalmente vogliamo vedere la finestra, non e' vero? ;)
*/
gtk_widget_show(window);
/* lancia il ciclo principale di gtk
*/
gtk_main();
/* si arriva a questo punto dopo la chiamata di gtk_main_quit(),
* il che accade quando viene distrutta la finestra principale
*/
return 0;
}
/* questo e' il gestore di segnale che e' stato connesso all'evento di
* pressione/rilascio del bottone della GtkList
*/
void
sigh_button_event (GtkWidget *gtklist,
GdkEventButton *event,
GtkWidget *frame)
{
/* facciamo qualcosa solo nel caso di rilascio del terzo bottone
* (quello piu' a destra)
*/
if (event->type==GDK_BUTTON_RELEASE &&
event->button==3) {
GList *dlist, *free_list;
GtkWidget *new_prisoner;
/* recuperiamo l'elemento di lista selezionato correntemente,
* che sara' il nostro prossimo prigioniero ;)
*/
dlist=GTK_LIST(gtklist)->selection;
if (dlist)
new_prisoner=GTK_WIDGET(dlist->data);
else
new_prisoner=NULL;
/* cerchiamo elementi di lista gia' imprigionati,
* li rimetteremo nella lista.
* Ricordare di liberare la lista doppiamente collegata
* che viene restituita da gtk_container_children()
*/
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);
/* se abbiamo un nuovo prigioniero, lo rimuoviamo
* dalla GtkList e lo mettiamo nella cornice della
* "Prigione". Dobbiamo prima deselezionare l'elemento
*/
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);
}
}
}
/* questo e' il gestore di segnaleche viene chiamato de la
* GtkList emette il segnale "selection_changed"
*/
void
sigh_print_selection (GtkWidget *gtklist,
gpointer func_data)
{
GList *dlist;
/* recuperiamo la lista doppiamente collegata degli
* elementi selezionati della GtkList, ricordate di
* trattarla come sola lettura
*/
dlist=GTK_LIST(gtklist)->selection;
/* se non ci sono elementi selezionati non c'e' altro da
* fare che dirlo all'utente
*/
if (!dlist) {
g_print("Selection cleared\n");
return;
}
/* ok, abbiamo una selezione e quindi lo scriviamo
*/
g_print("The selection is a ");
/* ottieniamo l'elemento di lista dalla lista doppiamente
* collegata e poi richiediamo i dati associati con
* list_item_data_key. Poi semplicemente li stampiamo
*/
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");
}
Il widget GtkListItem è progettato allo scopo di essere un contenitore collegato ad un figlio, per fornire le funzioni per la selezione e deselezione allo stesso modo in cui il widget GtkList ne ha bisogno per i propri figli.
Un GtkListItem ha la sua propria finestra per ricevere eventi, e ha il suo proprio colore di sfondo, che di solito è bianco.
Dal momento che questo widget deriva direttamente da GtkItem, può essere trattato come tale usando la macro GTK_ITEM(ListItem), vedere il widget GtkItem per ulteriori informazioni. Di solito un GtkListItem ha solo un'etichetta per identificare per esempio un nome di file all'interno di una GtkList -- per cui viene fornita la funzione appropriata gtk_list_item_new_with_label(). Si può ottenere lo stesso effetto creando una GtkLabel da sola, assegnando al suo allineamento i valori xalign=0 e yalign=0.5, aggiungendo successivamente un contenitore alla GtkListItem.
Dal momento che non si è obbligati a mettere una GtkLabel, si può anche aggiungere una GtkVBox una GtkArrow ecc. alla GtkListItem.
Un GtkListItem non crea alcun nuovo segnale di per se, ma eredita i segnali di GtkItem. Per ulteriori informazioni, vedere GtkItem::.
guint gtk_list_item_get_type (void)
Restituisce l'identificatore di tipo `GtkListItem'.
GtkWidget* gtk_list_item_new (void)
Crea un nuovo oggetto `GtkListItem'. Il nuovo widget viene restituito sottoforma di un puntatore ad un oggetto `GtkWidget'. In caso di fallimento, viene restituito `NULL'.
GtkWidget* gtk_list_item_new_with_label (gchar *LABEL)
Cre un nuovo oggetto `GtkListItem', avente come unico figlio un GtkLabel. Il nuovo widget viene restituito sottoforma di un puntatore ad un oggetto `GtkWidget'. In caso di fallimento, viene restituito `NULL'.
void gtk_list_item_select (GtkListItem *LIST_ITEM)
Questa funzione è essenzialmente un wrapper per una chiamata a gtk_item_select (GTK_ITEM (list_item)) che emetterà il segnale select. Vedere GtkItem:: per maggiori informazioni.
void gtk_list_item_deselect (GtkListItem *LIST_ITEM)
Questa funzione è essenzialmente un wrapper per una chiamata a gtk_item_deselect (GTK_ITEM (list_item)) che emetterà il segnale deselect. Vedere GtkItem:: per maggiori informazioni.
GtkListItem* GTK_LIST_ITEM (gpointer OBJ)
Effettua il cast di un puntatore generico a `GtkListItem*'. Vedere Standard Macros:: per maggiorni informazioni.
GtkListItemClass* GTK_LIST_ITEM_CLASS (gpointer CLASS)
Effettua il cast di un puntatore generico a `GtkListItemClass*'. Vedere Standard Macros:: per maggiorni informazioni.
gint GTK_IS_LIST_ITEM (gpointer OBJ)
Determina se un puntatore generico si riferisce ad un oggetto `GtkListItem'. Vedere Standard Macros:: per maggiorni informazioni.
Come esempio su questo argomento, si veda quello relativo alla GtkList, che riguarda anche l'uso del GtkListItem.