Introduction à gtkmm 2.4 Plan de cours 1. Vision d'ensemble 2. Gestion des évènements 3. Présentation des widgets

1 2 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Ce qui ne sera pas traité (en particulier) Vision d'ensemble

 Gtk+ (version C)

 Les détails des librairies sœurs – la Glib / Glibmm : Gestion de mémoire, types particuliers, entrées-sorties, ... – ,

 Détails de la libsigc 1. Introduction 2. Historique et position actuelle de Gtkmm  Gestion des erreurs et du logging 3. Organisation des librairies de Gtkmm  Internationalisation 4. Outils de développement  Les Tree View (pas de MVC en Gtk !) 5. Conventions de programmation de Gtkmm 6. Les basiques  Le parsing XML

 Comment créer une bonne interface ... 3 4 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

gtkmm Gtkmm vs (by Gtkmm developers)

Gtkmm does things in a more C++ way .  Binding C++ de Gtk (Gtkmm = Gtk--)  Qt has it's own Qt-specific containers, gtkmm uses std::string, std::list, std::vector, – Gtk+ : en C mais basé sur des concepts objet iterators, etc. It therefore duplicates a lot of stuff that is now in the standard library, such as containers and type information.  Ensemble de librairies pour la programmation  Gtkmm was able to use standard C++ to provide signals without changing the C+ + d'interfaces graphiques language. gtkmm uses pure C++. Qt requires extensions to C++ that are parsed by the moc pre-processor. Most significantly, they modified the C++ language to provide  Développé et maintenu par GNOME Foundation signals, so that Qt classes can not be used easily with non-Qt classes.  Sous licence LGPL 2.1  With gtkmm normal C++ memory management can be used. Qt demands that all widgets are dealt with as pointers, and that deletion of widgets is surrendered to  http://www.gtkmm.org parent widgets. – Téléchargements Arrangement of widgets seems to be simpler in gtkmm . In Qt, Containers and Layouts are separate classes, and child widgets must be added to both. – Documentations The gtkmm API tends to be more explicit . The behaviour of Qt classes is often – Qqs tutoriaux dependent upon the implicit effects of confusingly-overridden constructors. Also, Gtkmm and the other *mm modules allow you to build software which works more closely with the GNOME desktop . 5 6 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Look and feel Historique Bureau GNOME  1997 : + 1.0 (Mattis, Kimball & MacDonald) – U. Californie, Berkeley – Projet initié par la conception de GIMP – GTK = GIMP Tools Kit

 1998 : gtk+ 1.2 et gtkmm 1.2

 1998 : gtk+ 2.0 (620,000 lignes) et gtkmm2.0 – Pango, GdkPixbuf, ATW – Nouveaux Widget (Texte et Tree),

 2005 : Apparition de Cairo 1.0

Gnumeric sous Windows 7 8 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Situation actuelle Librairies usuelles

 Communauté de développement de Gtk active  Gtk ne réimplémente pas les structures usuelles de

 Toujours utilisée par GIMP programmation objet – Différence avec Qt  Librairie graphique utilisée pour GNOME, Xcfe  Utilise la librairie standard C++ (STL)  Encore assez largement utilisée – Container ( vector , list , map , ...) – Iterator et algorithm  Version actuelle assez abouti et stable – Sauf pour les String (utiliser les Glib:ustring !!)  Vers une version 3 ???  Détail qui a son importance : l'un des rares défaut de STL est de ne pas gérer l'UTF-8 (accents, etc...) !

 Toutes les librairies graphiques proposent leur version des string !

9 10 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Librairies associées de Gtkmm Organisation des

 Pango/Pangomm librairies – Gestion de l'affichage du texte

 Gdk – Primitives de dessin

 Cairo / Cairomm – Librairie de dessin vectoriel

 Facile de s'y retrouver: – Champs de compétence bien délimités – Chaque librairie utilise son propre namespace

11 12 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

pkg-config pkg-config

 pkg-config : outil de gestion des dépendances entre  Très utile pour faciliter l'écriture des commandes de les librairies installées sur le système compilation sans oublier d'includes

 La description de ces librairies se trouvent dans le

dossier :  Compilation : /usr/lib/pkgcon gfi gcc -c `pkg-config --flagc gtkmm2.4` -o  La commande suivante affiche tous les includes et fichier.o fichier.c librairies nécessaires à la compilation d’un fi chier

utilisation Gtkmm :  Édition de liens : gcc `pkg-config --libs gtkmm2.4` -o main pkg-confi g --libs --c fl ags gtkmm-2.4 fichier.o

13 14 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Outils de développement Outils de développement

 Interfaçage avec Eclipse CDT  Glade – cf. tutoriel en ligne pour la – http://glade.gnome.org/ création d'un projet C++ – Interface graphique pour sous Eclipse avec gestion créer simplement des des librairies Gtkmm. interfaces GTK+ – Facilité de codage de Eclipse – Existe pour Windows  auto-complétion – Alternative possible : Gazpacho

 GObject Builder – préprocesseur qui permet de construire des objets GObject

15 16 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Documentation Autres binds de Gtk+

 En ligne :  C++ : GtkMM

– http://www.gtkmm.org/documentation.shtml  C# : Gtk# – API  Java : Java-Gnome – Documentation générale  Python : PyGTK – Exemples  PHP : PHP-Gtk (partiel)

 Ada, OCaml, R, Perl, ...

