Programmation GTK2 en Pascal/GtkRadioToolButton

Programmation GTK2 en Pascal

Présentation

modifier

Le contrôle GtkRadioToolButton permet de gérer un élément de barre d'outils de type bouton radio, un bouton poussoir particulier appartenant à un groupe et où un seul bouton peut être dans l'état enfoncé. Il fonctionne en fait comme un bouton radio normal géré par le contrôle GtkRadioButton.

C'est une nouveauté de la version 2.6 de Gtk+.

Hiérarchie

modifier
Hiérarchie
GObject
  └─GtkObject
      └─GtkWidget
          └─GtkContainer
              └─GtkBin
                  └─GtkToolItem
                      └─GtkToolButton
                          ├─GtkMenuToolButton
                          └─GtkToggleToolButton
                              └─GtkRadioToolButton

Utilisation de base

modifier

Création

modifier

Afin de grouper les boutons radio dans une barre d'outils, Gtk+ utilise les listes simplement chaînées de GLib. Les fonctions sont équivalentes à celle du contrôle GtkRadioButton. Pour créer le premier bouton radio du groupe, il faut obligatoirement passer par une de ces fonctions :

function gtk_radio_tool_button_new(group : PGSList) : PGtkToolItem;
function gtk_radio_tool_button_new_from_stock(group : PGSList; stock_id : Pgchar) : PGtkToolItem;

Au moment de la création, le bouton radio est automatiquement ajouté à la liste group. Cependant, ce paramètre n'est pas obligatoire. Nous pouvons très bien mettre NULL comme valeur et cela marchera de la même manière, sauf que nous n'aurons pas de pointeur sur la liste. La valeur de retour de cette fonction sera aussi copiée dans la variable data de la liste chaînée.

La deuxième fonction de création permet de créer un bouton radio en utilisant les GtkStockItem qui est une structure contenant les informations sur le label et l'image à afficher. Gtk+ comporte déjà beaucoup de GtkStockItem prédéfinis (en tout cas les plus courant). Le paramètre stock_id est donc l'identifiant du GtkStockItem à utiliser.

Ensuite pour rajouter les autres boutons au groupe, il y a plusieurs possibilités. La première est d'utiliser une des trois fonctions précédentes mais ce n'est pas tout, car autant pour le premier bouton du groupe, il n'est pas nécessaire d'avoir une liste, autant pour les autres boutons cela devient obligatoire. Pour cela, Gtk+ nous fournit une fonction qui permet d'obtenir la liste dans laquelle les boutons du groupe sont ajoutés :

function gtk_radio_tool_button_get_group(button : PGtkRadioToolButton) : PGSList;

Avec cette fonction, nous pouvons donc connaître la liste à laquelle appartient le bouton button, ce qui va nous permettre d'ajouter de nouveau bouton au groupe. Mais là où cela se complique, c'est qu'il faut récupérer la liste avant chaque ajout de bouton avec le dernier bouton ajouté comme paramètre. Voici ce que cela donnerai pour un groupe de trois boutons :

pRadio1 := gtk_radio_tool_button_new(NULL);
pGroup := gtk_radio_tool_button_get_group(GTK_RADIO_TOOL_BUTTON(pRadio1));
pRadio2 := gtk_radio_tool_button_new(pGroup);
pGroup := gtk_radio_tool_button_get_group(GTK_RADIO_TOOL_BUTTON(pRadio2));
pRadio3 := gtk_radio_tool_button_new(pGroup);

Ce système peut donc s'avérer lourd lors de la création du groupe, surtout s'il contient un grand nombre de boutons. Heureusement, les concepteurs de Gtk+ ont pensé à nous simplifier la vie en ajoutant ces deux fonctions :

function gtk_radio_tool_button_new_from_widget(group : PGtkRadioToolButton) : PGtkToolItem;
function gtk_radio_tool_button_new_with_stock_from_widget(group : PGtkRadioToolButton; 
  stock_id : Pgchar) : PGtkToolItem;

Cette fois group ne correspond pas à la liste mais à un des boutons du groupe. À chaque appel d'une de ces fonctions Gtk+ va s'occuper de récupérer correctement la liste à laquelle appartient le bouton group et ajouter le nouveau bouton. Le code va être réduit et plus lisible.

Nous savons maintenant tout ce qu'il faut pour créer un groupe de GtkRadioToolButton.

NB : Contrairement aux fonctions usuelles de Gtk+ de création de contrôles, ces fonctions ne renvoient pas un PGtkWidget mais un PGtkToolItem.

