Obligement - L'Amiga au maximum

Mardi 19 juin 2018 - 12:43  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : Assembleur - Structure gadget (suite)
(Article écrit par Max et extrait d'Amiga News Tech - septembre 1989)


L'inspecteur Gadget (suite)

Reprenons notre étude de la structure Gadget là où nous l'avions laissée, c'est-à-dire juste après les "Activation Flags". On trouve à leur suite un mot qui détermine le type du gadget :

Valeur Nom Signification
1 BOOLGADGET Gadget booléen
3 PROPGADGET Gadget proportionnel
4 STRGADGET Gadget de chaîne ou numérique
$10 SIZING Gadget de modification de taille de fenêtre
$20 WDRAGGING Gadget de déplacement de fenêtre
$30 SDRAGGING Gadget de déplacement de l'écran
$40 WUPFRONT Gadget de "dépilement" de fenêtre
$50 SUPFRONT Gadget de "dépilement" d'écran
$60 WDOWNBACK Gadget "d'empilement" de fenêtre
$70 SDOWNBACK Gadget de "d'empilement" d'écran
$80 WCLOSE Gadget de fermeture de fenêtre
$1000 REQGADGET Gadget pour requête
$2000 GZZGADGET Gadget de bord dans une fenêtre GIMMEZEROZERO
$4000 SCRGADGET Gadget d'écran
$8000 SYSGADGET Gadget système

On n'utilisera en général que l'un des trois premiers types possibles (BOOL, PROP ou STR). Sachez toutefois que l'expression "gadget système" regroupe tous les gadgets "standards" de fenêtre et d'écran listés dans ce tableau. Viennent ensuite dans la structure plusieurs pointeurs.

Le premier désigne l'adresse d'une structure Image, au cas où votre gadget en contiendrait une (une Image n'est rien d'autre qu'un motif défini par vous, qu'Intuition dessinera dans votre gadget. Voir plus loin dans cette même rubrique).

Le second désigne l'adresse d'une seconde structure Image, qui sera affichée à la place de la première lorsque le gadget sera sélectionné, ce qui permet des effets intéressants, comme par exemple un interrupteur ON/OFF, etc. Ceci n'est bien sûr valable que si le bit "GADHIMAGE" est mis dans les Gadgets Flags (Cf. mois dernier).

Le troisième pointeur désigne l'adresse d'une structure IntuiText, au cas où nous voudrions afficher un texte quelconque dans notre gadget (pour le détail d'une structure IntuiText, voir cet article). On trouve ensuite un mot long nommé "Exclude" qui indique si l'activation de notre gadget doit provoquer la désactivation d'autres gadgets présents. On assure de source normalement bien informée, que cette fonction n'est pas d'une fiabilité exemplaire, qu'elle provoquerait un Guru de temps en temps... Voilà une affirmation que je n'ai pas encore eu la chance, si l'on peut appeler ça de la chance, de vérifier.

On continue la structure Gadget avec un pointeur sur une structure SpecialInfo, qui ne sera utilisée qu'avec les gadgets de chaîne, entiers et proportionnels. Nous y reviendrons en temps et en heure, c'est-à-dire dans quelques paragraphes.

Il ne nous reste plus qu'à donner un numéro d'identification (ID) à notre gadget, et la structure sera complète, le dernier mot long, "User Data", étant géré de manière interne par Intuition.

La structure Gadget telle que je viens de la décrire est valable pour un gadget de type booléen. Il faudra lui faire subir quelques modifications, heureusement mineures, pour un gadget de chaîne ou proportionnel.

Travail à la chaine

Qu'est-ce donc qu'un gadget dit "de chaîne" ? L'exemple évitant toujours de longues et ennuyeuses explications, en voici un : la fonction "Rename" du Workbench utilise un gadget de chaîne pour recevoir le nouveau nom de l'objet concerné. Il s'agit en gros d'un moyen simple et élégant d'attendre une entrée au clavier de la part de l'utilisateur. D'autant plus que de tels gadgets disposent de plusieurs facilités d'édition :
  • Flèches gauche/droite : déplacent le curseur d'un caractère respectivement vers la gauche ou la droite.
  • Flèches gauche/droite avec Shift : déplacent le curseur respectivement en début et en fin de chaîne.
  • Del (Suppression) : efface le caractère situé sous le curseur.
  • BackSpace (Effacement) : efface le caractère situé à gauche du curseur.
  • Return (Entrée) : met fin à l'édition du texte.
  • Amiga droite/A : fonction "Undo" (rétablit le texte initial).
  • Amiga droite/X : efface complètement le texte.
Pour mettre en oeuvre un gadget de chaîne, il suffit de définir une structure Gadget comme ci-dessus, en prenant soin d'initialiser le mot long SpecialInfo avec l'adresse d'une structure StringInfo (à ne pas confondre avec la structure IntuiText ! Une telle structure StringInfo est définie comme suit :

Offset Signification
0 Text Buffer
4 Undo Buffer
8 Start Cursor
10 Maximum Length
12 First Char
14 *
16 *
18 *
20 *
22 * = ces cinq mots sont définis par Intuition
24 RastPort
28 Integrer
32 Keymap

Examinons tout ça de plus près... Le premier mot long pointe sur un tampon mémoire suffisamment grand pour recevoir le texte entré. Le second mot long pointe sur un tampon mémoire "Undo", qui servira lors de l'appui sur les touches Amiga droite/A.

Le mot "Start Cursor" détermine la position du curseur dans la chaîne à l'ouverture du gadget ; il vaut mieux le fixer à 0 pour qu'il pointe sur le premier caractère ! Le mot "Maximum Length" détermine le nombre maximum de caractères que le texte pourra contenir.

"First Char" indique à partir de quel caractère du texte celui-ci doit être édité. Il vaut mieux également le mettre à 0, afin que ce soit à partir du premier caractère. Les cinq mots suivants seront utilisés par Intuition durant l'édition du texte. On y trouvera à la sortie divers renseignements, tel le nombre de caractères effectivement entrés, etc.

"RastPort", maintenant familier, n'a pas à être initialisé par nous ; pour une fois, Intuition s'en chargera tout seul, comme un grand. "Integer" contiendra, en fin d'édition, la valeur entrée dans un gadget de type entier. Enfin, "Keymap" pointe sur une table de définition de clavier présente en mémoire, qui sera utilisée lors de l'édition du texte. Tout ceci à condition bien entendu que vous ayez fixé le bit "ALTKEYMAP" dans les Gadget Flags (encore une fois, Cf. mois dernier).

Les gadgets entiers ne sont, finalement, qu'une variante des gadgets de chaîne, qui ne permettent que l'édition de chiffres (0 à 9). La valeur entrée au clavier sera automatiquement convertie par Intuition en un mot long et placée au label "Integer". C'est tout.

De la proportion

C'est ici que les choses se compliquent un peu. Le booléen, ça va, les chaînes aussi, mais les gadgets proportionnels, c'est autre chose, ça, ma bonne dame. Je vous conseille donc de vous asseoir confortablement avant de continuer à lire. Des gadgets proportionnels, vous en utilisez plus souvent que vous ne le croyez : les ascenseurs dans les fenêtres en sont, pour ne citer qu'eux. Il s'agit donc de gadgets qui donnent la possibilité de déplacer un curseur dans un cadre donné. Les tailles du curseur et du cadre sont bien entendu totalement définissables.

Pour programmer de tels gadgets, il nous faut évidemment une structure Gadget, identique à celle déjà vue. Le mot "Gadget Type" devra être fixé sur 3 (Proportional Gadget), le pointeur "Image" désignera la structure Image définissant le curseur, et le pointeur "Special Info" désignera l'adresse d'une structure Propinfo, structure que voici, sans plus attendre, détaillée pour vous :

Offset Signification
0 PropFlags
2 Hpos
4 Vpos
6 HorizBody
8 VertBody
10 à 20 Six mots utilisés par Intuition

Seuls les quatre premiers bits du mot "PropFlags" sont significatifs :

Bit Valeur Signification
0 1 AUTOKNOB
1 2 FREEHORIZ
2 4 FREEVERT
3 8 PROPBORDERLESS

Une fois n'est pas coutume, commençons par la fin : normalement, lorsqu'un gadget de type proportionnel est mis en oeuvre, Intuition encadre automatiquement le curseur (comme il le fait pour un titre de menu, par exemple). Fixer le bit PROPBORDERLESS permet d'éviter cet encadrement. FREEVERT et FREEHORIZ autorisent, s'ils sont fixés, le déplacement vertical et horizontal (respectivement) du curseur à l'intérieur de son cadre. Au moins l'un de ces deux bits doit être mis !

AUTOKNOB est d'un grand secours pour la mise au point de programmes, en attendant la version finale, plus esthétique. Ce bit fait en sorte qu'Intuition gère de lui-même la forme et la taille du curseur, proportionnellement au cadre qui le contient. Très pratique.

Revenons à la structure PropInfo. Hpos et Vpos contiennent les positions de départ du curseur, relativement aux bords du cadre qui le contient. Des valeurs comprises entre $0 (gauche/haut) à $FFFF (bas/droite) sont autorisées.

HorizBody et VertBody déterminent le pas de déplacement du curseur dans son cadre. Prenons pour exemple un gadget permettant de régler l'intensité d'un son. Le programme autorise des valeurs entières comprises entre 0 et 63, soit 64 valeurs différentes possibles. Dans ce gadget, si Hpos (ou Vpos, ne soyons pas sectaires) est égal à 0, le curseur sera totalement à gauche dans son cadre (respectivement, en haut) ; si au contraire, Hpos vaut $FFFF, le curseur sera totalement à droite dans son cadre (respectivement, en bas). Pour obtenir exactement 64 positions possibles pour le curseur, il faut spécifier pour HorizBody la valeur $FFFF/64, soit $400 (1024 décimal). Compris ? Bon, plus généralement, les valeurs HorizBody et VertBody se calculent d'après la formule : $FFFF/Nombre de positions du curseur possibles.

Les 6 derniers mots de la structure PropInfo sont gérés de manière interne par Intuition ; on y retrouve, à la fermeture du gadget, les nouvelles positions du curseur à l'intérieur de son cadre, entre autres. Pour le cas où le bit AUTOKNOB serait fixé, et pour reprendre l'exemple ci-dessus, notre curseur ferait exactement 1/64e de la taille totale du cadre. Dans le cas contraire, c'est à vous de faire en sorte, en le dessinant, qu'il soit à la bonne taille.

L'image a la parole

Si vous reprenez la structure Gadget, vous remarquerez un pointeur sur une structure Image, qui définit l'aspect de votre gadget. Une telle structure n'est vraiment pas longue à initialiser :

Offset Signification
0 Xpos
2 Ypos
4 Largeur
6 Hauteur
8 Nombre de plans de bits
10 Image Data
14 PlanePick
15 PlaneOnOff
16 Image Data 2

Les quatre premiers mots ne posent aucun problème de compréhension. Faites seulement attention à ce que Xpos et Ypos soient exprimés relativement aux bords du gadget, de la fenêtre ou de l'écran père de l'Image (une Image peut en effet être dessinée dans une fenêtre ou un écran. Hein ? Vous ne me croyez pas ? Et les icônes du Workbench, c'est du poulet, peut-être ?).

Le cinquième mot définit, de la même manière que pour un écran, sa profondeur, c'est-à-dire le nombre de plans de bits qui composent l'Image, c'est-à-dire enfin le nombre de couleurs. Il semble évident que ce nombre ne peut être supérieur à celui de l'écran père. Suit alors un pointeur sur les données graphiques de l'image elle-même, définies plan de bits par plan de bits.

L'octet "PlanePick" est un peu plus délicat à saisir ; si vous avez déjà programmé des BOB en AmigaBasic, cette notion devrait vous être familière. Dans le cas contraire, voici une succinte explication : il n'est pas obligatoire que l'Image s'affiche plan de bits par plan de bits à l'écran. On peut faire en sorte, par exemple, que le premier plan de bit de l'Image soit écrit dans le second plan de bits de l'écran, etc. Ceci permet de faire varier les couleurs d'une même Image, sans avoir à la redessiner entièrement. Dit de manière encore plus simple, "PlanePick" détermine les couleurs de l'Image.

"PlaneOnOff" est du même acabit : cet octet détermine ce qu'il adviendra des plans de bits non affectés par l'affichage de l'Image ; si vous désirez que ceux-ci restent tels quels, indiquez zéro, et s'ils doivent être inversés, indiquez un.

Et on termine cette structure Image par un pointeur sur d'éventuelles données graphiques supplémentaires.

Un petit mot pour en terminer avec les Images : comme je crois l'avoir fait remarquer plus haut, une Image peut-être dessinée n'importe où, que ce soit dans une fenêtre, un écran, ou une requête. Il existe une fonction Intuition, "DrawImage" (offset ?114) qui attend quatre paramètres :
  • Dans a0, l'adresse du RastPort dans lequel l'Image doit être dessinée.
  • Dans a1, l'adresse de la structure Image concernée.
  • Dans d0 et d1, les positions X et Y, encore une fois relatives aux bords du RastPort en question.
Il ne nous reste finalement plus qu'une certaine composante particulière à étudier, j'ai nommé les Borders.

Border

Quèsako, "Border" ? Si je vous dis qu'en français bien de chez nous, "Border" signifie "bord", vous ne serez guère plus avancés. Simplement, il s'agit d'un élément d'Intuition qui permet de dessiner des cadres d'un nombre quelconque de côtés. Un exemple aussi bête qu'idiot est une fenêtre : ce n'est plus ni moins d'un Border à quatre côtés !

L'avantage de pouvoir utiliser les Borders directement dans nos requêtes est évident : l'esthétique. Bien sûr, cela demande de s'em... s'enquiquiner un peu plus lors de la programmation, mais le résultat est tout de même beaucoup plus beau. Voyons d'abord le cas le plus simple. Nous voulons dessiner un Border, comme ça, à l'écran, par caprice ou par nécessité. Intuition met une fois de plus une de ses fonctions à notre disposition, j'ai nommé DrawBorder. D'offset -108, elle attend quatre paramètres :
  • Dans a0, l'adresse du RastPort dans lequel dessiner le Border.
  • Dans a1, l'adresse de la structure Border concernée.
  • Dans d0 et d1, les coordonnées X et Y du premier point du Border.
Structure Border ? J'ai dit "Structure Border", moi ? Tiens donc...

Offset Signification
0 Xoffset
2 Yoffset
4 Detail Pen
5 Block Pen (inutilisé)
6 Draw Mode
7 Nombre de points
8 Coordonnées
12 Next Border

Et c'est reparti mon kiki. "Xoffset" et "Yoffset" indiquent les coordonnées du premier point, relativement à celles données lors de l'appel de la fonction. Ça peut sembler ridicule et superflu, comme ça, mais lorsque le Border est intégré à une requête, "Xoffset" et "Yoffset" indiquent les coordonnées du premier point relativement au bord de la requête.

"DetailPen" et "BlockPen" sont désormais familiers, je ne m'étendrai donc pas dessus. Sachez seulement que "BlockPen" est ici inutilisé, allez savoir pourquoi (moi je sais, mais faites donc un effort intellectuel, que diable !). "DrawMode" n'est pas lui non plus un inconnu, il détermine le mode de dessin (JAM1, JAM2, etc.). Le mot suivant indique le nombre de points dans le cadre ; n'oubliez jamais qu'il faut trois points pour dessiner deux droites ayant un sommet commun.

Le mot long suivant pointe sur la table des coordonnées de chacun des points du cadre, un par un, à la suite l'un de l'autre. Et finalement, suit un pointeur sur une éventuelle structure Border supplémentaire. Comme d'habitude, un zéro indique qu'il n'y a pas d'autre structure.

Et de quatre !

Quatre quoi ? Mais voyons, quatre pages bien remplies, c'est déjà pas si mal. Du coup, je vous donne rendez-vous au mois prochain où nous verrons comment intégrer une Image et un Border dans une requête, faisant elle-même partie d'une fenêtre, elle-même assujettie à un écran. M'excuserez si j'omets le menu.


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]