# MenuBar (Vala)

Tiffany Antopolski
tiffany.antopolski@gmail.com 2012
Un composant graphique qui contient des éléments graphiques GtkMenuItem
Luc Rebert,
traduc@rebert.name 2011
Alain Lojewski,
allomervan@gmail.com 2011-2012
Luc Pionchon
pionchon.luc@gmail.com 2011
Bruno Brouard
annoa.b@gmail.com 2011-12
Luis Menina
liberforce@freeside.fr 2014

# BarreDeMenu

Une BarreDeMenu créée avec XML et GtkBuilder.

# Création d'une BarreDeMenu avec XML

Pour créer une BarreDeMenu avec XML :

créez le fichier barredemenu.ui avec votre éditeur de texte favorit.

Saisissez la ligne suivante en haut du fichier :

<?xml version="1.0"? encoding="UTF-8"?>

We want to create the interface which will contain our menubar and its submenus. Our menubar will contain File, Edit, Choices and Help submenus. We add the following XML code to the file:

<?xml version="1.0" encoding="UTF-8"?> <interface> <menu id="menubar"> <submenu> <attribute name="label">File</attribute> </submenu> <submenu> <attribute name="label">Edit</attribute> </submenu> <submenu> <attribute name="label">Choices</attribute> </submenu> <submenu> <attribute name="label">Help</attribute> </submenu> </menu> </interface>

Créons maintenant le fichier .vala et utilisons GtkBuilder pour importer le fichier barredemenu.ui que nous venons de faire.

# Ajout de la BarreDeMenu à la fenêtre avec GtkBuilder

public class MyWindow : Gtk.ApplicationWindow { internal MyWindow (MyApplication app) { Object (application: app, title: "MenuBar Example"); this.set_default_size (200, 200); } }

class MyApplication: Gtk.Application { protected override void activate () { new MyWindow (this).show (); } protected override void startup () { base.startup ();

/* Setup menubar. */ /* Get the UI file. */ var builder = new Gtk.Builder (); try { builder.add_from_file ("menubar_basis.ui"); /* Handle the exception. */ } catch (Error e) { error ("Unable to load file: %s", e.message); }

/* Get the menubar from the builder. */ this.menubar = builder.get_object ("menubar") as MenuModel; } }

/* main creates and runs the application. */ public int main (string[] args) { return new MyApplication ().run (args); }

Maintenant, compilez le fichier vala et lancez-le. L'application devrait ressembler à l'image en haut de cette page.

# Ajout d'éléments aux menus

Commençons par ajouter 2 éléments au menu Fichier : Nouveau et Quitter. Pour ce faire, ajoutons une `section` contenant ces éléments au SouMenu `Fichier`. Le fichier barredemenu.ui devrait ressembler à ceci (les lignes 6 à 13 comportent la section nouvellement ajoutée) :

<?xml version="1.0" encoding="UTF-8"?> <interface> <menu id="menubar"> <submenu> <attribute name="label">File</attribute> <section> <item> <attribute name="label">New</attribute> </item> <item> <attribute name ="label">Quit</attribute> </item> </section> </submenu> <submenu> <attribute name="label">Edit</attribute> </submenu> <submenu> <attribute name="label">Choices</attribute> </submenu> <submenu> <attribute name="label">Help</attribute> </submenu> </menu> </interface>

En suivant ce modèle, ajoutez les éléments `Copier` et `Coller` au SousMenu `Édition` et un élément `À propos` au SousMenu `Aide`. Nous allons attendre pour ajouter des éléments au SousMenu Choix d'être un peu plus loin dans ce guide.

Il es inutile de recompiler le programme vala si vous n'avez apporté des modifications qu'au fichier barredemenu.ui. Éxecutez seulement votre application compilée précédemment et les modifications dans l'interface utilisateur vont être prises en compte.

# Définition des actions

Ceci est un processus en trois étapes.

Premièrement, créons la matrice ActionEntry dans la classe MyApplication. Une ActionEntry se compose :

du nom « action name » (obligatoire)

de la fonction de rappel pour connecter le signal « activate » à l'action (si applicable)

du type de paramètre qui doit être transmis à la fonction activate pour l'action (si applicable)

de l'état initial de cette action (si applicable)