Programme exemple

modifier

Nous allons créer dans une fenêtre une barre d'outils avec deux boutons radio. Le clic sur un bouton affiche son label dans la fenêtre.

Voilà le fichier gtk046.pas :

 program gtk046;
 
 uses glib2, gtk2;
 
 procedure gtk_toolbar_insert(toolbar : PGtkToolbar; item : PGtkToolItem; pos : gint); cdecl;
   external gtklib name 'gtk_toolbar_insert';
 
 procedure OnToggleBtn(APWidget : PGtkwidget; AData : pgpointer); cdecl;
 var
   LabelBtnRad : PGChar;
 begin
   LabelBtnRad := gtk_tool_button_get_label(GTK_TOOL_BUTTON(APWidget));
   gtk_label_set_label(GTK_LABEL(AData), LabelBtnRad);
 end;
 
 var
   pFenetre     : PGtkWidget;
   pVBox        : PGtkWidget;
   pBarreOutils : PGtkWidget;
   pBoutonRadio1 : PGtkToolItem;
   pBoutonRadio2 : PGtkToolItem;
   pLabel       : PGtkWidget;
   pGroupe      : PGSList;
 
 begin
   gtk_init(@argc, @argv);
   pFenetre := gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_position(GTK_WINDOW(pFenetre), GTK_WIN_POS_CENTER);
   gtk_window_set_default_size(GTK_WINDOW(pFenetre), 320, 200);
   gtk_window_set_title(GTK_WINDOW(pFenetre), 'Gtk046 : Barre d''outils');
   gtk_signal_connect(pGTKOBJECT(pFenetre), 'destroy', G_CALLBACK(@gtk_main_quit), NULL);
 
   // Création de la GtkVBox
   pVBox := gtk_vbox_new(FALSE, 5);
   gtk_container_add(GTK_CONTAINER(pFenetre), pVBox);
 
   // Création de la barre d'outils
   pBarreOutils := gtk_toolbar_new;
   gtk_box_pack_start(GTK_BOX(pVBox), pBarreOutils, FALSE, FALSE, 0);
 
   // Création des boutons radio
 //  pBoutonRadio1 := gtk_radio_tool_button_new_with_stock_from_widget(NULL, GTK_STOCK_OPEN);
 //  pBoutonRadio1 := gtk_radio_tool_button_new_from_widget(NULL);
   pBoutonRadio1 := gtk_radio_tool_button_new(NULL);
   pGroupe := gtk_radio_tool_button_get_group(GTK_RADIO_TOOL_BUTTON(pBoutonRadio1));
   gtk_toolbar_insert(GTK_TOOLBAR(pBarreOutils), pBoutonRadio1, -1);
   gtk_tool_button_set_label(GTK_TOOL_BUTTON(pBoutonRadio1), 'Btn 1');
 
 //  pBoutonRadio2 := gtk_radio_tool_button_new_from_widget(GTK_RADIO_TOOL_BUTTON(pBoutonRadio1));
   pBoutonRadio2 := gtk_radio_tool_button_new(pGroupe);
   gtk_toolbar_insert(GTK_TOOLBAR(pBarreOutils), pBoutonRadio2, -1);
   gtk_tool_button_set_label(GTK_TOOL_BUTTON(pBoutonRadio2), 'Btn 2');
 
   // Création du label
   pLabel := gtk_label_new('Label');
   gtk_box_pack_start(GTK_BOX(pVBox), pLabel, FALSE, FALSE, 0);
 
   // Signaux des boutons
   gtk_signal_connect(pGTKOBJECT(pBoutonRadio1), 'toggled', G_CALLBACK(@OnToggleBtn), pLabel);
   gtk_signal_connect(pGTKOBJECT(pBoutonRadio2), 'toggled', G_CALLBACK(@OnToggleBtn), pLabel);
 
   gtk_widget_show_all(pFenetre);
   gtk_main;
 end.

NB : Je n'ai pas réussi à faire fonctionner les lignes en commentaires. La barre d'outils demeure vide.

Voilà ce que donne l'exécution du programme gtk046 :

 

Et après avoir cliqué sur le deuxième bouton :

 


Barre d'outils : GtkToolbar ~ GtkToolItem ~ GtkToolButton ~ GtkMenuToolButton ~ GtkToggleToolButton ~ GtkRadioToolButton ~ GtkSeparatorToolItem