Académique Documents
Professionnel Documents
Culture Documents
N
1
ous abordons ici la cr eation dinterfaces graphiques fen etr ees, qui constituent la plus grande partie des applications actuelles. Une fen etre est un el ement graphique, souvent rectangulaire qui peut contenir ` un programme peuvent correspondre de des menus, des boutons, des champs de saisie de texte... A nombreuses fen etres.
La programmation dune application graphique n ecessite lutilisation dune biblioth` eque en ce sens quune telle pratique simplie enorm ement le d eveloppement. Rien ninterdit ` a un programmeur de dessiner un rectangle ` a l ecran, qui sera appel e fen etre, de dessiner des petits rectangles qui seront appel es boutons, et de faire en sorte que lorsque lutilisateur clique sur ces boutons, leur image soit modi ee de telle fa con quon ait limpression quil senfonce. N eanmoins, entrer dans de tels m eandres rend l ecriture dun programme beaucoup plus longue. Le but ici, est de se concentrer sur ce ` a quoi doit servir le programme, et de laisser les t aches de gestion des el ements graphiques ` a une biblioth` eque qui contient d ej` a tout le code de leur achage. Il existe de nombreuses biblioth` eques pour cr eer des interfaces graphiques, certaines r eserv ees ` a un syst` eme dexploitation particulier (Windows, GNU/Linux...), dautres dont le code est ecrit pour plusieurs syst` emes. De telles biblioth` eques sont dites portables et permettent en th eorie dutiliser le m eme code source pour di erents syst` emes (on obtiendra un programme ex ecutable d edi e` a un syst` eme particulier en compilant le code source pour ce syst` eme), sans avoir ` a le modier. Lutilisation dune biblioth` eque portable est largement conseill ee, et le choix reste assez important : Qt, Gtk, Fltk, Graphapp, WxWindows,... On distingue ces biblioth` eques selon quelles sont pr evues pour tel ou tel type de langage de programmation. Qt et Fltk sont faites pour programmer en C++, par exemple, alors que Gtk et Graphapp sont utilisables en C. On les distingue aussi en fonction de leur richesse, cest ` a dire essentiellement en fonction de la diversit e des el ements graphiques quelles proposent (fen etres, boutons, champs de saisie, menus, etiquettes, editeurs de textes, barres de d element...)1 . Dans la suite nous nous int eresserons ` a la biblioth` eque Graphapp, qui nest pas parmi les plus riches, mais qui reste parmi les plus simples ` a utiliser.
Programmation ev enementielle
1. cr eation des fen etres, des boutons et des autres el ements graphiques ; 2. attente dun ev enement (fermeture dune fen etre, appui sur un bouton, d eplacement de la souris, appui sur une touche du clavier, ...) ; 3. traitement dun ev enement, par une proc edure ecrite ` a cet eet, et nomm ee callback (ou encore fonction r eexe) ; 4. retour ` a l etape 2.
1. d ecrire linterface en pr ecisant o` u il veut placer tel bouton, telle etiquette et tel champ de saisie 2. ecrire les proc edures callback qui seront appel ees par le syst` eme de gestion des ev enements de la biblioth` eque lorsque lutilisateur agira sur tel ou tel el ement. Nous allons illustrer ici nos propos avec la r ealisation dun convertisseur de monnaie. Notre interface comportera un champ pour entrer une valeur num erique, une liste de choix pour choisir la monnaie de d epart, une liste de choix pour choisir la monnaie darriv ee, une zone pour indiquer le r esultat de la conversion, un bouton pour demander la conversion et un bouton pour quitter :
Voici un sc enario dutilisation du convertisseur : Le convertisseur sache ` a l ecran. Lutilisateur entre une valeur num erique ` a convertir (par exemple 150). Lutilisateur clique sur convertir. La valeur convertie (en euros) sache au dessous de 150.0. Lutilisateur s electionne ( (Dollars) ) dans la liste du bas. Le convertisseur ache l equivalent en dollars de 150 francs. Lutilisateur clique sur ( (Quitter) ). Le programme se termine. La gure 1.1 illustre la fa con dont doivent sarticuler les actions de lutilisateur avec les t aches eectu ees par le programme. Dans la colonne de gauche sont repr esent ees les t aches eectu ees par la machine et dans celle de droite les t aches eectu ees par lutilisateur. Le temps s ecoule de haut en bas. Nous voyons que, except e lors du d ebut du programme (achage des el ements graphiques), le programme doit ( (r epondre) ) dune certaine mani` ere aux actions de lutilisateur. Mais le programme ignore ce que va faire lutilisateur, et donc dans quel ordre il devra donner ses r eponses. Enn, il appara t que le programme a deux r eponses possibles : action A : ((Lecture de la valeur dans le champ, calcul du r esultat et achage) ) ou action B : ((Fermeture des fen etres et terminaison du programme) ) Lex ecution de lune de ces deux actions est conditionn ee par l el ement de la fen etre qui a et e activ e par lutilisateur : Laction A devra etre d eclench ee si lutilisateur a cliqu e sur ( (Conversion) ), ou bien a s electionn e une monnaie dans une des deux listes d eroulantes et laction B devra etre d eclench ee si lutilisateur a cliqu e sur ( (Quitter) ). Les actions de lutilisateur sont appel ees les ev enements. Le programme doit donc r epondre aux ev enements. Une fonction qui r epond a ` un ev enement est appel ee fonction callback, et ce type de programmation (donner les actions que le programme doit faire en r eponse ` a une sollicitation de lutilisateur) est appel e programmation ev enementielle. Une biblioth` eque de cr eation dinterfaces graphiques digne de ce nom prend en charge : lachage (au niveau du pixel) des el ements, lattente quun ev enement se produise et enn lappel de la fonction callback associ ee ` a un el ement de linterface graphique lorsque celui-ci est activ e par lutilisateur. Notons au passage un inconv enient de ce type de programmation (si on ne dispose pas doutils evolu es comme les processus l egers) : la ligne temporelle correspondant au programme dans le sch ema pr ec edent est dessin ee en pointill es. Pendant ces pointill es, la machine attend simplement que lutilisateur fasse quelque chose. En revanche, lors de la r ealisation de laction A par exemple, le programme est monopolis e jusqu` a ce quelle se termine. Pendant le court laps de temps de la r ealisation de la t ache A, le programme ne sera donc pas r eactif : lutilisateur aura beau cliquer fr en etiquement, cela ne servira ` a rien. Dans le cas du convertisseur, cela na pas dimportance puisque la t ache A sex ecute tellement rapidement que la ( (non r eactivit e) ) de linterface nest pas perceptible. Si par contre, une des callbacks associ ee ` a un el ement graphique mettait plusieurs secondes, voire plusieurs minutes ` a sex ecuter, lutilisateur aurait pour sa part limpression que le programme est bloqu e : il se plaindra que linterface est ( (gel ee) ), ce qui est particuli` erement p enible. La solution que nous utiliserons pour pallier ce probl` eme dans Graphapp est lutilisation des timers, dont nous reparlerons plus loin. Enn, il faut etre conscient que dans un programme comme celui-ci, la machine ne fait rien la plupart du temps, except e attendre que lutilisateur daigne agir sur linterface. Les calculs sont extr emement rapides, et d` es quune callback est termin ee, la machine attend....
Utilisateur
Lutilisateur entre une une valeur num erique (150) Lutilisateur clique sur Cnversion
Lecteur de la valeur dans le champ dentr ee. Calcul du r esultat (en regardant le choix des monnaies). Achage du r esultat
Lecteur de la valeur dans le champ dentr ee. Calcul du r esultat (en regardant le choix des monnaies). Achage du r esultat
Le programme se termine
Utilisation de Graphapp
Une application qui utilise la biblioth` eque Graphapp poss` ede le squelette donn e dans le source 1.1. \#include<stdio.h> \#include<graphapp.h> App * app;
3.1
La cr eation dune fen etre se fait par linterm ediaire de la fonction new window : App * app; Window * win; app = new_app(argc, argv); ... win = new_window(app, rect(100,100,200,110), "Convertisseur", STANDARD_WINDOW); show_window(win); ... Le code pr ec edent cr ee une fen etre de largeur 200, de hauteur 110, et dont le coin sup erieur gauche est en position 100,100 sur l ecran. Son titre est ( (Convertisseur) ). Le soruce 1.2 d etaille la cr eation dune fen etre et lajout dun bouton dans cette fen etre. App * app; Window * win; Control * b; app = new_app(argc, argv); ... win = new_window(app, rect(100,100,200,110), "Convertisseur", STANDARD_WINDOW); b = new_button(win, rect(10,70,90,30), "Conversion", calcul); show_window(win); ... Src. 1.2: Ajout dune fen etre et dun bouton
Dans cet exemple, le bouton a son coin sup erieur gauche plac e aux coordonn ees 10,10 dans la fen etre. Il a pour largeur 90 et pour hauteur 30. Le texte inscrit dessus est ( (Conversion) ) et lorsquil sera activ e par lutilisateur, la proc edure calcul sera appel ee. Cette derni` ere devra avoir pour squelette (prototype) :
3.2
Nous allons voir comment utiliser ce que nous avons vu an de cr eer le convertisseur de monnaie. An de r ealiser le travail proprement, nous allons : cr eer une structure qui contiendra les el ements de linterface (plut ot que davoir une multitude de variables di erentes) ; d eporter la cr eation de linterface dans une fonction s epar ee. Une premi` ere portion de code, consacr ee ` a la cr eation de linterface, est donn ee dans le source 1.4. La structure nomm ee inter, de type myinterface contiendra un pointeur vers lapplication, vers la fen etre et vers chacun des contr oles (le champ de saisie, le label et les deux boutons). La fonction app main est classique et appelle la fonction creation interface qui a pour objet de cr eer les el ements graphiques. Le seul point original de cette derni` ere fonction est lutilisation des deux variables ll et hh pour obtenir le placement des objets graphiques. Cette m ethode permet de facilement modier la taille des el ements graphiques sans avoir ` a refaire la mise en page, comme indiqu e sur la gure 1.2.
typedef struct
{
App * app; Window * win; Control * bouton; Control * boutonq; Control * champs; Control * etiquette; } TInterface; // D eclaration de variables globales TInterface inter; // Fonction de cr eation de linterface void creation_interface() { int ll=90; int hh=30; inter.win=new_window(inter.app, rect(100,100,2*ll+20,3*hh+20),\ "Convertisseur",STANDARD_WINDOW); inter.champs=new_field(inter.win,rect(10,10,ll,hh),""); inter.etiquette=new_label(inter.win,rect(10,10+hh,ll,hh),\ "",ALIGN_LEFT | VALIGN_CENTER); inter.bouton=new_button(inter.win,rect(10,10+2*hh,ll,hh),"Conversion",NULL); inter.boutonq=new_button(inter.win,rect(10+ll,10+2*hh,ll,hh),"Quitter",NULL); show_window(inter.win); }
Fig. 1.2 Mise en page de linterface du convertisseur Notons aussi qu` a la place des callbacks associ ees aux boutons gure la valeur NULL, qui signie que nous nassocions pas de callback. En l etat, le programme peut etre compil e et test e. Tout y gure, mais rien ne marche encore, car nous navons pas indiqu e quoi faire en cas de lappui sur un bouton. Modions les deux lignes de cr eation des boutons en : inter.bouton=new_button(inter.win,rect(10,10+2*hh,ll,hh),\ "Conversion",calcul); inter.boutonq=new_button(inter.win,rect(10+ll,10+2*hh,ll,hh),\ "Quitter",quitter); Nous devons ` a pr esent ecrire les deux callbacks calcul et quitter (cf. source 1.5).
void quitter(Control * c)
{ ask_ok(inter.app,"Merci", "Au revoir"); hide_window(inter.win); }
void calcul(Control * c)
{
} Src. 1.5: Callbacks utilis ees par le convertisseur Le premi` ere fonction est tr` es simple, elle ache une bo te de dialogue ayant pour titre ( (Merci) ), pour contenu ( (Au revoir)) et un bouton ( (OK) ). La fonction ask ok ne se nira que lorsque lutilisateur aura cliqu e sur le bouton ( (OK) ). Puis, la fen etre principale est cach ee. Une fois la fonction quitter termin ee, la biblioth` eque Graphapp reprend etre ont disparu. Puisque cest le cas, le la main avec sa boucle main loop, qui se termine lorsque toutes les fen programme se termine. La seconde fonction est un peu plus longue : get control text(inter.champs) renvoie une cha ne de caract` eres contenant ce qui est inscrit dans un champ de saisie. atof(get control text(inter.champs)) renvoie donc un float contenant cette valeur (suppos ee num erique), et cete valeur est stock ee dans la variable valeur. Puis, la valeur est divis ee par 6.55957. La ligne : sprintf(chaine,"%08.2f",valeur) ; a pour eet d( ( ecrire) )
valeur sur 8 chires, dont 2 apr` es la virgule, dans la cha ne de caract` eres chaine. Cette cha ne est pass ee en etiquette (le label). param` etre de set control text qui lache dans l En r esum e, la fonction void calcul(Control * c) regarde la valeur dans le champ de saisie, la divise par 6.55957 et ache le r esultat dans le label. On obtient donc une conversion de francs en euros. Nous voulons ` a pr esent pouvoir changer la monnaie de d epart et la monnaie darriv ee. Pour permettre le choix des monnaies, nous allons utiliser des drop down lists (listes d eroulantes) comportant le choix des unit es. Le contenu nes de caract` eres termin ee des listes se fait en donnant en param` etre ` a la fonction new drop list une liste de cha par NULL. Par exemple : Control * dl; char * monnaie[]={"Francs","Euros","Dollars",NULL}; dl=new_drop_list(inter.win,rect(10,10,90,30),monnaie,calcul); Nous obtiendrons une liste d eroulante contenant les el ements Francs, Euros et Dollars. De plus, lorsque lutilisateur fera un choix dans cette liste, la callback calcul sera appel ee. Modions la d enition de notre interface comme indiqu e dans le source 1.6.
typedef struct
{ App * app; Window * win; Control * bouton; Control * boutonq; Control * champs; Control * etiquette; Control * liste1; Control * liste2; } TInterface; // Declaration des variables globales TInterface inter; char * monnaie[]={"Francs","Euros","Dollars",NULL};
void creation_interface()
{
} Src. 1.6: Interface du convertisseur avec listes d eroulantes ` pr A esent, notre programme peut etre compil e et test e, sauf que la s election dun el ement dans une des listes ne modiera en rien le r esultat (mais le recalculera puisque la callback calcul est appel ee). Nous devons donc pouvoir, a partir de la s ` election des monnaies, r ecup erer les taux. La fonction qui permet de conna tre l element s electionn e dune liste est get control value(inter.liste1) qui renvoie un entier contenant lindice de l el ement s electionn e
(en partant de 0). Cet indice pourra nous permettre dacc eder ` a un tableau contenant les taux, si nous modions notre programme : // Declaration des variables globales myinterface inter; char * monnaie[]={"Francs","Euros","Dollars",NULL}; float taux[]={6.55,1.0,1.2}; ` pr A esent, nous pouvons r ecup erer le taux (par rapport ` a leuro) de la monnaie s electionn ee comme monnaie de d epart, en indiquant : taux[get_control_value(inter.liste1)] La conversion de la monnaie de d epart vers la monnaie darriv ee se fait en : divisant la valeur entr ee par le taux de la monnaie de d epart ; puis en multipliant le r esultat par le taux de la monnaie darriv ee. Nous navons donc plus qu` a modier en cons equence notre fonction calcul (cf. source 1.7)
void calcul(Control * c)
{
La source dinformation la plus compl` ete sur la biblioth` eque Graphapp reste sa documentation, ainsi que les nombreux exemples fournis avec. Vous etes encourag es ` a consulter cette documentation le plus souvent possible. Nous allons n eanmoins ici faire un rapide tour dhorizon des possibilit es.
4.1
Objets simples
Parmi les objets ( ( el ementaires) ) g er es par Graphapp, on trouve les Points, les Rectangles, les Couleurs, les Images et les Curseurs. 4.1.1 Points
Un objet de type Point est une structure regroupant deux entiers x et y. Ce type de donn ees permet de repr esenter un point ` a l ecran. Rappelons ` a cet eet que le syst` eme de coordonn es ( (informatique) ) place lorigine dans le coin sup erieur gauche des objets, et laxe des ordonn ees vers le bas. Enn, en r` egle g en erale, les coordonn ees sont relatives ` a lobjet que lon d esigne : on parle de coordonn ees ` a l ecran pour une fen etre, de coordonn ees dans la fen etre pour un el ement graphique qui lui appartient, et de coordonn ees dans un el ement graphique pour un point dessin e sur cet el ement. Voici un exemple de code qui utilise des variables de type Point : Point p,p1; p=pt(5,8); p1.x=5; p1.y=p.y+10;
10 4.1.2 Rectangles
Un objet de type Rectangle est une structure regroupant 4 entiers : x, y, width et height, repr esentant respectivement les coordonn ees du coin sup erieur gauche dun rectangle, sa largeur et sa hauteur. De tels rectangles ont leurs ar etes parall` eles aux c ot es de l ecran. De nombreuses manipulations sont possibles sur les rectangles, comme tester leur egalit e, tester sils ont une intersection, si un rectangle est inclus dans un autre, ... Voici un exemple de code qui manipule des variables de type Rectangle : Rectangle r,r1; Point p; r=rect(10,10,100,50); r1=rect(20,20,40,10)); p=pt(12,12); // Teste si r1 est inclus dans r if (rect_in_rect(r1,r)) { ... } // Teste si le point est inclus dans r1 if (point_in_rect(p,r1)) { ... }
4.1.3
Couleurs
Les couleurs dans Graphapp sont d enies par leurs trois composante rouge, vert, bleu (comme cest lhabitude), ainsi que par leur composante alpha (cest le niveau de transparence). Une composante alpha ` a 0 correspond ` a une couleur compl` etement opaque, alors quune composante alpha ` a 255 correspond ` a une couleur compl` etement transparente. Une couleur est donc une structure comprenant quatre champs de type byte (ce type est aussi d eni par Graphapp et correspond ` a des entiers positifs compris entre 0 et 255) : alpha, red, green et blue. Notons cependant que la transparence, bien que support ee par le type de donn ees, nest pas implant ee dans la biblioth` eque. Nous nous contenterons donc de couleurs opaques : Colour c,c1; c=rgb(255,0,0); // Rouge c1=rgb(255,255,0); // Jaune
4.1.4
Images, curseurs
Nous ne d etaillerons pas ici le fonctionnement des images et des curseurs. Sachez n eanmoins quil est possible de copier une partie de l ecran vers une image, de d eposer une image sur une partie de l ecran, de cr eer une image ` a partir dun chier etc. Les objets relatifs ` a ces manipulations sont : Image, ImageList, ImageReader ou Bitmap. En ce qui concerne les curseurs, la structure ` a utiliser se nomme Cursor et Graphapp contient bon nombre de curseurs pr ed enis, comme lhabituelle ` eche, le curseur de texte, la croix, la main, ...
4.2
Nous avons d ej` a vu dans la section pr ec edente comment ouvrir une fen etre et ajouter boutons, labels, champs de saisie et listes d eroulantes dedans. Nous allons rapidement faire un tour dhorizon des autres possibilit es en nous attardant un peu sur le type Window. 4.2.1 Fen etre
Le type de donn ees se nomme Window. Nous pouvons entre autres cacher (hide window), acher (show window), d eplacer (move window) et retailler (size window) une fen etre.
11
Les ev enements associ es ` a une fen etre sont la fermeture (lutilisateur a cliqu e sur la croix), la modication de sa taille, ou la n ecessit e de la redessiner (par exemple parce quelle etait masqu ee par une autre fen etre et vient d etre a nouveau d ` ecouverte). Il est aussi possible de r epondre ` a la pression dune touche, et aux actions de la souris. La m ethode g en erale, pour enregistrer les callbacks, est de faire appel ` a une fonction pr ecise correspondant au type d ev enement souhait e, et ` a lui donner le nom de la fonction qui traitera ces ev enements. Si nous souhaitons par exemple tracer un point dans la fen etre lorsque lutilisateur clique, nous devons : 1. ouvrir une fen etre ; 2. indiquer le nom de la proc edure qui traitera l ev enement ( (clic souris) ); 3. ecrire cette proc edure. etre un pointeur Le point 2 correspond ` a un appel ` a la fonction on window mouse down en lui donnant en param` vers la fen etre (de type Window *) et un pointeur vers la fonction callback (de type WindowMouseFunc). Ce dernier type de donn ees est d eni dans Graphapp ainsi (voir documentation) :
Graphapp comprend de nombreux autres el ements graphiques. La gure 1.3 les repr esente presque tous, an que chacun puisse se faire une id ee de ce qui est possible. Le programme permettant dacher ces el ements graphiques se nomme alldemo.exe et se trouve sur vos machines.
4.3
La biblioth` eque Graphapp poss` ede quelques fonctions de dessin permettant de r ealiser des petits programmes de visualisation. Tout trac e se fait dans un objet de type Graphics *. On peut obtenir un tel objet ` a partir dun Control, par exemple, ou dune Image (nous reparlerons du type Image plus tard). Un contexte dachage est obtenu comme indiqu e dans le source 1.9. En possession dun objet de type Graphics *, nous pouvons : choisir une couleur : set rgb(Graphics *g, Colour col) ; tracer un point : int draw point(Graphics *g, Point p) ; tracer une ligne : int draw line(Graphics *g, Point p1, Point p2) ;
12
/* ============================================================== Fichier clic.c Indique dans un terminal les coordonn ees du point cliqu e ================================================================= */
char buf[500];
sprintf(buf,"Coordonn ees %d %d (%d)\n",xy.x,xy.y,buttons); ask_ok(inter.app,"Clic",buf);
} {
void creation_interface()
inter.win=new_window(inter.app, rect(100,100,200,200),\ "Dessin",STANDARD_WINDOW); on_window_mouse_down(inter.win,affiche_coord); show_window(inter.win); }
1. Cr eation dinterfaces graphiques Graphics *g; Control *c; ... g=get_control_graphics(c); .... del_graphics(g); Src. 1.9: Obtenir et rendre un contexte dachage avec Graphapp ...
13
Le contexte dachage doit etre lib er e par : del graphics(Graphics *g) ; Lextrait de programme donn e dans le source 1.10 cr ee un contr ole, obtient un contexte graphique, trace 10 lignes de couleurs al eatoires et de positions al eatoires puis rend le contexte dachage. Control *c; Graphics *g; Window *w; int i; c=new_control(w,rect(0,0,100,100)); g=get_control_graphics(c); for (i=0;i<10;i++) { set_rgb(g,rgb(rand()%256,rand()%256,rand()%256)); draw_line(g,pt(rand()%100,rand()%100),pt(rand()%100,rand()%100)); } del_graphics(g); Src. 1.10: Tracer des lignes dans un Control Lorsque le contr ole est cach e (par une autre fen etre par exemple) puis ` a nouveau d ecouvert, le syst` eme de fen etrage doit le retracer. Cette t ache incombe ` a Graphapp (cest lui qui redessine ses contr oles). Si la biblioth` eque sait retracer des boutons, des barres de d element... elle ne sait pas retracer un objet contenant des dessins quelconques. Cest donc au programmeur de donner une fonction qui retracera le contenu du contr ole. Cette fonction est indiqu ee par : on control redraw(Control *c, DrawFunc redraw). La fonction redraw doit donc etre ecrite par le programmeur :
14
Graphics *g; g=get_control_graphics(c); draw_image(g,rect(0,0,c->area.width,c->area.height),img,get_image_area(img)); del_graphics(g); } Pour terminer, notons quil existe une assez grande vari et e de fonctions graphiques, permettant de dessiner des rectangles, des rectangles remplis, des lignes, des ellipses, des arcs de cercle, des lignes bris ees ou du texte (consulter la documentation)...
4.4
Timers
Un timer permet de faire ex ecuter une certaine fonction ` a intervalles r ep et es. D` es que notre programme contient une t ache ` a ex ecuter un peu longue, qui ne doit pas bloquer linterface utilisateur, nous devons utiliser des timers. La d enition dun timer se fait ainsi : Timer *t; App * app; ... t=new_timer(app,fonc_timer,100); La fonction new timer cr ee un nouveau timer, qui appellera automatiquement la fonction fonc timer toutes les 100 millisecondes. La fonction fonc timer doit avoir pour squelette :
Nous voudrions que le programme fonctionne comme indiqu e sur la gure 1.4. Or ce nest pas possible, car le programme ne peut pas g erer en m eme temps linterface graphique et le spot. La solution consiste ` a appliquer le principe de la gure 1.5. Le programme utilise alors son temps dattente (les pointill es) pour de temps ` a autre ex ecuter une fonction qui fera l eg` erement bouger le spot. La fonction fonc timer ressemblera donc ` a celle don e dans le source 1.11.
1. Cr eation dinterfaces graphiques Spot ` a l ecran Le spot se d eplace continuellement ` a l ecran en utilisant la valeur de la fr equence cournate Programme Cr ation et achage des el ements graphiques de la fen etre Utilisateur
15
Le programme se termine
void fonc_timer(Timer * t)
{
int valx,valy;
Graphics *g; valy=sin(temps)*100+150; valx=temps/6.28*300; g=get_control_graphics(inter.c); set_rgb(g,rgb(0,0,0)); fill_rect(g,rect(0,0,300,300)); set_rgb(g,rgb(30,255,50)); fill_ellipse(g,rect(valx-2,valy-2,4,4)); del_graphics(g); temps=temps+deltat; if (temps>6.28) temps=temps-6.28;
} Src. 1.11: Utilisation dun timer avec Graphapp (premi` ere partie)
16
Programme Cr ation et achage des el ements graphiques de la fen etre D eplacer le spot D eplacer le spot
Utilisateur
Lutilisateur clique sur V++ Lintervalle Dt est divis e par 1.2 D eplacer le spot D eplacer le spot D eplacer le spot Lutilisateur clique sur quitter Le programme se termine
17
Cette fonction est assez simple ` a comprendre. Elle utilise deux variables globales temps et deltat repr esentant respectivement le temps et laugmentation de largument de la fonction sinus ` a chaque appel de fonc timer. Par cons equent, il sut daugmenter deltat pour avoir limpression que le point se d eplace plus vite, et inversement. Le reste du programme est donn e dans le source 1.12.
4.5
4.5.1
Bo tes de dialogues
Bo tes standard
Graphapp contient quelques bo tes de dialogues pr ed enies, pour faciliter le travail du programmeur. Ces bo tes eponse armative ou n egative (ask yes no), de permettent dacher un message (ask ok), de demander une r demander une cha ne de caract` eres (ask string), ou de s electionner un chier (ask file open et ask file save). Deux de ces bo tes sont repr esent ees dans la gure 1.6.
4.5.2
Console de debuggage
Lutilisation de Graphapp sous Windows ne permet pas de disposer de la fonction printf qui permet dans bien des cas de trouver des erreurs dans les programmes en achant les valeurs de variables ou des messages indicatifs. Ce probl` eme peut etre contourn e en utilisant la console de debuggage2 . La fonction open debug(inter.app) ouvre la console de debuggage. On dispose alors dune fonction nomm ee ` la n dun debugprintf, qui fonctionne exactement comme printf mais ache dans la fen etre de debuggage. A programme, il faut refermer la fen etre de debuggage ainsi : ... main_loop(inter.app); close_debug(); del_app(inter.app);
Graphapp et Dev-C++
Pour compiler un programme utilisant Graphapp avec Dev-C++, il faut disposer des chiers den-t ete app.h, debug window.h et graphapp.h, ainsi que de la version statique de la biblioth` eque libgraphapp.a Si les chiers ne sont pas ` a lemplacement standard (par exemple les r epertoires c :/Dev-Cpp/include et c :/Dev-Cpp/lib) le param etrage de Dev-C++ doit etre fait comme indiqu e dans les bo tes 1 et 2 de lannexe. Dans la bo te 3 de la m eme annexe, la ligne -lgraphapp doit gurer dans la partie Editeur de liens.
2 La
console de debuggage ne gure pas dans le manuel, car elle a et e d evelopp ee localement.
18
typedef struct
{ App * app; Window * win; Control *c; // Zone de trac e Control * pp; // Bouton ++ Control * pm; // Bouton -} Tinterface; TInterface inter; // Les deux variables globales float temps; float deltat; // Callback appel ee lors de lappui sur un des deux boutons // Notez comment sy prendre pour regarder lequel des deux boutons a // provoqu e l ev` enement void deltat_cb(Control * c) { if (c==inter.pp) deltat*=1.2; else deltat/=1.2; }
void creation_interface()
{ inter.win=new_window(inter.app, rect(100,100,300,330),\ "Oscillo",STANDARD_WINDOW); inter.c=new_control(inter.win,rect(0,0,300,300)); inter.pp=new_button(inter.win,rect(0,302,150,25),"V++",deltat_cb); inter.pm=new_button(inter.win,rect(150,302,150,25),"V--",deltat_cb); show_window(inter.win); }