du rappel à connecter au signal « change-state » (si applicable)

const ActionEntry[] actions = { { "new", new_cb }, // {"action name", callback_function} { "quit", quit_cb } };

Deuxièmement, nous créons les fonctions de rappel qui sont connectées aux actions.

void new_cb (SimpleAction action, Variant? parameter) { print ("You clicked \"New\"\n"); //new MyWindow (this).show (); }

void quit_cb (SimpleAction action, Variant? parameter) { print ("You clicked \"Quit\"\n"); this.quit (); }

Et troisièmement, nous connectons les éléments du menu aux actions dans le fichier XML en y ajoutant l'attribut « action » :

<item> <attribute name="label">New</attribute> <attribute name="action">app.new</attribute> </item> <item> <attribute name="label">Quit</attribute> <attribute name="action">app.quit</attribute> </item>

# Le SousMenu Choix et les éléments avec leur état

Les lignes 30 à 80 inclues de décrivent le code XML utilisé pour créer le menu Choix de l'interface utilisateur.

# Actions : application ou fenêtre ?

Ci-dessus, nous créons les actions « new » et « open » comme faisant partie de la classe MyApplication. Les actions qui gèrent l'application elle-même (comme « quit »), doivent être créées de la même façon.

Quelques actions, comme « copy » et « paste » gèrent la fenêtre, pas l'application. Les actions gérant la fenêtre doivent être créées dans la classe window.

The complete example files contain both application actions and window applications. The window actions are the ones usually included in the application menu also. It is not good practice to include window actions in the application menu. For demonstration purposes, the complete example files which follow include XML in the UI file which creates the application menu which includes a "New" and "Open" item, and these are hooked up to the same actions as the menubar items of the same name.

# Fichier XML complet de l'interface utilisateur de cet exemple

<?xml version="1.0" encoding="UTF-8"?> <interface> <menu id="menubar"> <submenu> <attribute name="label">File</attribute> <section> <item> <attribute name="label">New</attribute> <attribute name="action">app.new</attribute> </item> <item> <attribute name="label">Quit</attribute> <attribute name="action">app.quit</attribute> </item> </section> </submenu> <submenu> <attribute name="label">Edit</attribute> <section> <item> <attribute name="label">Copy</attribute> <attribute name="action">win.copy</attribute> </item> <item> <attribute name="label">Paste</attribute> <attribute name="action">win.paste</attribute> </item> </section> </submenu> <submenu> <attribute name="label">Choices</attribute> <submenu> <attribute name="label">Shapes</attribute> <section> <item> <attribute name="label">Line</attribute> <attribute name="action">win.shape</attribute> <attribute name="target">line</attribute> </item> <item> <attribute name="label">Triangle</attribute> <attribute name="action">win.shape</attribute> <attribute name="target">triangle</attribute> </item> <item> <attribute name="label">Square</attribute> <attribute name="action">win.shape</attribute> <attribute name="target">square</attribute> </item> <item> <attribute name="label">Polygon</attribute> <attribute name="action">win.shape</attribute> <attribute name="target">polygon</attribute> </item> <item> <attribute name="label">Circle</attribute> <attribute name="action">win.shape</attribute> <attribute name="target">circle</attribute> </item> </section> </submenu> <section> <item> <attribute name="label">On</attribute> <attribute name="action">app.state</attribute> <attribute name="target">on</attribute> </item> <item> <attribute name="label">Off</attribute> <attribute name="action">app.state</attribute> <attribute name="target">off</attribute> </item> </section> <section> <item> <attribute name="label">Awesome</attribute> <attribute name="action">app.awesome</attribute> </item> </section> </submenu> <submenu> <attribute name="label">Help</attribute> <section> <item> <attribute name="label">About</attribute> <attribute name="action">win.about</attribute> </item> </section> </submenu> </menu> <menu id="appmenu"> <section> <item> <attribute name="label">New</attribute> <attribute name="action">app.new</attribute> </item> <item> <attribute name="label">Quit</attribute> <attribute name="action">app.quit</attribute> </item> </section> </menu> </interface>

# Fichier vala complet de cet exemple

public class MyWindow : Gtk.ApplicationWindow {

/* Callback functions for the window actions. */ void copy_cb (SimpleAction action, Variant? parameter) { print ("\"Copy\" activated\n"); }

void paste_cb (SimpleAction action, Variant? parameter) { print ("\"Paste\" activated\n"); }

void shape_cb (SimpleAction action, Variant? parameter) { print ("shape is set to %s\n", parameter.get_string(null)); action.set_state (parameter); }

/* Create the window actions. */ const ActionEntry[] actions = { /*{ "action name", cb to connect to "activate" signal, parameter type, initial state, cb to connect to "change-state" signal } */ { "copy", copy_cb }, { "paste", paste_cb }, { "shape", shape_cb, "s", "'line'"} };

internal MyWindow (MyApplication app) { Object (application: app, title: "MenuBar Example"); this.set_default_size (200, 200);

/* Setup window actions. */ this.add_action_entries (actions, this); } }

class MyApplication: Gtk.Application { protected override void activate () { new MyWindow (this).show (); }

/* Callback functions for the application actions. */ void new_cb (SimpleAction action, Variant? parameter) { //new MyWindow (this).show (); print ("You clicked \"New\"\n"); }

void quit_cb (SimpleAction action, Variant? parameter) { print ("You clicked \"Quit\"\n"); this.quit (); }

void awesome_cb (SimpleAction action, Variant? parameter) { var active = action.get_state ().get_boolean (); action.set_state (new Variant.boolean (!active)); if (active) print ("You unchecked \"Awesome\"\n"); else print ("You checked \"Awesome\"\n"); }

void state_cb (SimpleAction action, Variant? parameter) { print ("state is set to %s\n", parameter.get_string(null)); action.set_state (parameter); }

/* Create the application actions. */ const ActionEntry[] actions = { { "new", new_cb }, { "quit", quit_cb }, { "awesome", awesome_cb, null, "false" }, { "state", state_cb, "s", "'off'" } };

protected override void startup () { base.startup ();

/* Setup application actions. */ this.add_action_entries (actions, this);

/* Setup menubar and app_menu. */ /* Get the UI file. */ var builder = new Gtk.Builder (); try { builder.add_from_file ("menubar.ui"); } catch (Error e) { error ("Unable to load file: %s", e.message); }

/* Get the menubar from the builder. */ this.menubar = builder.get_object ("menubar") as MenuModel;

/* Get the app_menu from the builder. */ this.app_menu = builder.get_object ("appmenu") as MenuModel; } }

/* main creates and runs the application. */ public int main (string[] args) { return new MyApplication ().run (args); }

# Mnémoniques

Les étiquettes peuvent contenir des mnémoniques. Les mnémoniques sont les caractères soulignés dans l'étiquette et sont utilisés pour se déplacer à l'aide des touches du clavier. Par exemple, « _Fichier » au lieu de seulement « Fichier » dans l'attribut barredemenu.ui de l'étiquette.

Vous pouvez voir les mnémoniques en appuyant sur la touche Alt. Pour ouvrir le menu Fichier, appuyez sur la combinaison de touches AltF.

# Raccourcis clavier

Des raccourcis clavier peuvent être explicitement ajoutés aux définitions de l'interface utilisateur. Il est par exemple usuel de pouvoir quitter une application en appuyant sur la combinaison CtrlQ ou enregistrer un fichier avec CtrlS. Pour ajouter un raccourci clavier à la définition de l'interface, ajoutez simplement un attribut « accel » à l'élément.

`<attribute name="accel">&lt;Primary&gt;q</attribute>` will create the CtrlQ sequence when added to the `Quit` label item. Here, "Primary" refers to the Ctrl key on a PC or the ⌘ key on a Mac.

<item> <attribute name="label">_Quit</attribute> <attribute name="action">app.quit</attribute> <attribute name="accel">&lt;Primary&gt;q</attribute> </item>

# Chaînes de caractères traduisibles

Since GNOME applications are being translated into many languages, it is important that the strings in your application are translatable. To make a label translatable, simple set `translatable="yes"`:

`<attribute name="label" translatable="yes">Quit</attribute>`

# Documentation API associée

Dans cet exemple, les éléments suivants sont utilisés :

Glib.ActionEntry

Gtk.Builder

# Exercices