|
|||||||||||||||||||||||||||||||||||||||||||||||||
|
La création de menus déroulants sur Amiga s'effectue, comme bien d'autres choses d'ailleurs, avec l'aide de l'interface logicielle Intuition. Celle-ci permet l'affichage des menus et la gestion des interactions entre l'utilisateur et le programme via ce menu. La première partie de cet article va donc consister en une description des menus : comment les créer et comment les gérer. Un programme d'exemple constituant la seconde partie mettra en pratique toute cette théorie. Dernier point avant que de commencer : les termes anglais entre parenthèses dissiminés tout au long de cet article, sont les termes "officiels" que vous trouverez dans la documentation développeur de Commodore, ceci afin de permettre à ceux qui la possèdent, de s'y retrouver plus facilement. Définition et accès Pour activer un menu Intuition, l'utilisateur doit appuyer sur le bouton droit de la souris. Intuition affiche alors la barre de menus (menu strip) liée à la fenêtre active, en haut de l'écran. Elle est composée d'un certain nombre de mots, baptisés "intitulés" ou "titres" des menus. Quand l'utilisateur positionne le pointeur de la souris sur un menu, il le sélectionne : le titre du menu apparaît alors en surbrillance et une boîte contenant les différentes options qu'il propose (menu items) apparaît juste en dessous. La largeur de cette boîte est indépendante de celle du titre du menu. Sa hauteur dépend quant à elle du nombre d'options dans le menu et de leur hauteur. Lorsque l'utilisateur sélectionne une option (toujours à l'aide du pointeur de la souris), celle-ci apparaît à son tour en surbrillance. La confirmation de la sélection se fait tout simplement en relâchant le bouton droit de la souris, l'option choisie étant toujours en surbrillance. Une option de menu peut faire apparaître un sous-menu (sub-menu) présentant lui-même d'autres options. Hiérarchie La description ci-dessus, bien qu'un peu fastidieuse, nous permet d'appréhender la hiérarchie au sein des menus. En effet, on voit que l'on peut lier X menus à une fenêtre, chacun pouvant contenir Y options, pouvant elles-mêmes contenir Z sous-options. Chaque entité de même niveau est liée à la suivante par une liste chaînée simple. Initialisation Lorsque l'on veut gérer des menus, il faut d'abord les penser. On dessine sur papier la structure des menus, comprenant toutes les entités associées en partant des sous-options, puis les options, et en finissant par les menus. A noter que divers utilitaires du domaine public ou du commerce permettent de simplifier cette tâche. Leur principale caractéristique est de produire un code source C ou assembleur que le programmeur n'aura plus qu'à inclure dans son projet. Le plus célèbre est PowerWindows d'Innovatronics. Structure d'un menu Comme toujours dans l'Amiga, un menu (comprenez "un titre de menu") est défini par une structure C, que voici : ![]() NextMenu : pointeur sur le menu suivant dans la liste. Lorsqu'il s'agit du dernier menu de la barre, NextMenu doit être initialisé à NULL. LeftEdge, TopEdge, Width, Height : taille de la boîte de sélection du menu. LeftEdge représente la position de la boîte relativement à celle de l'écran. Width représente sa largeur. TopEdge et Height ne servent pas dans la version actuelle d'Intuition, plus tard peut-être (pour le moment on les met à 0 et on en parle plus). Flags : peuvent être fixé par le programme et par Intuition. Ce sont :
Firstftem : pointeur sur la première option du menu qui est une structure MenuItem. Structure d'une option La structure C associée aux fonctions et sous-fonctions est la même, mais elle ne s'utilise pas de la même manière. Cette structure est la suivante. ![]() LeftEdge, TopEdge, Width, Height : taille et position de la boîte de sélection de l'option (zone dans laquelle l'option est sélectionnée par le pointeur de souris). LeftEdge et TopEdge représentent la position relative du coin haut-gauche de la boîte par rapport à la position du coin haut-gauche de celle du menu. Width et Height représentent respectivement la largeur et la hauteur de la boîte. Flags : positionnée par le programme ou par Intuition. Ce sont :
Le champ MutualExclusion est un mot long (type LONG sur 32 bits) où chaque bit représente une option dans la liste correspondant a un menu. Le premier dans la liste a le bit 0, le second le bit 1, etc. Ce qui signifie dans un premier temps que seules 32 options appartenant à un même menu peuvent utiliser ce champ (ce qui n'est déjà pas si mal !). Lorsque le énième bit du champ MutualExclude de l'option X est positionné, l'option N est automatiquement exclue lorsque l'option X est sélectionnée. Dans notre exemple, on va mettre $fff6 pour tonneau (on exclut tous les autres sauf la fiole et lui). Pour le bidon et la bouteille, on met $0001 car on exclut le tonneau seulement. Pour la fiole on mettra $0000 car on n'exclut rien du tout. ItemFill : pointeur sur l'intitulé de la fonction, en l'occurrence une structure IntuiText si le drapeau ITEMTEXT est positionné, sinon c'est une structure Image. SelectFill : si le drapeau HIGHIMAGE est positionné, Intuition substituera à la structure contenue dans ItemFill celle contenue dans SelectFill lorsque l'option sera sélectionnée. SelectFill est donc un pointeur sur une structure IntuiText ou Image, selon la présence ou non du drapeau ITEMTEXT. Note : on ne peut pas afficher une image à la place d'un texte, et vice-versa. Command : code ASCII du caractère composant le raccourci clavier lorsque le drapeau COMMSEQ est positionné. L'utilisateur peut choisir directement l'option en appuyant simultanément sur la touche Amiga droite et sur le caractère contenu dans ce champ. Au niveau programme proprement dit, tout se passe comme si la fonction avait été sélectionnée à la souris. Note : aucune vérification n'est faite pour voir si une même commande est utilisée plusieurs fois dans un menu. De plus, Intuition ne fait pas la différence entre les majuscules et minuscules ; s'il en a besoin, le programme doit tester lui-même si une touche Shift (ou verrouillage nulérique) est enfoncée au moyen du champ Qualifier de la structure IntuiMessage (Cf. plus loin). SubItem : pointeur sur la première sous-option de cette option. Ce champ est ignoré si l'option courante fait déjà partie d'un sous-menu. NextSelect : dernier champ de la structure, mais il est loin d'être le moins important. En effet, si l'utilisateur a la possibilité de sélectionner plusieurs options dans un menu en une seule opération (en cliquant avec le bouton de gauche de la souris les différentes options, tout en maintenant le bouton droit de la souris appuyé), rien dans l'IntuiMessage n'indique au programme que c'est bel et bien ce qui s'est passé. Pour garder une trace de cette sélection multiple et donc permettre de traiter toutes les options choisies, Intuition remplit le champ NextSelect avec le numéro de l'option suivante. Bon allez, je suis compréhensif et vous livre un petit bout de source qui illustre la manière de s'y prendre. ![]() On a donc décrit la structure de son petit menu, en suivant les explications ci-dessus et en s'imprégnant de l'exemple ci-dessous (le va-et-vient est terminé, on continue). Première opération à réaliser, ouvrir une fenêtre à l'aide de la fonction OpenWindow(). En effet, pour attacher un menu à une fenêtre, il semble raisonnable d'ouvrir une fenêtre (si, si, j'vous jure !). Comme déjà dit plus haut, le champ CheckMark de la structure NewWindow peut pointer sur une structure Image décrivant une coche personnelle à utiliser pour toutes les options du menu ayant les drapeau CHECKIT et CHECKED positionnés. Ensuite, on attache le menu à la fenêtre, à l'aide de la fonction SetMenuStrip().
"fenêtre" est un pointeur sur une structure Window créée par OpenWindow(). Il s'agit de la fenêtre à laquelle on veut attacher le menu. "menu" est un pointeur sur le premier menu de la liste chaînée des menus à afficher. Bien entendu, il ne se passe rien de particulier lorsque l'utilisateur sélectionne une option du menu. C'est au programme de réagir en conséquence. Il faut donc écrire un petit bout de code pour savoir ce que l'utilisateur a sélectionné et quelle fonction activer. Pour ce faire, on va encore se faire aider par Intuition. A chaque fois que l'utilisateur active le système de gestion de menus en pressant le bouton droit de la souris, Intuition génère un message (sous la forme d'une structure IntuiMessage) de classe MENUPICK. Vous pouvez donc tester les messages que vous envoie Intuition pour savoir si oui ou non il s'agit de l'activation d'un menu. Voici le résultat en quelques lignes. ![]()
Si l'on active la fonction 2 du menu 4 on a :
On notera qu'Intuition envoie systématiquement un message MENUPICK lorsque l'utilisateur a enfoncé le bouton droit de la souris, et ce même si aucune sélection n'a été effectuée. D'où l'utilité de vérifier que le champ Code soit différent de MENUNULL. Le programme d'exemple fournit une fonction testmenu() qui utilise ce principe. Il ne nous reste plus qu'à étudier quelques fonctions qui permettent de travailler dynamiquement sur les menus et nous aurons fait le tour de cet outil si pratique. Fonctions utiles Nous avons entrevu la possibilité qui nous était donnée d'interdire ou d'autoriser l'accès à un menu, une option ou une sous-option en plein milieu de l'exécution du programme. L'interdiction est réalisée à l'aide de la fonction OffMenu()
"fenetre" est un pointeur sur la fenêtre à laquelle est lié le menu. "numero" correspond au numéro de la fonction ou du menu à interdire (sous une forme équivalente au champ Code de la structure IntuiMessage de type MENUPICK que renvoie Intuition quand une fonction a été sélectionnée). On le calcule avec la formule :
C'est tout simple et en plus ça fonctionne très bien. Pour autoriser un menu à nouveau on utilise OnMenu() :
Enfin, la dernière fonction :
...calcule l'adresse d'une option ou sous-option à partir de l'adresse du premier menu et du numéro associé au menu à la fonction ou la sous-fonction à autoriser. Enfin, lorsque l'on n'a plus besoin du menu, on l'élimine de la fenêtre grâce à la fonction :
"fenetre" étant le pointeur sur la fenêtre à laquelle est lié le menu. Conclusion Il ne vous reste plus qu'à étudier le programme fourni comme exemple et qui se trouve bien entendu sur la disquette d'accompagnement de ce numéro. Il a été compilé sans problème avec Lattice 5.10 et Aztec 5.0d. ![]() ![]()
|