http://www.gtk.org/language-bindings.html 17 18 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Portabilité Licence

 Peut être porté sur tout OS pouvant faire fonctionner un  GTK+ est un projet libre : GNU LGPL 2.1 (Library serveur X (et disposant d'une version convenable de la General Public licence)

XLib)  Les codes utilisant GTK+ ne doivent pas – Sous GNU/ obligatoirement être licenciés GPL ! – Sous Windows – La LGPL exige uniquement de conserver la trace des  Avec MinGW personnes ayant contribuer au code  Compatibilité partielle (mais difficile) avec MSVC – Valable aussi bien pour l'utilisation des librairies que du code – Sous MacOS X source

 Nouvellement possible avec Qt 4.5 !

19 20 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Introduction à Gtkmm Conventions de nommage

 Nom des classes : – Pas de préfixe (préfixé par le namespace !)  ex: Button ou Gtk:: Button  Attention : GtkButton réfère à la structure C d'un bouton dans la librairie Gtk+ – Chaque « mot » commence par une majuscule

1. Historique et position actuelle de Gtkmm  ex: Button, Text View, VB ox, Viewport, ... 2. Organisation des librairies de Gtkmm  Nom des membres 3. Outils de développement et binds 4. Conventions de programmation de Gtkmm – Commencent par « m_ » 5. Les basiques – Mots avec majuscules, séparés par des « _ » – ex : m_L abel _V alue(''Value :'');

 Label contenu dans un widget

21 22 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Conventions de nommage Conventions de nommage

 Méthodes  Les handlers : commencent par le mot clé « on » – Pas de majuscule  ex : virtual void on_ clicked() – Mots séparés par des « _ » – Fonctions connectés aux signaux correspondants

 Getter et setter – Fonctions déclarées comme protégées  Elles peuvent être surchargées lors de la conception de ses – set : Commence par le mot clé « set » propres widgets qui héritent des widgets par existants  ex. void set_ label (const Glib::ustring& label)  Propriétés de l'interface (GLib) : commencent par le mot – get : Commence par le mot clé « get » clé « property »  ex. Glib::ustring get_ label() const  ex : Glib::PropertyProxy_ReadOnly  Signaux : identifiés par le mot clé « » signal property_ focus_on_click() const – ex: signal_ clicked() – Fonctions rarement utiles ! – Préférer l'usage des set et des get !

23 24 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les includes Introduction à Gtkmm

 #include par exemples : – #include – #include – Sans majuscule !

 Attention aux inclusions provenant des librairies sœurs – #include 1. Historique et position actuelle de Gtkmm  #include 2. Organisation des librairies de Gtkmm – Inclut tous les widgets et les librairies sœeurs 3. Outils de développement et binds – Évite de se poser des questions d'inclusion 4. Conventions de programmation de Gtkmm 5. Les basiques

25 26 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Éléments basiques 1 : les widgets Éléments basiques 2 : les signaux

 Un application Gtkmm est constituée de Fenêtres  Gtkmm est basé sur les concepts de signal et de callback (windows) contenant des éléments d'interfaces (widgets) (ou handlers) tels que : – des signaux peuvent être émis par les widgets lors – boutons d'évènements comme un clic de souris – boîtes de textes – chaque widget a ses propres signaux qu'il peut émettre (dans la limite des signaux X !) – ... – les signaux peuvent être rattrapés pour être traités ( signal  Chaque type de widget est représenté par une classe handlers )  Les widgets sont organisés graphiquement  Les signaux de Gtkmm sont basés sur libsigc++ – en ligne ou en colonne de widgets

m_button1.signal_clicked().connect( sigc::mem_fun(*this, &HelloWorld::on_button_clicked) ); 27 28 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Éléments basiques 2 : les signaux Conception d'une application Gtkmm

 Comparaison avec Java/ 1. Conception de fenêtres et de widgets par la combinaison – Java/Swing : principe de Listeners des widgets existants

m_button1.addActionListerner( new ActionListener() { – Définition de la forme de l'interface public void actionPerformed(ActionEvent e) { system.out.println('coucou'); } 2. Conception des signal handlers }); – Gtkmm : un handler est une fonction qui implémente un – Définition des comportements potentiels de comportement à réaliser l'interfaces

m_button1.signal_clicked().connect( sigc::mem_fun(*this, 3. Connexions des signaux et signal handlers &HelloWorld::button_clicked) ); – Description du comportement de l'interface en fonction des void HelloWorld::button_clicked() { évènements (actions de l'utilisateur) cout << 'coucou' << end; } 29 30 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Éléments basiques 3 : 1er programme Première classe d'une « interface »

#include int main(int argc, char *argv[]) { #include Gtk::Main kit(argc, argv); int main(int argc, char *argv[]) Gtk::Window window; { Gtk::Main kit(argc, argv); return Gtk::Main::run(window); MaFenetre window; }

return Gtk::Main::run(window);  Gtk::Main kit(argc, argv) : Objet Gtk::Main indispensable pour créer } une application Gtkmm – Initialise Gtkmm – Lit les arguments destinées aux appli. X ( e.g. options -display, -geometry)

 Gtk::Window window : Créer un objet fenêtre

 Gtk::Main::run(window) : Exécute la fenêtre comme fenêtre principale

31 32 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Première classe d'une « interface » Plan de cours maFenetre::maFenetre() : Gtk::Window() { 1. Vision d'ensemble set_title('Ma fenetre'); Gtk::HBox m_box; 2. Gestion des évènements window.add(m_box); Gtk::Label m_label('Cliquer pour quitter'); 3. Présentation des widgets Gtk::Button m_button('Quitter'); m_box.pack_start(m_label); m_box.pack_start(m_button);

m_button.signal_clicked().connect(sigc::ptr_fun(&on_butto n_clicked)); m_label.show(); m_button.show(); }

void maFenetre::on_button_clicked() { ... } 33 34 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Gestion des évènements La boucle d'évènements

 Gtkmm implémente une boucle de gestion des évènements

– Correspond au thread de l'interface – Dans la classe Gtk::Main – Lancée par Gtk::Main::run()

1. La boucle d'évènements int main(int, char **) int main(int argc, char *argv[]) 2. Les évènements d'affichage { { 3. Surcharger les handlers Gtk::Main app(); Gtk::Main kit(argc, argv); app.run(); Gtk::Window window; 4. Connexion des signaux return 0; 5. Activer les signaux X masqués } return Gtk::Main::run(window); }

35 36 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

La boucle d'évènements La boucle d'évènements

 Exemple d'implémentation de la boucle d'évènements  Les évènements sont traités au travers des notions de :

– signal : un objet peut « émettre » un évènement décrit par un signal

