CLIST

 

Clist sta per Columned List
Con questo widget possiamo infatti creare una lista con più colonne.
Prima di creare una clist dobbiamo quindi decidere quante colonne vogliamo.

Ci sono due modi per creare una Clist:

GtkWidget *gtk_clist_new ( gint columns );

GtkWidget *gtk_clist_new_with_titles( gint columns,
gchar *titles[] );

Ogni colonna della lista può avere una label (etichetta) o un bootone che reagisce quando viene clikkato.

Se usiamo la seconda funzione possiamo dunque assegnare direttamente i titoli delle colonne che compariranno nella nostra Clist.
Se invece usiamo la prima funzione possiamo comunque associare i titoli alle colonne in un secondo momento.

Per settare il modo di selezione della Clist useremo:

void gtk_clist_set_selection_mode( GtkCList *clist,
GtkSelectionMode mode );

Dove l'argomento selectionMode può assumere uno dei seguenti valori:
GTK_SELECTION_SINGLE
GTK_SELECTION_BROWSE
GTK_SELECTION_MULTIPLE
GTK_SELECTION_EXTENDED

Possiamo inoltre modificare l'aspetto della clist con il solito shadow_type:

void gtk_clist_set_shadow_type( GtkCList *clist,
GtkShadowType border );

Dove appunto l'attributo puo' assumere uno dei seguenti valori (stabilendo quindi il tipo di ombreggiatura o l'effetto 3d):

GTK_SHADOW_NONE
GTK_SHADOW_IN
GTK_SHADOW_OUT
GTK_SHADOW_ETCHED_IN
GTK_SHADOW_ETCHED_OUT

Come abbiamo già accennato i titoli delle colonne possono essere settati sia come bottoni che come semplici label. A questo fine ci possiamo servire delle funzioni:

void gtk_clist_column_title_active( GtkCList *clist,
gint column );

void gtk_clist_column_title_passive( GtkCList *clist,
gint column );

void gtk_clist_column_titles_active( GtkCList *clist );

void gtk_clist_column_titles_passive( GtkCList *clist );

Per mostrare o nascondere i titoli delle colonne ci potremo avvalere di:

void gtk_clist_column_titles_show( GtkCList *clist );

void gtk_clist_column_titles_hide( GtkCList *clist );

Possiamo naturalmente anche cambiare i titoli. Useremo a tale scopo:

void gtk_clist_set_column_title( GtkCList *clist,
gint column,
gchar *title );

Dato che come abbiamo visto la Clist ci permette di usare dei bottoni per i titoli possiamo incorporare in essi altre widget come ad esempio dell pixmaps. A tal fine useremo la funzione:

void gtk_clist_set_column_widget( GtkCList *clist,
gint column,
GtkWidget *widget );

E' anche possibile cambiare la giustificazione di una colonna:

void gtk_clist_set_column_justification( GtkCList *clist,
gint column,
GtkJustification justification );
L'attributo GtkJustification può assumere uno dei seguenti valori:

GTK_JUSTIFY_LEFT
GTK_JUSTIFY_RIGHT
GTK_JUSTIFY_CENTER
GTK_JUSTIFY_FILL

La prossima funzione è molto importante in quanto permette di settare la larghezza delle colonne:

void gtk_clist_set_column_width( GtkCList *clist,
gint column,
gint width );

Tenete presente che la larghezza è espressa in pixel e non in caratteri.

Cosa che vale anche per la prossima funzione che ci permette di settare l'altezza delle colonne:

void gtk_clist_set_row_height( GtkCList *clist,
gint height );

Possiamo anche far muovere (scrollare) la lista per visualizzare una certa riga o colonna:

void gtk_clist_moveto( GtkCList *clist,
gint row,
gint column,
gfloat row_align,
gfloat col_align );

E con la seguente funzione possiamo accertare se la riga che ci interessa è visibile:

GtkVisibility gtk_clist_row_is_visible( GtkCList *clist,
gint row );

Dove il valore di ritorno può essere uno dei seguenti:

GTK_VISIBILITY_NONE
GTK_VISIBILITY_PARTIAL
GTK_VISIBILITY_FULL

Se ci torna FULL sappiamo inoltre che sono visibili anche tutte le colonne.

Ed ecco un'altra cosa interessante. Possiamo fare in modo di cambiare il colore dello sfondo e del testo di una riga con le funzioni:

void gtk_clist_set_foreground( GtkCList *clist,
gint row,
GdkColor *color );

void gtk_clist_set_background( GtkCList *clist,
gint row,
GdkColor *color );

Attenzione che i colori devono essere comunque stati preventivamente allocati:

Per aggiungere delle righe possiamo usare le solite tre funzioni che ci permettono di inserirle all'inizio alla fine o in una posizione specifica:

gint gtk_clist_prepend( GtkCList *clist,
gchar *text[] );

gint gtk_clist_append( GtkCList *clist,
gchar *text[] );

Il valore di ritorno di queste due ci indicano la posizione in qui sono state inserite.

void gtk_clist_insert( GtkCList *clist,
gint row,
gchar *text[] );

Invece per rimuovere una singola riga possiamo usare:

void gtk_clist_remove( GtkCList *clist,
gint row );

C'e' poi anche una chiamata che rimuove tutte le righe "pulendo" del tutto la Clist:

void gtk_clist_clear( GtkCList *clist );

Ci sono anche due funzioni molto comode che permettono di evitare il flickering della lista quando si inseriscono velocemente un gran numero di righe. Con queste due funzioni "congeliamo" la lista e la riattiviamo dopo che si è concluso l'inserimento dei dati in modo che il redraw sarà operato solo a operazioni completate:

void gtk_clist_freeze( GtkCList * clist );

void gtk_clist_thaw( GtkCList * clist );

Ogni cell della lista può contenere testo pixmaps o entrambi. A seconda di cosa vogliamo possiamo usare le seguenti funzioni:

void gtk_clist_set_text( GtkCList *clist,
gint row,
gint column,
gchar *text );

void gtk_clist_set_pixmap( GtkCList *clist,
gint row,
gint column,
GdkPixmap *pixmap,
GdkBitmap *mask );

void gtk_clist_set_pixtext( GtkCList *clist,
gint row,
gint column,
gchar *text,
guint8 spacing,
GdkPixmap *pixmap,
GdkBitmap *mask );

Le funzioni sono chiare vale solo la pena puntualizzare che l'argomento "spacing" nella chiamata gtk_clist_set_pixtext rappresenta il numero di pixel che vogliamo siano inseriti tra la pixmap e l'inizio del testo.

Per ricavare i dati presenti nella lista useremo:

gint gtk_clist_get_text( GtkCList *clist,
gint row,
gint column,
gchar **text );

gint gtk_clist_get_pixmap( GtkCList *clist,
gint row,
gint column,
GdkPixmap **pixmap,
GdkBitmap **mask );

gint gtk_clist_get_pixtext( GtkCList *clist,
gint row,
gint column,
gchar **text,
guint8 *spacing,
GdkPixmap **pixmap,
GdkBitmap **mask );

Non è necessario richiamare tutti i dati se non servono ed in tal caso si possono usare i NULL come argomento ad esempio:

gchar *mytext;
gtk_clist_get_pixtext(clist, row, column, &mytext, NULL, NULL, NULL);

Per sapere che tipo di dati contiene la cella possiamo usare:

GtkCellType gtk_clist_get_cell_type( GtkCList *clist,
gint row,
gint column );

che restituisce uno dei seguenti valori:

GTK_CELL_EMPTY
GTK_CELL_TEXT
GTK_CELL_PIXMAP
GTK_CELL_PIXTEXT
GTK_CELL_WIDGET

Possiamo anche settare l' indentation sia orizzontale che verticale di una cell con:

void gtk_clist_set_shift( GtkCList *clist,
gint row,
gint column,
gint vertical,
gint horizontal );

E' anche possibile associare dei dati ad una riga che non saranno visibili dall'utente ma che possono essere utili per il programmatore:

void gtk_clist_set_row_data( GtkCList *clist,
gint row,
gpointer data );

void gtk_clist_set_row_data_full( GtkCList *clist,
gint row,
gpointer data,
GtkDestroyNotify destroy );

gpointer gtk_clist_get_row_data( GtkCList *clist,
gint row );

gint gtk_clist_find_row_from_data( GtkCList *clist,
gpointer data );

Venendo alla selezione ecco le due funzioni che ci permettono di selezionare/deselezionare una riga:

void gtk_clist_select_row( GtkCList *clist,
gint row,
gint column );

void gtk_clist_unselect_row( GtkCList *clist,
gint row,
gint column );

Ed una che con le coordinate (ad es. del mouse pointer) ci ritorna la corrispondente riga e colonna:

gint gtk_clist_get_selection_info( GtkCList *clist,
gint x,
gint y,
gint *row,
gint *column );

Segnali:

Oltre ai segnali standard del GtkContainer da cui la Clist discende abbiamo dei segnali specifici:

select_row - che ci ritorna nell'ordine le seguenti informazioni: GtkCList *clist, gint row, gint column, GtkEventButton, *event
unselect_row - che ci ritorna le stesse informazioni di select_row
click_column - che ritorna *clist, gint column

Cos' se vogliamo connettere una callback al segnale select_row la dichiareremo in questo modo:

void select_row_callback(GtkWidget *widget,
gint row,
gint column,
GdkEventButton *event,
gpointer data);

E la connetteremo con:

gtk_signal_connect(GTK_OBJECT( clist),
"select_row"
GTK_SIGNAL_FUNC(select_row_callback),
NULL);

 

 

ESEMPIO

#include <gtk/gtk.h>

/* click sul bottone "Add List" */
void button_add_clicked( gpointer data )
{
int indx;

/* Aggiungiamo alla Clist 4 righe di 2 colonne ciascuna*/
gchar *drink[4][2] = { { "Milk", "3 Oz" },
{ "Water", "6 l" },
{ "Carrots", "2" },
{ "Snakes", "55" } };

/* Aggiungiamo il testo*/

for ( indx=0 ; indx < 4 ; indx++ )
gtk_clist_append( (GtkCList *) data, drink[indx]);

return;
}

/* Quando si clikka il bottone "Clear List" */
void button_clear_clicked( gpointer data )
{

gtk_clist_clear( (GtkCList *) data);

return;
}

/* Quando si clikka il bottone "Hide/Show titles" */
void button_hide_show_clicked( gpointer data )
{
/* Un flag per ricordare lo stato 0 = visibile */
static short int flag = 0;

if (flag == 0)
{
/* Nasconde i titles e setta il flag a 1 */
gtk_clist_column_titles_hide((GtkCList *) data);
flag++;
}
else
{
/* Mostra i titles e resetta il flag a 0 */
gtk_clist_column_titles_show((GtkCList *) data);
flag--;
}

return;
}

/* Se si arriva qui, l'utente ha selezionato una riga nella list. */
void selection_made( GtkWidget *clist,
gint row,
gint column,
GdkEventButton *event,
gpointer data )
{
gchar *text;

/* Ricava il testo presente nella riga e colonna clikkata */
gtk_clist_get_text(GTK_CLIST(clist), row, column, &text);

/* Stampiamo le informazioni sulla riga selezionata */
g_print("You selected row %d. More specifically you clicked in "
"column %d, and the text in this cell is %s\n\n",
row, column, text);

return;
}

int main( int argc,
gchar *argv[] )
{
GtkWidget *window;
GtkWidget *vbox, *hbox;
GtkWidget *clist;
GtkWidget *button_add, *button_clear, *button_hide_show;
gchar *titles[2] = { "Ingredients", "Amount" };

gtk_init(&argc, &argv);

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize(GTK_WIDGET(window), 300, 150);

gtk_window_set_title(GTK_WINDOW(window), "GtkCList Example");
gtk_signal_connect(GTK_OBJECT(window),
"destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);

vbox=gtk_vbox_new(FALSE, 5);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);

/* Crea la GtkCList con due colonne */
clist = gtk_clist_new_with_titles( 2, titles);

/* Connettiamo il segnale select_row */
gtk_signal_connect(GTK_OBJECT(clist), "select_row",
GTK_SIGNAL_FUNC(selection_made),
NULL);

/* Diamo l'ombreggiatura */
gtk_clist_set_shadow_type (GTK_CLIST(clist), GTK_SHADOW_OUT);

/* Settiamo la larghezza delle colonne */
gtk_clist_set_column_width (GTK_CLIST(clist), 0, 150);

gtk_box_pack_start(GTK_BOX(vbox), clist, TRUE, TRUE, 0);
gtk_widget_show(clist);

hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
gtk_widget_show(hbox);

button_add = gtk_button_new_with_label("Add List");
button_clear = gtk_button_new_with_label("Clear List");
button_hide_show = gtk_button_new_with_label("Hide/Show titles");

gtk_box_pack_start(GTK_BOX(hbox), button_add, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), button_clear, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), button_hide_show, TRUE, TRUE, 0);

/* Connttiamo le callbacks ai tre bottoni */
gtk_signal_connect_object(GTK_OBJECT(button_add), "clicked",
GTK_SIGNAL_FUNC(button_add_clicked),
(gpointer) clist);
gtk_signal_connect_object(GTK_OBJECT(button_clear), "clicked",
GTK_SIGNAL_FUNC(button_clear_clicked),
(gpointer) clist);
gtk_signal_connect_object(GTK_OBJECT(button_hide_show), "clicked",
GTK_SIGNAL_FUNC(button_hide_show_clicked),
(gpointer) clist);

gtk_widget_show(button_add);
gtk_widget_show(button_clear);
gtk_widget_show(button_hide_show);

/* Mostriamo la finestra ed entriamo nel ciclo principale */
gtk_widget_show(window);
gtk_main();

return(0);
}

 

Torna all'indice