mercredi 27 juin 2018

Chapitre 37 : gestion des menus avec X11


Ca y est, j’ai trouvé comment centrer les fenêtres principales que nous créons depuis le raspberry en assembleur, sur l’écran du PC. En effet j’avais fait une erreur dans la lecture du tutoriel xlibbook, car je pensais que les paramètres USPosition et USSize concernait des particularités pour les Etats-Unis. En fait US signifie user (utilisateur) et le passage de ces paramètres au gestionnaire d’écran permet le centrage de la fenêtre . Pour cela nous utilisons la fonction XSetWMNormalHints que nous appelons après la création de la fenêtre et avant son affichage. Cela ne change pas grand-chose par rapport à l’appel de XMoveWindow car le résultat sera le même.
Dans ce nouveau programme, nous allons voir la création de menus  qui sont des fenêtres et même qui sont pratiquement identiques à des boutons !!! Donc nous retrouvons, la routine de connexion au serveur X11, la création de la fenêtre principale dans laquelle nous avons corrigé le problème du centrage, le chargement des polices utilisées, la création des contextes graphiques, la création d’une fenêtre d’affichage des messages et son bouton OK. J’ai corrigé une erreur que j’avais faite dans le programme précédent sur le centrage du libellé du bouton. En effet j’avais calculé l’écart entre la taille du bouton en pixel et la taille du libellé en caractères, ce qui est faux. Il faut calculer la taille du texte en pixel et cette taille est fonction de la police utilisée. Il faut appeler la fonction XTextWidth pour la longueur et XTextExtents pour la hauteur. 
Remarque : le chargement des polices de caractères alimente une structure de données. Pour certaines fonctions X11, il faut passer le pointeur sur cette structure, pour d'autres, il faut passer l'identification de la police qui se trouve au déplacement +4 de la structure.
Ensuite nous créons les menus principaux au dessus d’une ligne de séparation puis les sous menus des menus Fichier et Fonction. Les sous menus se distinguent des menus et boutons par le fait qu’ils ne sont pas affichés à la création de la fenêtre mais lors de l’appui sur le menu principal. Vous remarquez que les routines de création se ressemblent toutes et donc qu’il est possible de regrouper tout cela dans les mêmes routines. Je me rends compte aussi que d’avoir créée une structure appelée bouton n’était pas une bonne idée !! Il valait mieux partir de la structure X11 Windows et ajouter les quelques données dont nous avons besoin pour les boutons ou les menus.
Maintenant la partie intéressante !! : la gestion des évènements de toutes ces fenêtres. Pour la fenêtre principale nous retrouvons les évènements de fermeture et d’affichage déjà vus. Nous ajoutons des routines de masquage des sous menus lorsque la souris repasse dans la fenêtre principale.
Ensuite pour chaque menu principal, nous trouvons les routines pour changer la bordure du menu lorsque la souris entre ou sort du menu. Et nous trouvons l’action à entreprendre à chaque clic sur le menu.
Pour le menu Aide, nous nous contentons d’afficher la fenêtre de messages avec un texte d’aide. Hélas, je me suis rendu compte que l’on ne pouvait pas utiliser le retour ligne pour afficher plusieurs lignes de texte. Je vous laisse le soin de trouver une amélioration pour afficher une ou plusieurs lignes dans cette fenêtre.
Pour le clic sur le menu Fonction, nous affichons 2 sous menus qui vont permettre de modifier le code fonction associé à un Contexte graphique. En effet, si nous dessinons sur les mêmes pixels avec le même contexte graphique, il est possible de choisir comme va être le pixel résultat et donc obtenir des effets surprenants au niveau des couleurs des dessins. Ici je n’ai crée que 2 sous menus pour la fonction and et xor et je vous laisse le soin de créer les autres sous menus de toutes les fonctions. J’ai mis au début du programme les constantes de chaque fonction.
Pour le clic sur le menu Fichier, nous affichons 3 sous menus, un pour quitter le programme, un pour dessiner un cercle de couleur verte et un pour dessiner un polygone de couleur bleue. Les 2 dessins se recouvrent partiellement pour voir les résultats des modifications des fonctions du Contexte graphique. Attention, il y a quelques petites astuces pour les dessins : pour le cercle les angles sont comptés en 64 iéme de degré et donc il faut mettre la valeur 64 * 360 pour avoir un cercle complet. Pour les polygones, il faut déclarer les sommets par des coordonnées en 16 bits (directive .hword). Vous remarquerez que dans chaque routine, nous changeons de couleur du dessin par la fonction XSetForeground ce qui est bien commode.
Lors de l’exécution, le passage de la souris sur les menus s’effectuent correctement avec une légère difficulté si la souris passe sur la fenêtre principale avant d’accéder à un sous menu : les sous menus disparaissent !! Peut être il est préférable de les fermer lorsque la souris passe sur un autre menu principal. Les libellés des menus s’effacent aussi dans le cas de recouvrement des fenêtres, il faudrait donc gérer l’évenement Expose pour chaque menu.
Comme les autres programmes, celui-ci peut être grandement amélioré !!! A vous de jouer !!
Voici le résultat sans avoir choisi de fonction and ou xor :

Aucun commentaire:

Enregistrer un commentaire