while( program == running ) {  action d'un utilisateur ( e.g. souris ou keyboard) while(not event_table.empty ()) { const Event &e = event_table.pop();  envoi programmé ( e.g. timer) switch ( e.type ()) { – callback (ou handler ) : un objet peut être déclenché par des case Event::BUTTON_CLICKED : //Action à réaliser évènements, le callback est une fonction indique comment ... réagir ! case Event::NEED_REDRAW : ... default :  Connexion } : le programmeur associe un signal à un } callback

37 38 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

La boucle d'évènement La boucle d'évènements

 Table de connexion (pour se faire une vague idée du fonctionnement) Main Loop Events

While(events pending) Objet Évènement Action (callback)

Application Cacher exit() Callback Button1 Pressed fonction1() Expose events Re-Painting Button1 Released fonction2() invalidated regions Lookup callback for event Button2 Pressed fonction3() exit(0)

Button2 Pressed fonction4()

...

Hacking GTK+, -Muthiah A, Octave-Gtk+ team 39 40 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

La boucle d'évènements : 2 piles Gestion des évènements d'affichage

 Une pile d’évènements (FIFO) : entasse et se dépile  En fonction de ce qui se passe dans l'IHM, Gtkmm au fur et à mesure des demandes de l’utilisateur ou du détermine quels sont les zones à afficher programme – Ajout dans une queue de zones à afficher – Les signaux créent de nouveaux évènements, – Chaque zone correspond à un widget – Les callbacks les consomment  Lors du traitement d'une zone à afficher Gtkmm fait  Une pile d'évènements d'affichage ( expose appel à la fonction on_expose_event de la classe events ) Gtk::Widget – Retient les zones de l'écran à rafraichir,  En surchargeant la fonction on_expose_event on peut – Gestion intelligente : évite des doublons, mutualisation des ajouter ou redéfinir l'affichage d'un widget régions !

 Gtkmm assure la distribution des évènements

41 42 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Gestion des évènements d'affichage Gestion des évènements

bool ZoneDessin::on_expose_event(GdkEventExpose* event) { Glib::RefPtr gc = Gdk::GC::create(get_window());

Gdk::Color bleu("blue"); get_default_colormap()->alloc_color( bleu ); Gdk::Color rouge("red"); get_default_colormap()->alloc_color( rouge );

gc->set_foreground(bleu); get_window()->set_background(rouge); 1. La boucle d'évènements get_window()->clear(); 2. Les évènements d'affichage get_window()->clear(); get_window()->draw_line(gc, 1, 1, 100, 100); 3. Connecter des évènements get_window()->draw_layout(gc, 40, 40, 1. Surcharger les handlers create_pango_layout("Bonjour")); 2. Connexion des signaux return true; } 4. Activer les signaux X masqués

43 44 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Connexion d'un évènement Surcharger les handlers

 La connexion des évènements consiste à faire des ajouts  Les widgets disposent déjà de handlers prédéfinis et dans la « table des connexions » connectés par défaut

 Deux méthodes – Fonctions identifiées par le préfixe on_ – Surcharger les handlers – Les fonctions sont virtual protected – Établir des connexions – Chaque handler est associé a un évènement du widget – Exemples Gtk::Button : virtual void on_pressed () virtual void on_released () virtual void on_clicked () virtual void on_enter () virtual void on_leave () virtual void on_ activate ()

 Il faut surchargées ces fonctions pour implémenter l'action désirée – Nécessite de construire une classe spécifique pour chaque bouton 45 46 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Glib::SignalProxy0< void > signal_pressed () Glib::SignalProxy0< void > signal_released () Surcharger les handlers Les signaux Glib::SignalProxy0< void > signal_clicked () Glib::SignalProxy0< void > signal_enter () Glib::SignalProxy0< void > signal_leave ()  on_clicked() est appelé suite à un évènement X  Les signaux Glib::SignalProxy0< void > signal_activate ()

#include – Un « signal » est une fonction : #include int main(int argc, char *argv[])  caractérise un type d'évènement qui peut être émis #include { Gtk::Main kit(argc, argv);  n'envoie pas l'évènement lorsqu'on l'appelle class myButton : public Gtk::Button { Gtk::Window win; – Chaque classe de widget dispose de ses propres signaux public: win.set_title("buttonExample"); – myButton(){}; win.set_border_width(10); Identifiés par le préfixe signal_ virtual ~myButton(){}; – On retrouve les mêmes que pour les handlers prédéfinis myButton button; protected: win.add(button); – Exemples : signaux de Gtk::Button //Surcharge du callback : button.show(); virtual void on_clicked();  Il ne faut par faire appel aux signaux, ils servent à }; Gtk::Main::run(win); un usage interne pour déclarer des connexions ! void myButton::on_clicked() return 0; { };  Les signaux doivent être connectés à des callbacks pour printf("Clic!\n"); } déclencher une action 47 48 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les signaux et les callbacks Rappel sur les pointeurs de fonctions

 Connexions des signaux (sans paramètres)  Un pointeur de fonction () .connect( sigc::ptr_fun( &handler ) ); – ou functor – ou fonction objet Exemple est une variable qui représente une fonction  Permet d'abstraire des fonctions void on_button_clicked() {  Exemple Pointeur de fonction std::cout << "Hello World" << std::endl; int compare_function(int A, int B) { qui retourne un } return (A < B); entier et prend deux } paramètres entiers main() { ... Gtk::Button b("Hello World"); /* Déclaration d'une fonction */ void sort_ints(int* items, int nb, int (*cmpfunc)(int, int) ); b.signal_clicked() .connect( sigc::ptr_fun( &on_button_clicked ) ); ... } int main() { int items[] = {4, 3, 1, 2}; sort_ints(items, sizeof(items)/sizeof(int), compare_function ); 49 } 50 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Rappel sur les pointeurs de fonctions Les signaux et les callbacks

