Suivez-nous sur X

|
|
|
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,
ALL
|
|
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
|
|
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
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Amiga C Manual - Les fenêtres
(Article écrit par Anders Bjerin et extrait d'Amiga C Manual - mars 1990)
|
|
Note : traduction par Serge Hammouche.
2. Les fenêtres
2.1 Introduction
Les fenêtres (windows) sont des boîtes rectangulaires qui peuvent être
aussi grandes que l'écran ou ne faire qu'un pixel de large. Elles peuvent
être redimensionnées, déplacées sur l'écran, passer devant ou derrière
d'autres fenêtres, et ainsi de suite. Tout est géré par Intuition, et
votre programme n'a pas à s'en occuper si vous ne le voulez pas.
Le but des fenêtres est de rendre la communication entre l'utilisateur et
l'ordinateur aussi facile que possible. Les fenêtres fournissent à
l'utilisateur un affichage structuré facile à comprendre. Elles
permettent aussi à l'utilisateur d'interagir avec les programmes grâce à
des symboles graphiques (les gadgets) qui peuvent être liés aux fenêtres
(voir le chapitre 4 - Les gadgets
pour plus d'informations sur les gadgets).
Les fenêtres fonctionnent en étroite relation avec les écrans, dans la
mesure où la résolution de l'écran, etc. influent sur le dessin des
fenêtres. Le déplacement d'un écran entraîne aussi celui de toutes les
fenêtres qui lui sont liées.
2.2 Les fenêtres spéciales
Les fenêtres normales sont des boîtes rectangulaires avec une bordure
autour. Cependant, il existe des types de fenêtre spéciaux.
2.2.1 Les fenêtres d'arrière-plan (backdrop windows)
Les fenêtres d'arrière-plan seront toujours derrière toutes les autres fenêtres.
Ceci vous permet d'avoir une fenêtre à l'arrière-plan, et elle y restera,
même si l'utilisateur se sert des gadgets de profondeur.
Les fenêtres d'arrière-plan diffèrent des autres fenêtres car :
- Elles s'ouvrent toujours derrière toutes les autres, y compris les
autres fenêtres d'arrière-plan déjà ouvertes.
- Le gadget de fermeture est le seul gadget système que vous pouvez lier à
une fenêtre d'arrière-plan (vous pouvez bien sûr y lier vos propres gadgets
normalement).
- Elle sera toujours derrière n'importe quelle autre fenêtre.
La fenêtre d'arrière-plan est très pratique quand vous voulez avoir un dessin à
l'arrière-plan (par exemple votre affichage principal), avec des outils,
etc. sur la fenêtre. Ceci permet à l'utilisateur de déplacer vos outils
comme il/elle veut sans craindre de passer les fenêtres derrière
l'affichage principal.
Dessiner dans une fenêtre d'arrière-plan plutôt que sur l'écran lui-même est
très courant car il est alors impossible de dessiner au mauvais moment.
Si un menu (Voir le chapitre 5 - Les menus
pour plus d'informations) est
affiché, les routines de dessin attendront automatiquement, et ne
détruiront donc pas le menu, ce qui serait arrivé si vous aviez dessiné
directement sur l'écran.
2.2.2 Les fenêtres sans bordures (borderless windows)
Les fenêtres sans bordures sont des fenêtres normales sauf que (surprise,
surprise) elle n'ont pas de bordures. Il est très courant de combiner une
fenêtres sans bordures et une fenêtre d'arrière-plan, pour recouvrir un écran.
Il peut être gênant pour l'utilisateur qu'une fenêtres sans bordures ne
recouvre pas entièrement l'écran, car il/elle ne peut alors plus savoir
ou les bordures de la fenêtre sont. Il est donc généralement préférable
d'avoir des fenêtres sans bordures de la taille de l'écran.
2.2.3 Les fenêtres Gimmezerozero (Gimmezerozero windows)
Une fenêtre Gimmezerozero est une fenêtre normale, sauf qu'elle est
constituée de deux zones : une fenêtre Outer et une fenêtre Inner. La fenêtre Outer
est utilisée pour afficher les bordures, les gadgets système, etc., tandis
que la fenêtre Inner n'est utilisée que par vous.
Si vous dessinez dans une fenêtre normale, vou devez commencer quelques
pixels en retrait (11, 1) pour ne pas dessiner dans les bordures, etc.
Par contre, si vous dessinez dans une fenêtre Gimmezerozero, vous n'avez
pas à faire de corrections. Le coin supérieur gauche de votre fenêtre Inner
est toujours à la position (0,0).
Les fenêtres Gimmezerozero sont donc très pratiques si vous voulez faire
beaucoup de dessins sans avoir à vous soucier des bordures.
L'inconvénient est qu'elles consomment beaucoup plus de mémoire et de
temps qu'une fenêtre normale.
2.2.4 Les fenêtres SuperBitmap (SuperBitMap windows)
Si vous utilisez une fenêtre SuperBitMap, vous allouez vous-même la
mémoire pour l'affichage de la fenêtre au lieu de laisser Intuition s'en
charger. L'avantage est que vous pouvez définir une zone de dessin plus
grande que la fenêtre. Vous pouvez alors faire défiler la zone de dessin
dans la fenêtre. Un bon exemple vous en est fourni par les programmes de
démonstrations joints à votre disquette Workbench quand vous avez acheté votre
ordinateur.
Il est généralement préférable de combiner une fenêtre SuperBitMap à une
fenêtre Gimmezerozero. Les bordures, etc., ne seront alors pas dessinées dans
votre SuperBitMap, mais dans la fenêtre Outer. Ceci vous permet de faire ce
que vous voulez dans la fenêtre Inner sans affecter les bordures, etc.
2.3 Les gadgets système (system gadgets)
Les gadgets système permettent à l'utilisateur de déplacer la fenêtre, la redimensioner, la passer
derrière les autres fenêtres, etc., sans même que votre programme ne le sache. Les gadgets
système sont contrôlés par Intuition, et sont toujours identiques. Il
vous suffit de dire à Intuition quels gadgets vous voulez, et il fait le
reste pour vous.
Les cinq gadgets système sont placés comme suit :
1 2 3 4
[*][***********][*][*]
| |
| fenêtre |
| |
| |
|__________________[*]
5
|
1 : gadget de fermeture (close gadget). Cliquez pour fermer la fenêtre.
C'est le seul gadget système auquel votre programme doit répondre.
Il indiquera à votre programme que l'utilisateur a cliqué sur le
gadget de fermeture, mais vous devez fermer la fenêtre vous-même en
appelant la fonction CloseWindow().
2 : barre de déplacement (drag gadget). Une pression du bouton gauche de
la souris quand le pointeur est dessus permet de déplacer la fenêtre
tant que le bouton n'est pas relaché. Si votre fenêtre a un intitulé,
il sera affiché par-dessus le gadget mais ne s'y mélangera pas.
3 : cellule de mise en arrière (depth-arrangement gadget back). Cliquer
sur ce gadget passe la fentre derrière toutes les autres fenêtres.
4 : cellule de mise en avant (depth-arrangement gadget up). Cliquer sur ce
gadget passe la fentre devant toutes les autres fenêtres.
5 : cellule de redimensionnement (size gadget). Une pression du bouton gauche de
la souris quand le pointeur est dessus permet changer la taille de la
fenêtre tant que le bouton n'est pas relaché.
2.4 Le rafraîchissement des fenêtres
Comme les fenêtres peuvent être déplacées sur l'écran, il est très
courant qu'elles se chevauchent. Si l'utilisateur éloigne la fenêtre du
dessus, celle du dessous doit être rafraîchie.
Il y a deux méthodes pour rafraîchir une fenêtre :
- Le rafraîchissement simplte (simple refresh). Intuition vous indique simplement qu'il faut la
rafraîchir, et votre programme doit tout redessiner lui-même.
- Le rafraîchissement intelligent (smart refresh). Intuition sauvegarde les parties cachées, et les remet
automatiquement en place. Consomme plus de mémoire que le rafraîchissment simple, mais rafraîchit
l'affichage beaucoup plus vite.
Si vous avez une fenêtre SuperBitMap, vou avez alloué la mémoire pour
l'affichage vous-même, et votre fenêtre ne sera donc pas detruite par les
autres fenêtres.
Si vous changez la taille d'une fenêtre à rafraîchissement simple, ou qu'elle est
dévoillée après avoir été masquée, Intuition vous indiquera que vous
devez la rafraîchir. Une fenêtre à rafraîchissement intelligent ne vous demandera de la
rafraîchir que si vous l'avez agrandie.
Le message IDCMP "REFRESHWINDOW" vous indique qu'il faut rafraîchir la
fenêtre (voir le chapitre 8 - IDCMP
pour plus d'informations sur les drapeaux IDCMP).
Attention : si votre programme reçoit un message REFRESHWINDOW, vous devez
appeler les fonctions BeginRefresh() - EndRefresh() :
- BeginRefresh() redessine aussi vite que possible. Seules les parties
endommagées de la fenêtre seront rafraîchies.
- EndRefresh() indique à Intuition que vous avez fini de redessiner.
Si vous recevez un message REFRESHWINDOW et que vous ne voulez pas
redessiner l'affichage, vous devez quand même appelez les deux fonctions.
Ceci mettra de l'ordre dans le système et réorganisera la Layer.library.
2.5 Initialiser une fenêtre
Avant d'ouvrir une fenêtre, vous devez initialiser une structure NewWindow qui ressemble à ceci :
struct NewWindow
{
SHORT LeftEdge, TopEdge;
SHORT Width, Height;
UBYTE DetailPen, BlockPen;
ULONG IDCMPFlags;
ULONG Flags;
struct Gadget *FirstGadget;
struct Image *CheckMark;
UBYTE *Title;
struct Screen *Screen;
struct BitMap *BitMap;
SHORT MinWidth, MinHeight;
SHORT MaxWidth, MaxHeight;
USHORT Type;
};
|
- LeftEdge (bord gauche) : position initiale en x de la fenêtre.
- TopEdge (bord supérieur) : position initiale en y de la fenêtre.
- Width (largeur) : largeur initiale de la fenêtre. Si la fenêtre est liée à
un écran haute résolution, elle peut aller de 1 à 640. Sinon (écran basse résolution)
elle peut aller de 1 à 320.
- Height (hauteur) : hauteur initiale de la fenêtre. Elle peut aller de 1 à la hauteur de l'écran.
- DetailPen (crayon à détail) : le registre couleur utilisé pour afficher le texte.
- BlockPen (crayon à bloc) : le registre couleur utilisé pour les remplissages de blocs, etc.
- IDCMPFlags (drapeaux IDCMP) : voir le
chapitre 8 - IDCMP pour la liste et les explications de ces drapeaux.
- FirstGadget (premier gadget) : un pointeur sur le premier fadget de votre liste, ou NULL si vous
n'avez pas de gadget personnel lié à la fenêtre (voir le
chapitre 4 - Les gadgets pour plus d'informations sur les gadgets).
- CheckMark (coche) : un pointeur sur une structure Image (voir le
chapitre 3 - Les graphismes pour plus d'informations
sur les structures Image) qui sera utilisée pour les éléments des menus sélectionnés (voir le
chapitre 7 - Les menus
pour plus d'informations sur les menus). Si aucun pointeur n'est donné (NULL), Intuition utilisera la coche
par défaut.
- Title (intitulé) : un pointeur sur une chaîne terminée par NULL qui sera utilisée comme intitulé de
la fenêtre. La chaîne sera placée dans la barre d'intitulé, en haut de la fenêtre.
- Screen (écran) : un pointeur sur votre écran personnalisé, ou NULL si la fenêtre doit être liée
à l'écran Workbench. Si la fenêtre est liée à l'écran Workbench, mettez la variable Type à WBENCHSCREEN, sinon
mettez la à CUSTOMSCREEN.
- BitMap : si vous utilisez une fenêtre SuperBitMap, vous devez fournir à Intuition un pointeur
sur la structure BitMap que vous avez initialisée, NULL sinon. Pensez à activer le drapeau SUPER_BITMAP, et je
vous conseille aussi de prendre une fenêtre Gimmezerozero.
- Flags (drapeaux) : si vous voulez des gadgets système, une fenêtre spéciale (sans bordures, d'arrière-plan, etc.),
activez les drapeaux nécessaires :
Gadgets système :
- WINDOWCLOSE : ajoute le gadget de fermeture dans le coin supérieur
gauche de votre fenêtre. Rappelez-vous que c'est le seul gadget système auquel votre programme doit répondre.
Intuition vous informera simplement que l'utilisateur veut fermer la fenêtre, mais vous devez le faire
vous-même en appelant la fonction CloseWindow().
- WINDOWDRAG : transforme la barre d'intitulé en un gadget qui permet à l'utilisateur de déplacer la fenêtre.
- WINDOWDEPTH : si vous voulez que l'utilisateur puisse passer la fenêtre
devant ou derrière toutes les autres fenêtres, activez ce drapeau. Les gadgets (de mise en avant/en arrière) seront
placés dans le coin supérieur droit de la fenêtre.
- WINDOWSIZING : permet à l'utilisateur de redimensioner la fenêtre comme
il le souhaite (vous pouvez spécifier les tailles maximale et minimale de la fenêtre grâce aux variables
MinWidth/MinHeight/MaxWidth/MaxHeight). La cellule de redimensionnement sera placée dans la bordure de
droite par défaut (SIZEBRIGHT), mais peut aussi être placée dans la bordure inférieure (activez le drapeau
SIZEBOTTOM) si vous voulez que la fenêtre soit affichée avec la largeur maximale.
Fenêtres spéciales :
- BACKDROP : activez ce drapeau si vous voulez une fenêtre d'arrière-plan.
- BORDERLESS : activez ce drapeau si vous voulez une fenêtre sans bordures.
- GIMMEZEROZERO : activez ce drapeau si vous voulez une fenêtre Gimmezerozero.
- SUPER_BITMAP : activez ce drapeau si vous voulez une fenêtre SuperBitMap.
Si vous utilisez un bitmap que vous avez alloué vous-même, vous devez aussi initialisez la variable
BitMap pour qu'elle pointe sur votre structure BitMap. Explication plus loin dans ce chapitre.
Drapeaux de rafraîchissement. Si vous n'utilisez pas une fenêtre SuperBitMap, vous devez activer
l'un de ces drapeaux :
- SIMPLE_REFRESH : votre programme doit redessiner l'affichage lui-même.
- SMART_REFRESH : Intuition redessinera automatiquement l'affichage si
nécessaire. Il n'y a que quand l'utilisateur agrandit la fenêtre que vous devez vous-même redessiner l'affichage.
Autres drapeaux :
- REPORTMOUSE : activez ce drapeau si vous voulez recevoir les mouvements du pointeur en terme
de coordonnées x,y (voir le chapitre 8 - IDCMP pour plus d'informations).
- NOCAREREFRESH : activez ce drapeau si vous ne voulez pas recevoir de message vous demandant de
redessiner votre fenêtre.
- RMBTRAP : activez ce drapeau si vous ne voulez pas que l'utilisateur ait accès aux menus tant
que la fenêtre est active. Si vous voulez utilisez le bouton droit de la souris pour autre chose que les menus,
vous devez activer ce drapeau (voir le
chapitre 8 - IDCMP pour plus d'informations).
- ACTIVATE : activez ce drapeau si vous voulez que la fenêtre soit
activée à son ouverture. L'utilisateur pourra bien sûr activer d'autres fenêtres après s'il le désire.
Cliquer dans une fenêtre l'activera, et toutes les entrées se feront dans la nouvelle fenêtre active.
Toutes les autres fenêtres seront désactivées, et leur barres d'intitulé passeront en mode fantôme (ghosted).
Si vous avez demandé le gadget système WINDOWSIZING, vous devez fixer les
tailles minimale/maximale de votre fenêtre, sinon vous pouvez ignorer ces
variables. Si une variable est fixée à zéro, la taille initiale (Width/Height)
sera utilisée comme taille maximale/minimale :
- MinWidth : largeur minimale de la fenêtre.
- MinHeight : hauteur minimale de la fenêtre.
- MaxWidth : largeur maximale de la fenêtre.
- MaxHeight : hauteur maximale de la fenêtre.
- Type : si votre fenêtre doit être liée à l'écran Workbench, mettez
WBENCHSCREEN, sinon mettez CUSTOMSCREEN. Si vous activez le drapeau CUSTOMSCREEN,
vous devez mettre dans la variable Screen un pointeur sur votre écran personnalisé préalablement ouvert.
Il est courant de déclarer et d'initialiser la structure NewWindow selon ses besoins, en ignorant (NULL)
le pointeur Screen. Vous ouvrez alors votre écran personnalisé, et
immédiatement après vous initialisez le pointeur Screen avec le pointeur retourné par la
fonction OpenScreen() (voir l'exemple 2 pour plus d'informations).
2.6 Ouvrir une fenêtre
La procédure d'ouverture d'une fenêtre est très proche de l'ouverture
d'un écran personnalisé. L'idée est que vous déclarez une structure NewWindow
(similaire à NewScreen) et l'initialisez selon vos besoins. Il vous
suffit dès lors d'appeler la fonction OpenWindow() (similaire à
OpenScreen()) avec votre structure NewWindow, et la fonction retourne un
pointeur sur votre structure Window. Vous n'aurez alors plus besoin de la
structure NewWindow (si vous ne voulez plus ouvrir de fenêtre utilisant
la même structure bien sûr).
Appelez la fonction OpenWindow() comme suit :
my_window = OpenWindow( &my_new_window );
|
...où my_window a été déclaré comme :
struct Window *my_window;
|
...et my_new_window a été déclaré comme :
struct NewWindow *my_new_window;
|
...et initialisée selon vos besoins.
OpenWindow() retournera un pointeur sur votre structure Window. Si elle
n'a pas pu ouvrir la fenêtre (par exemple par manque de mémoire), elle
retournera NULL. Pensez donc à vérifier ce qu'a retourné OpenWindow() :
if( my_window == NULL )
{
/* Panique ! Impossible d'ouvrir la fenêtre */
}
|
2.7 La structure Window
Quand vous aurez ouvert la fenêtre, vous recevrez un pointeur (my_window)
sur une structure Window :
struct Window
{
struct Window *NextWindow; /* Pointeur sur la prochaine fenêtre.*/
SHORT LeftEdge, TopEdge; /* Position de la fenêtre. */
SHORT Width, Height; /* Taille de la fenêtre. */
SHORT MouseY, MouseX; /* Position du pointeur par rapport */
/* au coin supérieur gauche de la */
/* fenêtre. */
SHORT MinWidth, MinHeight; /* Taille minimale/maximale de la */
USHORT MaxWidth, MaxHeight; /* fenêtre. */
ULONG Flags; /* Les drapeaux de la fenêtre. */
struct Menu *MenuStrip; /* Pointeur sur le premier menu de */
/* la fenêtre. */
UBYTE *Title; /* L'intitulé de la fenêtre. */
struct Requester *FirstRequest;
struct Requester *DMRequest;
SHORT ReqCount;
struct Screen *WScreen; /* Un pointeur sur l'écran auquel la */
/* fenêtre est liée. */
struct RastPort *RPort; /* Le RastPort de la fenêtre. */
BYTE BorderLeft, BorderTop, BorderRight, BorderBottom;
struct RastPort *BorderRPort; /* Pointeur sur le RastPort de la */
/* fenêtre Outer s'il s'agit d'une */
/* fenêtre Gimmezerozero. */
struct Gadget *FirstGadget;
struct Window *Parent, *Descendant;
USHORT *Pointer; /* Données pour le Pointeur. */
BYTE PtrHeight; /* Hauteur du pointeur. */
BYTE PtrWidth; /* Largeur du pointeur. */
BYTE XOffset, YOffset; /* point actif du pointeur. */
ULONG IDCMPFlags; /* Les drapeaux IDCMP. */
struct MsgPort *UserPort, *WindowPort;
struct IntuiMessage *MessageKey;
UBYTE DetailPen, BlockPen;
struct Image *CheckMark;
UBYTE *ScreenTitle; /* L'intitulé de l'écran auquel la */
/* fenêtre est liée. */
/* A n'utiliser que si vous avez ouvert une Gimmezerozero Window: */
SHORT GZZMouseX; /* Position de la souris par rapport à l'Inner */
SHORT GZZMouseY; /* Window. */
SHORT GZZWidth; /* Taille de la fenetre Inner. */
SHORT GZZHeight;
UBYTE *ExtData;
BYTE *UserData;
struct Layer *WLayer;
struct TextFont *IFont;
};
|
2.8 Ouvrir une fenêtre SuperBitMap
La différence entre l'ouverture d'une fenêtre normale et celle d'une
fenêtre SuperBitMap est qu'Intuition alloue automatiquement de la mémoire
pour l'affichage d'un fenêtre normale, tandis qu'une fenêtre SuperBitMap
doit allouer sa mémoire elle-même. Néanmoins, c'est en fait moins dur
qu'il n'y paraît. Vous n'avez qu'à suivre ces étapes :
- 1. Déclarer et initialiser une structure NewWindow selon vos besoins.
(prendre Flags = SUPER_BITMAP, et BitMap=NULL)
struct NewWindow my_new_window={ .... };
|
- 2. Déclarer une structure BitMap :
- 3. Initialiser votre propre BitMap en appelant la fonction :
InitBitMap( &my_bitmap, Depth, Width, Height );
|
- &my_bitmap : un pointeur sur la structure my_bitmap.
- Depth : nombre de plans de bits à utiliser.
- Width : la largeur du BitMap.
- Height : la hauteur du BitMap.
- 4. Allouer de la mémoire pour l'affichage du BitMap :
for( loop=0; loop < Depth; loop++)
if( (my_bitmap.Planes[loop] = AllocRaster( Width,
Height )) == NULL )
{
/* Panique ! Pas assez de mémoire */
}
|
- 5. Après avoir alloué la mémoire d'affichage, il est préférable d'effacer les plans de bits :
for( loop=0; loop < Depth; loop++)
BltClear(my_bitmap.Planes[loop], RASSIZE(Width, Height), 0);
|
- 6. S'assurer que le pointeur BitMap de NewWindow pointe bien sur votre structure BitMap :
my_new_window.BitMap=&my_bitmap;
|
- 7. Enfin, ouvrir la fenêtre :
my_window = OpenWindow( &my_new_window );
|
- 8. Ne pas oublier de fermer la fenêtre, et de libérer la mémoire d'affichage :
CloseWindow( my_window );
for( loop=0; loop < Depth; loop++)
if( my_bitmap.Planes[loop] )
FreeRaster( my_bitmap.Planes[loop], Width, Height );
|
2.9 Faire son propre pointeur personnalisé (custom pointer)
Chaque fenêtre peut avoir son propre pointeur. Quand la fenêtre devient
active, le pointeur change d'apparence. Ceci aide l'utilisateur à savoir
quelle fenêtre est active, et peut aussi renseigner l'utilisateur sur ce
qu'est en train de faire l'ordinateur. Par exemple, un traitement de
texte peut avoir un pointeur en forme de crayon, et quand l'ordinateur
est occupé, le pointeur peut se changer en un petit symbole "Zzz".
Si votre fenêtre utilise un pointeur personnalisé (custom), vous devez :
- Allouer et initialiser une structure de données Sprite.
- Utiliser la fonction SetPointer() pour changer le pointeur de la fenêtre.
Quand vous faites une nouvelle image pour votre pointeur, vous devez
d'abord prévoir à quoi il ressemblera. Le pointeur est en fait un sprite
(Voir le chapitre 10 - Les sprites
pour plus d'informations sur les sprites),
il peut donc avoir jusqu'à 16 pixels de large, et être aussi haut que vous
le souhaitez. Vous pouvez utiliser trois couleurs plus la transparence
(comme le pointeur est un sprite (no. 0), il peut passer d'un écran à un
autre ayant une résolution différente sans problèmes d'affichage).
Un joli pointeur "flèche" (16 pixels de large, 16 lignes de haut) peut avoir cet aspect :
0000000200000000 0: Transparent
0000002200000000 1: Rouge
0000023200000000 2: Noir
0000231200000000 3: Blanc
0002311200000000
0023111222222200
0231111133333320
2311111111111132
0211111111111112
0021111222221112
0002111200023112
0000211200023112
0000021200023112
0000002200023112
0000000200023112
0000000000022222
|
Vous devez maintenant le transformer en données Sprite. Chaque ligne du
pointeur sera transformée en deux mots de données. Le premier mot
représente le premier plan de bits, et le deuxième mot le deuxième plan de bits.
Le principe est que pour la couleur 0 les deux plans de bits doivent être à
0, pour la couleur 1 le plan de bit 0 doit être à 1 et le plan de bits 1 à
0 et ainsi de suite :
Couleur Plan de bits 1 Plan de bits 0 Car
--------------------------------------------------------------------
0 0 0 00 Binaire = 0 Décimal
1 0 1 01 Binaire = 1 Décimal
2 1 0 10 Binaire = 2 Décimal
3 1 1 11 Binaire = 3 Décimal
|
Les données du pointeur ressembleront donc à ceci :
Plan de bits 0 Plan de bits 1
0000 0000 0000 0000 0000 0001 0000 0000
0000 0000 0000 0000 0000 0011 0000 0000
0000 0010 0000 0000 0000 0111 0000 0000
0000 0110 0000 0000 0000 1101 0000 0000
0000 1110 0000 0000 0001 1001 0000 0000
0001 1110 0000 0000 0011 0001 1111 1100
0011 1111 1111 1100 0111 0000 1111 1110
0111 1111 1111 1110 1100 0000 0000 0011
0011 1111 1111 1110 0100 0000 0000 0001
0001 1110 0000 1110 0010 0001 1111 0001
0000 1110 0000 1110 0001 0001 0001 1001
0000 0110 0000 1110 0000 1001 0001 1001
0000 0010 0000 1110 0000 0101 0001 1001
0000 0000 0000 1110 0000 0011 0001 1001
0000 0000 0000 1110 0000 0001 0001 1001
0000 0000 0000 0000 0000 0000 0001 1111
|
La dernière étape est la traduction des nombres binaires en hexadécimal.
Regroupez les nombres binaires par quatre et transformez-les en hexadécimal :
0000 = 0 0100 = 4 1000 = 8 1100 = C
0001 = 1 0101 = 5 1001 = 9 1101 = D
0010 = 2 0110 = 6 1010 = A 1110 = E
0011 = 3 0111 = 7 1011 = B 1111 = F
|
Le résultat aura cette allure :
Zéro Un
-------------
0000 0100
0000 0300
0200 0700
0600 0d00
0E00 1900
1E00 31FC
3FFC 60FE
7FFE c003
3FFE 4001
1E0E 21F1
0E0E 1119
060E 0919
020E 0519
000E 0319
000E 0119
0000 001F
|
Comme l'Amiga doit aussi stocker la position du pointeur, sa taille, etc.,
vous devez aussi déclarer deux mots vides au début des données du sprite
et deux autres à la fin. Ces mots seront initialisés et mis à jour par
Intuition, vous n'avez donc pas à vous en occuper.
Voici donc la déclaration et l'initialisation des données d'un beau
sprite flèche pour un pointeur (un nombre hexadécimal tel 3FFE s'écrit 0x3FFE en C) :
UWORD chip my_sprite_data[36]=
{
0x0000, 0x0000, /* Utilisés seulement par Intuition. */
0x0000, 0x0100,
0x0000, 0x0300,
0x0200, 0x0700,
0x0600, 0x0D00,
0x0E00, 0x1900,
0x1E00, 0x31FC,
0x3FFC, 0x60FE,
0x7FFE, 0xC003,
0x3FFE, 0x4001,
0x1E0E, 0x21F1,
0x0E0E, 0x1119,
0x060E, 0x0919,
0x020E, 0x0519,
0x000E, 0x0319,
0x000E, 0x0119,
0x0000, 0x001F,
0x0000, 0x0000 /* Utilisés seulement par Intuition. */
};
|
Ce n'est donc pas si compliqué quand on y est habitué, mais pour vous
faciliter un peu la tâche, j'ai écrit des utilitaires qui vous aideront à
transformer les graphismes en données de sprite (voir le répertoire
Tool
pour plus d'informations).
La dernière étape est l'appel de la fonction SetPointer() qui doit se faire comme suit :
SetPointer( my_window, my_sprite_data, 16, 16, 0, -7);
|
- my_window : pointeur sur la fenêtre.
- my_sprite_data : pointeur sur les données du sprite.
- 16 : hauteur.
- 16 : largeur (inférieure ou égale à 16 !).
- 0 : XOffset, côté gauche (position du point actif).
- -7 : YOffset, à 7 lignes du haut (position du point actif).
Le point actif (hot spot) est le pixel qui sert de point sensible au pointeur. Sur
le pointeur par défaut, il est en haut à gauche, mais sur notre pointeur
personnalisé, il doit être sur le coté gauche (0), à mi-hauteur (-7).
Pour restorer le pointeur par défaut, il suffit d'appeler la fonction ClearPointer() :
ClearPointer( my_window );
|
Comme vous aller utiliser des données graphiques, il est important de les
placer en mémoire Chip. La mémoire Chip est constituée des 512 premiers
ko de mémoire, et les routines graphiques de l'Amiga exigent que les données
des sprites, comme toutes les autres données graphiques soient y soient
placées. La raison en est que si le processeur de l'Amiga peut adresser les 9
premiers Mo de mémoire, le Blitter (un coprocesseur graphique) lui, n'a
accès qu'aux 512 premiers ko).
Il y a un nouveau jeu de circuits ECS pour les Amiga 500 et 2000 qui permet au Blitter,
etc., d'accéder au premier Mo, mais sur Amiga OCS, les données doivent être placées
dans la mémoire située entre $00000 to $7FFFF.
Si vous utilisez le compilateur Lattice C V5.0 ou plus, c'est très
simple. Vous n'avez qu'à mettre le mot "chip" devant les données. Par exemple :
UWORD chip graphics_data[]={ ... };
|
Sur le compilateur Lattice C V4.0, vous pouvez compiler les sources avec
le commitateur "-acdb" qui chargera tout dans la mémoire Chip. Par exemple :
lc -acdb -Lm my_program.c
|
Ce qui lance lc1 puis lc2, et lie le code avec la bibliothèque mathématique standard.
Tout est chargé en mémoire Chip.
Si vous n'avez pas l'un de ces compilateurs C, vous verrez probablement
comment faire dans le manuel. Attention ! Si vous n'indiquez pas au
compilateur de toujours mettre les données graphiques dans la mémoire
Chip, vous allez finir avec d'horribles bogues. Ça pourra parfois marcher si
vous n'avez pas d'extension de mémoire, mais ça plantera probablement sur
un Amiga avec extension.
2.10 Les fonctions
Voici des fonctions qui sont souvent utilisées avec les fenêtres.
OpenWindow()
Cette fonction ouvre une fenêtre avec les caractéristiques définies
dans la structure NewWindow. Elle retourne un pointeur sur la structure Window.
Si vous voulez utiliser l'écran du Workbench, et qu'il a été fermé, il
est automatiquement réouvert. Par contre, si vous liez la fenêtre à
un écran personnalisé, vous devez l'ouvrir vous-même avant d'appeler la
fonction OpenWindow().
- Synopsis : my_window = OpenWindow( my_new_window );
- my_window : (struct Window *). Pointeur sur la structure Window ou NULL si la fenêtre n'a pas pu être ouverte.
- my_new_window : (struct NewWindow *). Pointeur sur la structure NewWindow qui a été initialisée selon vos besoins.
CloseWindow()
Cette fonction ferme une fenêtre que vous avez precédemment ouvert.
Rappelez-vous que vous devez fermer toutes les fenêtres liées à un
écran avant de pouvoir fermer cet écran, et que toutes les fenêtres
ouvertes doivent être fermées avant la fin de vos programmes.
- Synopsis : CloseWindow( my_window );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un
appel d'OpenWindow().
MoveWindow()
Cette fonction déplace une fenêtre. Elle a le même effet qu'un déplacement par l'utilisateur avec la barre de déplacement.
- Synopsis : MoveWindow( my_window, delta_x, delta_y );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
- delta_x : (long). Déplacement horizontal.
- delta_y : (long). Déplacement vertical.
SizeWindow()
Cette fonction modifie la taille de la fenêtre à volonté. Elle a le même effet qu'un redimensionnement par
l'utilisateur avec le gadget de redimensionnement.
- Synopsis : SizeWindow( my_window, delta_x, delta_y );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un
appel d'OpenWindow().
- delta_x : (long). Nombre de pixels dont la taille horizontale de la fenêtre doit varier.
- delta_y : (long). Nombre de pixels dont la taille verticale de la fenêtre doit varier.
WindowToFront()
Cette fonction place la fenêtre devant toutes les autres fenêtres.
- Synopsis : WindowToFront( my_window );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par
un appel d'OpenWindow().
WindowToBack()
Cette fonction place la fenêtre derrière toutes les autres fenêtres.
- Synopsis : WindowToBack( my_window );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par
un appel d'OpenWindow().
SetWindowTitles()
Cette fonction vous permet de changer le nom d'une fenêtre après qu'elle ait été ouverte.
- Synopsis : SetWindowTitles( my_window, window_t, screen_t );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par
un appel d'OpenWindow().
- window_t : (char *). Pointeur sur une chaîne terminée par NULL qui va va devenir le nom de la fenêtre, ou
0 (efface la barre de nom) ou encore -1 (garde l'ancien nom).
- screen_t : (char *). Pointeur sur une chaîne terminée par NULL qui va devenir le nom de l'écran de la fenêtre, ou
0 (efface la barre de nom) ou encore -1 (garde l'ancien nom).
WindowLimits()
Cette fonction change la taille limite maximale/minimale de la fenêtre. Toute valeur fixée à 0 reste inchangée.
- Synopsis : WindowLimits( my_window, min_w, min_h, max_w, max_h );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un
appel d'OpenWindow().
- min_w : (long). Largeur minimale de la fenêtre.
- min_h : (long). Hauteur minimale de la fenêtre.
- max_w : (long). Largeur maximale de la fenêtre.
- max_h : (long). Hauteur maximale de la fenêtre.
SetPointer()
Cette fonction vous permet de changer le pointeur d'une fenêtre.
- Synopsis : Setpointeur( my_window, data, height, width, x, y );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par
un appel d'OpenWindow().
- data : (short *). Pointeur sur les données du sprite.
- width : (long). La largeur du pointeur. Inférieure ou égale à 16.
- height : (long). La hauteur du pointeur. Peut être quelconque.
- x : (long). La position en x du point actif.
- y : (long). La position en y du point actif.
ClearPointer()
Supprime le pointeur personnalisé (custom), et le remplace par le pointeur par défaut d'Intuition.
- Synopsis : ClearPointer( my_window );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par
un appel d'OpenWindow().
ReportMouse()
Vous pouvez appeler cette fonction que vous voulez la fenêtre commence/arrête de vous signaler la position
de la souris (voir le chapitre 8 - IDCMP pour plus d'informations sur ReportMouse).
- Synopsis : ReportMouse( my_window, boolean );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un
appel d'OpenWindow().
- boolean : (long) mettez à "TRUE" si vous voulez que la fenêtre commence à
signaler la position de la souris, sinon mettez à "FALSE", et
la fenêtre arrêtera de signaler la position de la souris.
BeginRefresh()
Cette fonction accélère le rafraîchissement des fenêtres. Vous devez
appeler cette fonction avant de commencer à rafraîchir la fenêtre, et
seules les parties nécessaires seront redessinées.
- Synopsis : BeginRefresh( my_window );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par
un appel d'OpenWindow().
EndRefresh()
Cette fonction indique à Intuition que vous avez fini vos
rafraîchissements. Attention ! Si vous recevez un message REFRESHWINDOW,
vous devez appeler les fonctions BeginRefresh() et EndRefresh(), même
si vous ne voulez rien redessiner.
- Synopsis : EndRefresh( my_window );
- my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée
par un appel d'OpenWindow().
2.11 Exemples
Nous avons vu les différents types de fenêtres, comment y lier des
gadgets système, la marche à suivre pour personnaliser votre pointeur et
plus encore. Il est à présent temps de regarder quelques
exemples
(dans le répertoire "Amiga_C_Manual/2.Fenetres").
Exemple 1
Ce programme ouvre une fenêtre normale qui est liée à l'écran Workbench. Il l'affiche pendant 30 secondes, et la ferme.
Exemple 2
Ce prgramme ouvre un écran personnalisé haute résolution en 16 couleurs et
une fenêtre normale qui lui est liée. Il l'affiche pendant 30 secondes,
puis ferme l'écran personnalisé et la fenêtre.
Exemple 3
Ce programme ouvre une fenêtre normale qui est liée à l'écran Workbench. La fenêtre utilise tous
les gadgets système, et s'active automatiquement. Il l'affiche pendant 30 secondes, et la ferme.
Pensez que le gadget de fermeture ne ferme pas la fenêtre elle-même, il vous informe seulement que
l'utilisateur veut la fermer. Mais dans cet exemple, nous ne nous occupons pas de ce qu'il veut.
Exemple 4
Ce programme ouvre deux fenêtres normales qui sont liées à l'écran Workbench. Les fenêtres utilisent
tous les gadgets système. Il les affiche pendant 30 secondes, puis les ferme.
Exemple 5
Ce programme ouvre une fenêtre sans bordures qui est liée à l'écran Workbench. Il l'affiche pendant 30 secondes,
puis le programme prend fin.
Exemple 6
Comme l'exemple 5 sauf que la fenêtre utilise aussi tous les gadgets système.
Exemple 7
Ce programme ouvre trois fenêtres, deux sont normales et la troisième
est une fenêtre d'arrière-plan. Les fenêtres utilisent tous les gadgets
systeme sauf la fenêtre d'arrière-plan, qui ne peut utiliser que le gadget de
fermeture. Après 30 secondes, le programme prend fin (essayez de passer
la fenêtre 1 ou 2 derrière la fenêtre d'arrière-plan).
Exemple 8
Ce programme ouvre une fenêtre SuperBitMap qui est liée à l'écran Workbench.
Comme c'est une fenêtre SuperBitMap, nous en faisont aussi une fenêtre Gimmezerozero.
La fenêtre utilise tous les gadgets système, et des boites sont dessinées. Il l'affiche pendant 30 secondes,
puis la ferme (rétrécissez la fenêtre, puis agrandissez-la, et vous constaterez que
les lignes sont toujours là !).
Exemple 9
Ce programme ouvre une fenêtre normale à laquelle sont liés tous les
gadgets système. Si vous activez la fenêtre, le pointeur se transforme
en une "jolie" flèche.
Exemple 10
Ce programme ouvre deux fenêtres normales auxquelles sont liés tous les
gadgets système. Si la première fenêtre est activée, le pointeur se
transforme en un symbole "Zzz", si la deuxième fenêtre est activée, le
pointeur ressemblera à un pistolet.
|