Guida Gtk+ a puntate ( XX parte )
Bene continuiamo con i menu e le gtk+, come detto l’ultima volta, in questa puntata vediamo un po’ di funzioni che ho creato tempo fa e una tecnica che uso per aggiungere un po’ di elementi ai vari menu in modo semplice.
L’header aggiuntivo probabilmente richiesto sarà:
#include
La prima che andiamo a vedere serve per inserire un menu con l’icona e il testo di una GTK_STOCK:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | GtkWidget * menu_stock_append (GtkMenu * menu, const char *stock_id, GCallback func, GtkAccelGroup * accel_group, unsigned int accel_id, GdkModifierType mod_type, char *tooltip) { GtkWidget *widget; widget = gtk_image_menu_item_new_from_stock (stock_id, accel_group); gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget); gtk_widget_show (widget); if (func) g_signal_connect (G_OBJECT (widget), "activate", func, NULL); if (accel_id && accel_group) gtk_widget_add_accelerator (widget, "activate", accel_group, accel_id, mod_type, GTK_ACCEL_VISIBLE); if (tooltip) gtk_widget_set_tooltip_text (widget, tooltip); return widget; } |
Parametri:
- GtkMenu *menu: il widget riguardante il menu in cui inserire l’elemento convertito in GtkMenu tramite la macro GTK_MENU
- const char *stock_id: la GTK_STOCK scelta da inserire nel menu
- GCallback func: la funzione da collegare al click sull’elemento ( oppure NULL ) convertita tramite la macro G_CALLBACK
- GtkAccelGroup * accel_group: il gruppo di acceleratori ( scorciatoie da tastiere ) in cui varranno inserite le scorciatoie di questo elemento ( ne riparliamo meglio dopo ) o NULL se non si vuole usare nessuna scorciatoia.
- unsigned int accel_id: il tasto da assegnare alla scorciatoia ( tipo la lettera R, anche di questo ne riparliamo meglio dopo )
- GdkModifierType mod_type: il tipo di “maschera” da associare alla lettera per la scorciatoia, ad esempio si può scegliere il CTRL come maschera e per richiamare la scorciatoia da tastiera con i due esempi sopra riportati dobbiamo premere CTRL + R
- char *tooltip: Il suggerimento da visualizzare nel caso il mouse si fermi più di un tot di secondi sull’elemento o NULL se non lo si vuole inserire.
Questa funzione ritorna l’elemento che la funzione ha inserito nel menu può essere usato per disabilitare\abilitare quell’elemento, se non si deve eseguire nessuna operazione la variabile ritornata può anche essere ignorata.
La funzione che segue è anch’essa molto simile a quella appena mostrata, tranne per il fatto che della GTK_STOCK passata usa solo l’immagine mentre il testo può essere deciso e impostato a piacimento.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | GtkWidget * menu_label_with_stock_append (GtkMenu * menu, const char *label, const char *stock_id, GCallback func, GtkAccelGroup * accel_group, unsigned int accel_id, GdkModifierType mod_type, char *tooltip) { GtkWidget *widget, *image; image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU); gtk_widget_show (image); widget = gtk_image_menu_item_new_with_label (label); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), image); gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget); gtk_widget_show (widget); if (func) g_signal_connect (G_OBJECT (widget), "activate", func, NULL); if (accel_id && accel_group) gtk_widget_add_accelerator (widget, "activate", accel_group, accel_id, mod_type, GTK_ACCEL_VISIBLE); if (tooltip) gtk_widget_set_tooltip_text (widget, tooltip); return widget; } |
Come si può notare riceve gli stessi i parametri, ne presenta solo uno in più tra il primo e il secondo parametro della funzione precedente. Il parametro in più richiesto è proprio quello riguardante il testo da usare per l’elemento.
Terza funzione che andiamo a vedere è quella per inserire un separatore di voci ( una semplice linea ) per ad esempio suddividere gruppi di elementi che fanno azioni diverse nello stesso menu.
1 2 3 4 5 6 7 8 9 10 11 | GtkWidget * menu_separator_append (GtkMenu * menu) { GtkWidget *widget; widget = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget); gtk_widget_show (widget); return widget; } |
L’unico parametro che ricevere è come si può intuire il menu in cui inserire il separatore convertito con la macro GTK_MENU.
Ultima funzione è quella per aggiungere un menu alla barra dei menu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | GtkWidget * menu_append (GtkMenuBar * bar, GtkWidget * menu, const char *name, char *tooltip) { GtkWidget *widget; widget = gtk_menu_item_new_with_label (name); gtk_widget_show (widget); gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu); gtk_menu_shell_append (GTK_MENU_SHELL (bar), widget); if (tooltip) gtk_widget_set_tooltip_text (widget, tooltip); return widget; } |
Il primo parametro è la barra dei menu in cui inserirlo, il secondo è il menu, il terzo il nome da dare al menu e come ultimo, opzionale, il suggerimento da dare quando il mouse si ferma sul menu oppure NULL.
Prima di andare a vedere come utilizzare bene queste funzioni, faccio una piccola spiegazione delle scorciatoie da tastiera.
Bene, innanzitutto nel mondo Gtk+ le scorciatoie vengono chiamate acceleratori così da poterle chiamare in modo giusto. Questi acceleratori vengono inseriti in uno o più gruppi chiamati GtkAccelGroup, questi gruppi sono utili ad esempio per abilitare o disabilitare acceleratori in massa, ad esempio si può avere un gruppo di acceleratori riguardanti certe voci che vanno in contrasto con gli acceleratori di un altro gruppo e quindi effettuare le verifichè per far sì che quando uno dei due è abilitato l’altro sia disattivato.
Gli acceleratori son composti principalmente da due parti, il tasto da premere per attivarlo e la maschera da utilizzare per intercettarlo.. esempio pratico come detto più su:
- TASTO: GDK_R
- MASK: GDK_CONTROL_MASK
- COMBINAZIONE PER ATTIVARE LA SCORCIATOIA: Ctrl + R
L’elenco dei nomi per le costanti che definiscono i tasti potete trovarli qui: http://www.koders.com/c/fidD9E5E78FD91FE6ABDD6D3F78DA5E4A0FADE79933.aspx ( comunque alcuni caratteri possono essere inseriti tramite il loro valore ascii, ad esempio GDK_A è uguale ad ‘A’ )
Principali maschere utilizzabili: GDK_SHIFT_MASK ( Shift), GDK_CONTROL_MASK ( Control ), GDK_MOD1_MASK ( Alt ), GDK_SUPER_MASK ( Il tastino su cui purtroppo c’è il simbolo di windows, o di una casetta sugli eeepc ). Per altre vi rimando al link del tipo GtkModifierType: http://library.gnome.org/devel/gdk/unstable/gdk-Windows.html#GdkModifierType
Bene dopo questa premessa sugli acceleratori passiamo alla tecnica per utilizzare queste funzioni in modo semplice.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include "funzioni_sopra_elencate.h" /* window sarà il widget della finestra in cui inserire i menu * mentre container sarà il widget contenitore in cui * andremo ad inserire il menu, dovrà essere passato * usando la macro GTK_CONTAINER */ void menu_new (GtkWindow *window, GtkContainer *container) { GtkAccelGroup *group; GtkWidget *main_menu, *file_list, *edit_list; /* Creo la barra dei menu */ main_menu = gtk_menu_bar_new (); /* Creo il gruppo di acceleratori */ group = gtk_accel_group_new (); gtk_window_add_accel_group (window, group); /* Creo il menu File */ file_list = gtk_menu_new (); /* -- */ menu_stock_append (GTK_MENU (file_list), GTK_STOCK_NEW, NULL, group, GDK_N, GDK_CONTROL_MASK, "Crea un nuovo file"); menu_stock_append (GTK_MENU (file_list), GTK_STOCK_OPEN, NULL, group, GDK_O, GDK_CONTROL_MASK, "Apri un file"); menu_stock_append (GTK_MENU (file_list), GTK_STOCK_SAVE, NULL, group, GDK_S, GDK_CONTROL_MASK, "Salva il file"); menu_separator_append (GTK_MENU (file_list)); menu_label_with_stock_append (GTK_MENU (file_list), "Stampa Documento", GTK_STOCK_PRINT, NULL, group, GDK_P, GDK_CONTROL_MASK, "Stampa il file"); menu_separator_append (GTK_MENU (file_list)); menu_stock_append (GTK_MENU (file_list), GTK_STOCK_QUIT, NULL, group, GDK_Q, GDK_CONTROL_MASK, "Esci dal programma"); /* -- */ menu_append (GTK_MENU_BAR (main_menu), file_list, "File", NULL); /* Creo il menu Modifica */ edit_list = gtk_menu_new (); /* -- */ menu_stock_append (GTK_MENU (edit_list), GTK_STOCK_COPY, NULL, group, GDK_C, GDK_CONTROL_MASK, "Copia testo"); menu_stock_append (GTK_MENU (edit_list), GTK_STOCK_CUT, NULL, group, GDK_X, GDK_CONTROL_MASK, "Taglia testo"); menu_stock_append (GTK_MENU (edit_list), GTK_STOCK_PASTE, NULL, group, GDK_V, GDK_CONTROL_MASK, "Incolla testo"); /* -- */ menu_append (GTK_MENU_BAR (main_menu), edit_list, "Modifica", NULL); /* Inseriamo la barra comprensiva di menu all'interno del contenitore passato */ gtk_container_add (container, main_menu); } /* Così è molto più immediato creare menu di grosse dimensioni anche * se nei casi più specifici si può migliorare ancora il codice e la sua * gestione */ |
Fine Ventesima Puntata
Abbiam quasi finito con i menu, c’è ancora qualche funzione da descrivere ma siamo già a buon punto. Questa puntata è importante in quanto ho finalmente affrontato anche l’argomento degli acceleratori. Alla prossima, spero non tardi.
Ciauz
Ops, scusate wordpress traduce un po’ male i caratteri, all’inizio della guida quando dico l’header richiesto è: #include
volevo dire che l’header richiesto è:
#include <gdk/gdkkeysyms.h>