using namespace std;   Utilisation dans les // comparison, not case sensitive. Connexions des signaux (sans paramètres) bool compare_nocase (string first, string second) librairies standards { unsigned int i=0; () .connect( sigc::ptr_fun( &handler ) ); while ( (itolower(second[i])) return false; Exemple ++i; Il s'agit d'un pointeur } template if (first.length() mylist; } list::iterator it; mylist.push_back ("one"); main() { mylist.push_back ("two"); mylist.push_back ("Three"); Gtk::Button b("Hello World"); mylist.sort( compare_nocase ); b.signal_clicked() .connect( sigc::ptr_fun( &on_button_clicked ) ); cout << "mylist contains:"; for (it=mylist.begin(); it!=mylist.end(); ++it) } cout << " " << *it; cout << endl; http://www.cplusplus.com return 0; 51 52 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 } Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les signaux et les callbacks Les signaux et les callbacks

 La fonction connect() prend en paramètre un slot  Connexions des signaux (sans paramètres) – slot : représentation interne d'un pointeur de fonction () .connect( sigc::ptr_fun( &handler ) ); – Exemple de type : sigc::slot< bool , double >

 Fonction avec un paramètre de type double , et qui retourne un booléen Exemple

 La fonction construit un slot à partir sigc::ptr_fun void on_button_clicked() { d'une fonction std::cout << "Hello World" << std::endl; – On donne simplement un pointeur de fonction ( sans } parenthèses ! ) main() { – Exemple : void foo( int ) Gtk::Button b("Hello World"); { } b.signal_clicked() .connect( sigc::ptr_fun( &on_button_clicked ) ); } sigc::slot< void, int > sl = sigc::ptr_fun(& foo );

53 54 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Connexion à une méthode Connexion à une méthode

 sigc::ptr_fun( &handler ) : sert uniquement à connecter une fonction globale

 sigc::mem_fun( objet , &handler ) : sert à connecter une void on_button_clicked();

méthode d'une classe pour un objet particulier class some_class { void on_button_clicked(); – Utilisation identique : };

some_class some_object; void MaClasse::action() { main() { std::cout << "Hello World" << std::endl; Gtk::Button b; } b.signal_clicked().connect( sigc::ptr_fun(&on_button_clicked) ); b.signal_clicked().connect( sigc::mem_fun(some_object, void main() { &some_class::on_button_clicked) ); MaClasse obj , obj2; } Gtk::Button b("Hello World"); b.signal_clicked().connect( sigc::mem_fun( obj ,&MaClasse::action ) ); }

55 56 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Connexion des signaux aux callbacks Exemple de connexion

cf. Exemple buttonExample2.cpp  Les détails techniques permettent de bien comprendre int main(int argc, char *argv[]) ce qui se passent mais peuvent être oublié dans la #include { #include Gtk::Main kit(argc, argv); pratique d'utilisation de Gtkmm #include Gtk::Window win; class myButton : public win.set_title("buttonExample"); Gtk::Button win.set_border_width(10);  À retenir, connexions des signaux (sans paramètres) { public: myButton button; () .connect( sigc::ptr_fun( &handler ) ); myButton(){}; win.add(button); virtual ~myButton(){}; () .connect( sigc::mem_fun( &handler ) ); button.signal_enter().connect( public: sigc::mem_fun(button, void clicked(); &myButton::clicked) }; );

button.show(); void myButton::clicked()

{ Gtk::Main::run(win); printf("Click!\n"); return 0; } 57 }; 58 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Exemple d'appel à un signal Signaux/callbacks avec paramètres

 Certains signaux retournent valeurs ou ont des class myButton : public int main(int argc, char *argv[]) paramètres Gtk::Button { { public: Gtk::Main kit(argc, argv);  Les handlers doivent les gérer myButton(){}; virtual ~myButton(){}; Gtk::Window win;  La fonction exige la correspondance entre win.set_title("buttonExample 3"); connect() public: win.set_border_width(10); les profils de fonctions ( type safety à la compilation) void on_button_enter(); protected: myButton button; () .connect( sigc::ptr_fun( &handler ) ); virtual void on_clicked(); win.add(button); }; button.signal_enter().connect( sigc::mem_fun(button, void myButton::on_button_enter(){Ne marche pas ! Profil attendu Profil du handler printf("enter!\n"); &myButton:: on_button_enter ) signal_clicked(); ); décrit dans le construit par }; Mettre on_clicked() à la place !! signal proxy ptr_fun button.show(); void myButton:: on_clicked() { printf("Click!\n"); Gtk::Main::run(win); return 0; }; 60 62 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 }; Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Signaux/callbacks avec paramètres Signaux/callbacks avec paramètres

 La fonction connect() exige la correspondance entre  La fonction connect() exige la correspondance entre les profils de fonction les profils de fonction () .connect( sigc::ptr_fun( &handler ) ); () .connect( sigc::ptr_fun( &handler ) );

 Exemple  Exemple signal_focus() .connect( ptr_fun( &ma_fonction ) ) signal_focus() .connect( ptr_fun( &ma_fonction ) )

Glib::SignalProxy 1 signal_focus() Glib::SignalProxy 1 signal_focus()

bool ma_fonction(Gtk::DirectionType direction); bool ma_fonction(); Les profils de fonction ne correspondent pas ! ptr_fun( &ma_fonction ) : slot< bool, Gtk::DirectionType > ptr_fun( &ma_fonction ) : slot< bool >

63 64 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Signaux/callbacks avec paramètres Signaux/callbacks avec paramètres

 De même avec plusieurs paramètres (maximum 7)  Pour forcer la correspondance entre profils, il faut

 exemple de signal Gtk::editable parfois utiliser des fonctions de binding

– sigc::bind : ajouter des paramètres au handler – sigc::hide : masquer des paramètres du handler Glib::SignalProxy 3 – signal_insert_text() sigc::bind_return : ajouter un valeur de retour au handler – sigc::hide_return : masque le type de retour (remplacé par void ) void on_insert_text( const Glib::ustring& text, int length, int* position );

65 66 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Signaux/callbacks avec paramètres Signaux/callbacks avec paramètres

 Exemple d'utilisation de la fonction sigc::bind()  Exemple d'utilisation de la fonction hide_return()

– fonction : virtual void mon_handler(Glib::ustring data); – Il faut que le type de retour de la fonction corresponde – On veut la déclencher par un clic de bouton : également Glib::SignalProxy0< void > signal_clicked() – handler : bool mon_handler(); – signal : Glib::SignalProxy0< void > signal_clicked() – Connexion à réaliser m_button.signal_clicked() .connect( sigc::bind( sigc::mem_fun(*this, &mon_handler) , Glib::ustring("button 1") ) ); m_button.signal_clicked() .connect( sigc::hide_return( sigc::mem_fun(*this, &mon_handler) ) Valeur du ); paramètre supplémentaire

cf. exemple 4 : cf. exemple 4 : buttonExample_bind 67 buttonExample_bind 68 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Déconnection d'un signal Avantages et inconvénients

 Pour déconnecter un signal, il suffit de faire appel à la  Surcharge des handlers fonction disconnect() d'une connexion – Avantage : facile et rapide – Nécessite d'avoir conserver une trace de la connexion quelque – Inconvénients :

part !  nécessite de surcharger la classe de base pour chaque nouveau comportement  Les signaux peuvent être connectés et déconnectés  solution nécessitant une forte dépendance entre la classe de l'objet dynamiquement appelant et celle de l'objet appelé

sigc::connection connexion =  Connexion de signaux button_test.signal_clicked().connect ( sigc::ptr_fun( &test_connection ) – Avantages : );  générique

(...)  forte séparation appelant/appelé possible – connexion.disconnect(); Inconvénients :  les binds de functors

cf. exemple buttonExample_dynamicdisconnection  69 peut nécessiter un peu plus de travail de réflexion préalable ! 70 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les signaux et les callbacks Gestion des évènements

Résumé

– Chaque Widget est associé à des évènements – un évènement

 une fonction signal_XXX() : qui servir à connecter des actions aux évènements  une fonction on_XXX( params ) : qui peut être surchargée – Utilisation de la fonction connect() 1. La boucle d'évènements signal_XXX() .connect( mem_fun( object, &Class::function ) ) 2. Les évènements d'affichage  Les fonctions de binding ( sigc::bind()) servent à modifier les 3. Connecter des évènements paramètres de la fonction à appeler pour correspondre au profil du signal ! 1. Surcharger les handlers 2. Connexion des signaux  La fonction appelée doit récupérer tous les paramètres du signal 4. Activer les signaux X masqués – Il est possible de connecter et déconnecter dynamiquement les signaux 71 72 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les signaux X usuels Les signaux X usuels

 Dans la classe Gtk::Widget : tous les widgets peuvent,  Les signaux d'affichage

en principe, les utiliser Glib::SignalProxy1< bool, GdkEventExpose* > signal_expose_event () Glib::SignalProxy1< bool, GdkEventExpose* > signal_configure_event ()  Les signaux des évènements X (repérés par _event ) Glib::SignalProxy0 signal_realize () Glib::SignalProxy0 signal_hide () Glib::SignalProxy0 signal_show ()

Glib::SignalProxy1 signal_event()  Glib::SignalProxy1 signal_button_press_event() Les signaux de Drag & Drop

Glib::SignalProxy1 signal_button_release_event() Glib::SignalProxy1&> signal_drag_begin () Glib::SignalProxy1&> signal_drag_end () Glib::SignalProxy1 signal_key_press_event() Glib::SignalProxy2&,guint > ... signal_drag_leave () (...)

73 74 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Activation des signaux X usuels Activation des signaux X usuels

 Utilisation par défaut des signaux X  Exemple : activation des clics de souris sur un – Dans un certain nombre de widget, les signaux X sont déjà Gtk:DrawingArea utilisés pour les signaux propres à l'objet – Pour les autres, ils ne sont pas écouté par Gtk

 Récupérer les signaux X d'un widget Gtk::DrawingArea widg; – Dans le premier cas, on peut utiliser un EventBox , et widg. add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); indiquer les signaux à écouter widg. signal_button_press_event() .connect( ... ); – Dans le second, il suffit (mais nécessaire) d'indiquer les widg. signal_button_release_event() .connect( ... ); signaux à écouter

75 76 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Exemple : rendre un label cliquable La boucle d'évènements

bool on_button_clicked(GdkEventButton*)  Petit exercice de compréhension { std::cout << "fonction clicked\n"; – On propose d'afficher l'évolution d'un traitement en modifiant }; le label d'un bouton ainsi Gtk::EventBox m_EventBox ; fenetre.add(m_EventBox); – Que va-t-il se passer en pratique ? Gtk::Label m_Label("Mon label") ; m_EventBox .add( m_Label ); m_Label.set_size_request(110, 20); void go() { long i=LONG_MIN; //Préparation pour l'action (a faire avant l'affichage pour éviter long max= LONG_MAX; les erreurs) while( i < max ) { m_EventBox .set_events(Gdk::BUTTON_PRESS_MASK); double result = cos((double)i*PI/180); button->set_label( Glib::ustring::compose("done %1%%", (...) (double)i/(double)max) ); i++; //Connexion : sur l'Eventbox ! } m_EventBox .signal_button_press_event() .connect( sigc::ptr_fun( &on_bu } tton_clicked ) );

cf. exemple 5 : Almostlong.cpp 77 78 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Plan de cours Présentation des widgets

1. Vision d'ensemble  Objectif : 2. Gestion des évènements – Faire une revue rapide, non-exhaustive des widgets usuels – S'appuyer fortement sur la documentation 3. Présentation des widgets  Pour que je ne recopie pas ce qui y est déjà ! ( principe n°1 de l'informaticien : ne pas refaire ce qui fonctionne bien ! )

 Pour que vous trouviez facilement les informations dont vous avez besoin – Donner quelques exemples pratiques exemplaires de l'utilisation de Widgets

80 81 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Présentation des widgets La classe Widget

 Fonction liée à la géométrie du Widget

– Déterminer la taille d'un widget

 void set_size_request (int width=-1, int height=-1)

 Les requêtes de taille ne sont pas nécessairement satisfaites ! – Connaître la taille d'un widget

 get_width() et get_height() 1. La classe Widget  Allocation get_allocation () const 2. La hiérarchie des Widgets  Allocation : permet de connaître la taille et la position du 3. Présentation de qqs des widgets standard widget (alloué par le windows manager) 4. Autres éléments d'une interface

82 83 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

La classe Widget La classe Widget

 Modifier le style d'un Widget  Les fonctions d'affichage – style = couleurs, polices par défaut, pixmap de fond, ... – void show(), void show_all(), void show_now() – fonctions modify_...()  show() : Flags a widget to be displayed, – Les widgets qui ne sont pas flaggés ne seront pas affichés !! – annulé avec la fonction unset_...()  show_all() : Recursively shows a widget, and any child widgets  Modifier la couleur de fond d'un Widget (if the widget is a container), – void modify_bg (StateType state, const Gdk::Color& color)  show_now() : Shows a widget. -> Rentre dans la boucle – Gtk::StateType = {STATE_NORMAL, STATE_ACTIVE, principale et attend que le widget soit effectivement affiché. STATE_PRELIGHT, STATE_SELECTED, STATE_INSENSITIVE} Attention à son utilisation (!) – color = Gdk::Color('yellow'); (Voir /usr/share/X11/rgb.txt) – void queue_draw() et void queue_draw_area()  La modification passe par l'appel d'un évènement X. Le  Invalide une région de l'interface

Widget doit pouvoir le recevoir pour que la modification  Dans la boucle de traitement , une fois les évènements traités soit effective ! les régions invalidées reçoivent des évènements expose_event .

84 85 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Hiérarchie des Widgets Hiérarchie des Widgets

86 87 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Widget standard Fenêtre ( Gtk::Window)

 La classe est le widget représentant une fenêtre Standard Widgets Layout Widgets MVC Widgets Window dans l’environnement graphique.    Button Window TreeView     Label Container TextView C'est la seule classe représentant un « vrai » objet X    Entry Box ListView  – possède les fonctions en relation avec le window manager ,  Radio Table   Check Scrolled Window comme par exemple iconifi er la fenêtre, l’enrouler, etc.  Menubar   Menu On ne peut lancer qu'un Gtk::Window avec run()  Scrollbar Drawing Widgets Misc Widgets int main ( int argc , char ** argv ) {  Progressbar   Pane Gtk::Main app(argc , argv);  Ruler Drawing Area   Fixed Gtk::Window w;  Scale Window   Separators  Dialogs Curve app.run(w);  Tearoff menu items }  Tooltips  Preview  Notebook

Hacking GTK+, -Muthiah A, Octave-Gtk+ team 88 89 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Fenêtre ( Gtk::Window) Boutons

 On peut y inclure 1 autre Widget (mais pas 2!)  Gtk::Button ( doc ) – Gtk::Button button; – signal_clicked() – window. add (button);  Gtk::ToggleButton ( doc )  Qqs membres spécifiques – Bouton qui peut conserver son état – toggle() to switch the state – void set_title(const Glib::ustring& title) – void set_active(bool =true) – void set_icon (const Glib::RefPtr& icon) – bool get_active() – void resize(int width, int height)  Gtk::CheckButton ( doc )  Pas besoin de passer par la fonction set_size_request(...)  Gtk::RadioButton ( doc )

90 91 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les mnémonics ComboBox

 Mnémonic : permet à l'utilisateur d'une interface de  Liste de choix déroulante déclencher rapidement le bouton par une combinaison de touche

 Exemple: Alt+B  m_Combo.append_text('...') : ajoute un item  signal_changed() : signale la modification d'un choix (Sans arguments)  Dans le constructeur :  Glib::ustring get_active_text() : récupère le – Button('mon _Button' , true ) texte de l'item affiché  Fonctions add_label et add_mnemonic_label

92 93 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

ComboBox : exemple Entry

ExampleWindow::ExampleWindow()  Entrée textuelle sur 1 ligne { m_Combo.append_text("something");  Propriétés : m_Combo.append_text("something else"); m_Combo.append_text("something or other"); – visible (= false : mode password) add(m_Combo); – editable – max_length //Connect signal handler: m_Combo.signal_changed().connect(sigc::mem_fun(*this,  Gestion du contenu textuel : &ExampleWindow::on_combo_changed) ); – set_text(Glib::ustring t) show_all_children(); – Glib::ustring get_text() }  Signaux : void ExampleWindow::on_combo_changed() { – signal_changed(), signal_insert_text(), Glib::ustring text = m_Combo.get_active_text(); signal_delete_text() if(!(text.empty())) std::cout << "Combo changed: " << text << std::endl; – signal_insert_at_cursor() (retourne la chaîne insérée) } – signal_selection_received(), signal_selection_get() 94 95 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Label Label

 Le Label est un composant simple qui représente une  Le Label est un composant simple qui représente une chaîne de caractères dans une zone graphique. chaîne de caractères dans une zone graphique.

Label (const Glib::ustring& label, AlignmentEnum xalign, int main( int argc , char ** argv ) { AlignmentEnum yalign=ALIGN_CENTER, bool mnemonic=false) Gtk::Main app(argc , argv); Gtk::Window w ; Gtk::Label label ; label. set_markup("hello world !"); Label( 'Bonjour !' ); w.add( label ); Label( Glib::ustring('Banzaï') ); app.run( w ); }

96 97 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Label Solution : les EventBox

 C'est un élément qui ne permet pas de recevoir des  Exemple : modification de la couleur de fond d'un label

évènements X Gtk::EventBox m_eventbox; m_eventbox.add(m_label); – Formellement, il ne s'agit pas d'une fenêtre X m_eventbox.modify_bg(Gtk::STATE_NORMAL, Gdk::Color('red') ); – exemple ( label_Color.cpp ) : m_eventbox.show(); m_label.show(); m_label.modify_bg( Gtk::STATE_NORMAL, Gdk::Color('red') )

  Modifie la couleur du fond d'un widget Uniquement pour les « non-bin »  Fait appel à un évènement X pour modifier cette propriété, mais  Généralement utilisé sur les widget Misc l'évènement n'est pas pris en compte : le label reste gris !! – Label , Image et Arrow

98 99 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Autres widget « non-bin » Solution : les EventBox

 Gtk::Pixmap  Gtk::Alignment  Exemple: récupérer les évènements X d'un Label  Gtk::RadioButton Gtk::Arrow – set_events : Définit les types d'évènement X qui doivent être considérés  Gtk::Range Gtk::Box – signal_button_press_event() : correspond à un signal X de pression  Gtk::ScrolledWindow  Gtk::CheckButton de bouton  Gtk::Separator  Gtk::Fixed  Nom de fonction préfixée par ' _event '  Gtk::Table Gtk::Image  Gtk::Toolbar Gtk::Item  Gtk::AspectFrame Gtk::Label m_label("Click here");  Gtk::Frame add(m_eventbox); Gtk::MenuItem m_eventbox.add(m_Label);  Gtk::VBox Gtk::Notebook m_label.set_size_request(110, 20);  Gtk::HBox Gtk::Paned m_eventbox.set_events(Gdk::BUTTON_PRESS_MASK);  Gtk::VSeparator m_eventbox.signal_button_press_event(). connect( sigc::mem_f  Gtk::HSeparator un(*this, &ExampleWindow::on_eventbox_button_press) );

100 101 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les containers / conteneurs Les containers / conteneurs

 Deux types de conteneurs  Deux types de conteneurs Parent – Les conteneurs à un unique widget – Les conteneurs à un unique widget

 Frame  En tant que widget, il est positionné dans un Conteneur simple  Dialog widget parent (sauf Gtk::Window )

 Alignement  Contient un autre widget : il est ajouté avec une  Window fonction add  EventBox – Les conteneurs multiples

– Les conteneurs multiples, dont  En tant que widget, il est positionné dans un Parent  HBox : une liste dynamique d'espaces horizontaux widget parent  VBox : une liste dynamique d'espaces verticaux  Contient un ou plusieurs autres widgets Conteneur  Table : Grille de Widgets  Les fonctions d'ajout dépendent des conteneurs multiple  NoteBook : un widget à onglets  Menus/Toolbar

 Fixed : un conteneur à placement libre 102 103 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les containers / conteneurs Les containers / conteneurs

 Les containers permettent de structurer une interface  Représentation des zones sous la formes d'arbres graphique en « zones » – Les zones sont disjointes – Les séparations sont uniquement verticales et horizontales  Exception Gtk::Fixed : container de placement libre des widgets

Conteneurs multiples

Conteneurs simples

104 105 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Frame Alignement

 Élément décoratif  Alignement d'un widget dans un conteneur

 Contient le widget à aligner

 Propriétés  Constructeur : – le label – Alignment (AlignmentEnum xalign, AlignmentEnum yalign=Gtk::ALIGN_CENTER, float xscale=1.0, float Gtk::Window m_window; Gtk::Frame m_Frame; yscale=1.0) Gtk::DrawingArea m_DrawingArea;

m_Frame.set_label('Frame'); Gtk::Window m_window; Gtk::Alignment m_Alignment(Gtk::ALIGN_RIGHT, // Ajout d'un widget fils Gtk::ALIGN_CENTER, 0.0, 0.0); m_Frame.add (m_DrawingArea); Gtk::Button m_Button(''Close'');

// Ajout du cadre à la fenêtre m_window.add( m_Alignment ); m_window.add( m_Frame ); m_Alignment.add (m_Button ); 106 107 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Containers multiples Les Boxes (HBox ou VBox)

 Les conteneurs multiples, dont  Fonctions d'addition de widget – HBox : une liste dynamique d'espaces horizontaux – void pack_start(Gtk::Widget& w); ou void – VBox : une liste dynamique d'espaces verticaux add(Gtk::Widget& w); – – Table : Grille de Widgets void pack_end(Gtk::Widget& w);  – NoteBook : un widget à onglets Fonction de suppression de widget – Menus/Toolbar – void remove(Gtk::Widget& w); – Fixed  Fonction de réordonnancement : – void reorder_child(Gtk::Widget& child, int pos)

108 109 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les Boxes (HBox ou VBox) Les Boxes (HBox ou VBox)

void pack_start (Widget& child, PackOptions options=PACK_EXPAND_WIDGET,  guint padding=0) Exemple : pack_example.cpp void pack_start (Widget& child, bool expand, bool fill, guint padding=0)

 Détails d'une fonction pack – PackOptions

 PACK_SHRINK : Space is contracted to the child widget size. Gtk::VBox m_box; (expand = false, peu importe fill ) Gtk::Label m_label1("1"), m_label2("2"), m_label3("3");

 PACK_EXPAND_PADDING : Space is expanded, with extra space bool expand=true; //Indique si le box doit s'étirer avec le filled with padding. ( expand = true, fill =false ) parent bool fill=true; //Indique si les widgets du box doivent  PACK_EXPAND_WIDGET : Space is expanded, with extra space s'étirer avec le box ! (uniquement si expanding = true) filled by increasing the child widget size. ( expand = true, fill int padding=10; //minimum d'espace entre les widgets du box =true ) m_box.pack_start (m_label1 , expand, fill, padding); – Padding : espace fixe autour des widgets m_box.pack_start (m_label2 , true, fill, padding); m_box.pack_start (m_label3 , expand, fill, padding); 110 111 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les Boxes (HBox ou VBox) Fixed : un container particulier !

 Permet de positionner les widget où l'on veut, avec les tailles que l'on veut – Sort des contraintes VBox ou Hbox,

 Fonctions – void move(Widget& w, int x, int y) – void put(Widget& w, int x, int y) – void remove(Widget &w)

 L'utilisation de ce container est peu recommandée dans les interfaces classiques – problèmes d'overlapping

112 113 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Widget standard Présentation des widgets

Standard Widgets Layout Widgets MVC Widgets

   Button Window TreeView    Label Container TextView    Entry Box ListView   Radio Table   Check Scrolled Window  Menubar  Menu  Scrollbar Drawing Widgets Misc Widgets 1. La classe Widget  Progressbar   Pane  Ruler Drawing Area  2. La hiérarchie des Widgets  Fixed  Scale Window   Separators 3. Présentation de qqs des widgets standard  Dialogs Curve  Tearoff menu items 4. Autres éléments d'une interface  Tooltips  Preview  Notebook

Hacking GTK+, -Muthiah A, Octave-Gtk+ team 114 115 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Autres éléments d'une interface Les boîtes de dialogue

 Autres éléments permettant de construire une interface  Boîte de dialogue : Affiche des messages courts ou de – Les boîtes de dialogue récupérer des informations courtes – Les menus  Classe Gtk::Dialog – La barre d'outils – Fenêtre composée verticalement avec des Gtk::Label et des  ou encore ( cf. documentation) Gtk::Entry  Fonctions de pack sur le VBox récupéré par : Vbox* get_vbox() – La barre d'état – Associée à une action de retour – Les documents récents  Des boutons ( Button* add_button (const Glib::ustring& – Le clipboard button_text, int response_id) ) – Les impressions  ou d'autres actions (cf. add_action_widget(...) ) – Est exécutée avec la fonction int run()  retourne uniquement un entier correspondant à l'action de l'utilisateur 116 117 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les boîtes de dialogue Les boîtes de dialogue

 MessageDialog – Permet d'afficher des messages à l'utilisateur

MessageDialog (Gtk::Window& parent, const Glib::ustring & message, bool use_markup = false , MessageType type = MESSAGE_INFO , ButtonsType Gtk::MessageDialog dialog(*this, "This is a QUESTION MessageDialog", false /* buttons = BUTTONS_OK , bool modal = false ) use_markup */, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL); dialog.set_secondary_text( "And this is the secondary text that explains things."); int result = dialog .run() ; //Handle the response: switch(result) { BUTTONS_NONE case(Gtk::RESPONSE_OK): { MESSAGE_INFO std::cout << "OK clicked." << std::endl; BUTTONS_OK break; MESSAGE_WARNING } BUTTONS_CLOSE case(Gtk::RESPONSE_CANCEL): { MESSAGE_QUESTION std::cout << "Cancel clicked." << std::endl; BUTTONS_CANCEL break; MESSAGE_ERROR } BUTTONS_YES_NO default: { MESSAGE_OTHER std::cout << "Unexpected button clicked." << std::endl; BUTTONS_OK_CANCEL break; } 118 } 119 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Autres boîtes de dialogue Les menus et barre d'outils

 FileChooserDialog  Les menus et les icônes d'une barre d'outils sont

 ColorSelectionDialog associés à des Gtk::Action

  FontSelectionDialog Pour créer un menu, il faut créer un groupe d'actions Gtk::ActionGroup  AboutDialog

 Le groupe d'actions est géré par le UIManager – Disposition dans le menu – Affichage dans la barre d'outils

120 121 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les menus et barre d'outils Les menus et barre d'outils

 Création d'un groupe d'actions  Création d'un groupe d'actions – Utilisation de la fonction create() – Utilisation de la fonction create()

Glib::RefPtr m_refActionGroup = Glib::RefPtr m_refActionGroup = Gtk::ActionGroup::create() ; Gtk::ActionGroup::create() ;

m_refActionGroup-> add ( Gtk::Action::create("MenuFile", "_File") ); m_refActionGroup-> add ( Gtk::Action::create("MenuFile", "_File") ); m_refActionGroup-> add ( Gtk::Action::create("ExportData", "Export Data"), sigc::mem_fun(*this, &ExampleWindow::on_action_file_open) ); – Ajoute une action identifiée par « MenuFile » et qui affiche le texte « File » – Création d'une « vraie » action

– C'est un menu racine : contient des sous-menus et n'est pas  Associe l'action à un handler : action à réaliser lors du clic ! associé à une action – Mnémonic : « _ » pour les touches d'accès rapide

122 123 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les menus et barre d'outils Les menus et barre d'outils

 Création d'un groupe d'actions  UIManager – Utilisation de la fonction create() – insert_action_group : associe les actions à gérer – add_accel_group : ajout de la gestion, par la fenêtre, des Glib::RefPtr m_refActionGroup = Gtk::ActionGroup::create() ; touches de raccourcis du menu m_refActionGroup-> add ( Gtk::Action::create("MenuFile", "_File") ); m_refActionGroup-> add ( Gtk::Action::create("ExportData", "Export Data"), Glib::RefPtr m_refUIManager = Gtk::UIManager::create(); sigc::mem_fun(*this, &ExampleWindow::on_action_file_open) ); m_refUIManager->insert_action_group(m_refActionGroup); m_refActionGroup-> add ( Gtk::Action::create("New", Gtk::Stock::NEW), sigc::mem_fun(*this, &ExampleWindow::on_action_file_new) ); add_accel_group(m_refUIManager->get_accel_group()); m_refActionGroup-> add ( Gtk::Action::create("Quit", Gtk::Stock::QUIT), sigc::mem_fun(*this, &ExampleWindow::on_action_file_quit) );

Gtk::Stock : internationalisation dans Gtkmm

124 125 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Les menus et barre d'outils Les menus et barre d'outils

 UIManager  Réalisation du menu et de la barre d'outil

Glib::ustring ui_info =  La fenêtre doit pouvoir contenir plusieurs widgets => "" " " utilisation d'un vbox "

" " " " " " " " " " " " " " " Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar"); " " m_Box.pack_start(*pMenuBar, Gtk::PACK_SHRINK); " " Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ; " " m_Box.pack_start(*pToolbar, Gtk::PACK_SHRINK); " " " " " " " " " " " " ""; m_refUIManager->add_ui_from_string(ui_info); 126 127 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010

Bibliographie

 Cours de C++ et Gtk-- , Quesnel Gauthier, 2006

– http://www-lil.univ-littoral.fr/~quesnel/cplusplus.php

 Programming-with-gtkmm , Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Jason M’Sadoques, Ole Laursen, Gene Ruebsamen, Cedric Gustin, Marko Anastasov, and Alan Ott , 379 pages, 2006

– http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/pdf/programming-with-gtkmm.pdf

 Fondations of Gtk+ development , Andrew Krause, Apress, 629 pages, 2007.

– www.gtkbook.com/

 Sites internet

– www.gtk.org – www.gtkmm.org

 Pointeur sur les ressources de ce cours – http://www.irisa.fr/dream/Pages_Pros/Thomas.Guyet/enseignements/OCI/

128 Guyet Thomas - Cours OCI - M2 GL - IFSIC - 2010