Revenir au plan du site

Création d'une CheckBox utilisant la gestion de clavier avancée.


En accord avec la table ASCII de l'article précédent (tout à fait classique, sauf les 3 derniers caractères, je vais créer une fonte avec photoshop et l'exporter, ainsi qu'un petit curseur. La première version de la checkBox va être ultra simple, déjà parce qu'on va en mettre une seule à l'écran.
Ensuite, on va afficher la coche (valide, invalide) avec l'état du champ (actif ou non) ainsi que le libellé de la checkBox.

On va partir sur une structure assez simple (on ne se servira pas de tous les champs au début).
struct s_checkbox
routine_gestion defw ; routine que doit appeler la GUI
selectionnee defb ; checkbox active ou non
adresse_ecran defw ; position écran
valeur defb ; cochée ou pas cochée
libelle defs 20
suivant defw ; champ suivant
precedent defw ; champ precedent
endstruct

Voici mes images de travail et le source correspondant.
 
Petite subtilité avec cette fonte, elle dispose d'un index. On évite alors de faire la multiplication habituelle pour trouver les données et comme on a notre annuaire d'adresses, j'en ai profité pour optimiser le stockage. Ainsi, aucun caractère ne stocke de ligne vide.

Pour que le source s'assemble, il faudra les binaires de la fonte, de la coche ainsi que la quasi totalité du source précédent concernant la gestion clavier. Téléchargez les fichiers [  checkboxSprites  ] [  Fonte.dat  ] [  Fonte.idx  ] [  Gestion de clavier ASM  ]
La gestion de la checkBox se résume (pour le moment) à permuter le champ 'valeur' et afficher le champ
buildsna : bankset 0
org #38 : ei : ret
org #100 : run #100 : ld sp,#100 : ei

MACRO expandNextLineDE
ld a,d : add 8 : ld d,a : and #38 : jr nz,@termine
ld a,80 : add e : ld e,a : ld a,#C0 : adc d : ld d,a : res 3,d
@termine
MEND

struct s_checkbox
routine_gestion defw ; routine que doit appeler la GUI
selectionnee defb ; checkbox active ou non
adresse_ecran defw ; position écran
valeur defb ; cochée ou pas cochée
libelle defs 20
suivant defw ; champ suivant
precedent defw ; champ precedent
endstruct

ld bc,#7F10 : out (c),c : ld a,#54 : out (c),a
ld bc,#7F00 : out (c),c : ld a,#54 : out (c),a
ld bc,#7F01 : out (c),c : ld a,#44 : out (c),a
ld bc,#7F02 : out (c),c : ld a,#5B : out (c),a
ld bc,#7F03 : out (c),c : ld a,#4B : out (c),a

ld ix,uneCheck : call GUICheckBoxAffiche

laBoucle
halt 6 : call gererClavier

cp CODE_MORT : jr z,laBoucle ; pas de touche spéciale ni de caractère renvoyé, on ne fait rien

ld ix,uneCheck
cp ' ' : call z,GUICheckBoxFlip ; on a une entrée clavier et c'est Espace, alors on permute la coche
jr laBoucle


;------------------------------------------------------------------------------------------
; gestion de la checkBox
;------------------------------------------------------------------------------------------
GUICheckBoxFlip push af : ld a,(ix+s_checkbox.valeur) : inc a : and 1 : ld (ix+s_checkbox.valeur),a : call GUICheckBoxAffiche : pop af : ret

GUICheckBoxAffiche ld a,(ix+s_checkbox.selectionnee) : add a : add (ix+s_checkbox.valeur) ; numéro de sprite de 0 à 3
add a : add a : ld e,a : add a : add a : add a : add e ; x36 qui est la taille du sprite
ld hl,checkBoxSprites : add l : ld l,a : ld a,h : adc 0 : ld h,a ; adresse du sprite
ld de,(ix+s_checkbox.adresse_ecran) : ld b,4 : .centrage expandNextLineDE (void) : djnz .centrage
ld bc,(12<<8)|#FF
.displayCheck push de : ldi 3 : pop de
expandNextLineDE (void)
djnz .displayCheck
push ix : pop hl : ld a,s_checkbox.libelle : add l : ld l,a : ld a,h : adc 0 : ld h,a : exx
ld hl,(ix+s_checkbox.adresse_ecran) : ld a,4 : add l : ld l,a : ex hl,de
jp GUIDisplayString
checkBoxSprites incbin 'GUICheckboxSprites.bin'

;------------------------------------------------------------------------------------------
; affichage des chaines de caractères
;------------------------------------------------------------------------------------------

; HL' libelle
; DE destination écran
GUIDisplayString
exx : ld a,(hl) : or a : ret z : inc hl : exx ; A=caractère pseudo-ASCII
ld hl,fonte_idx>>2 : sub 32 : add l : ld l,a : add hl,hl : add hl,hl ; pointe dans l'index sur le descripteur de la lettre
push de
ld a,(hl) ; nombre de lignes à 'sauter'
push hl
or a : jr z,.displaySprite
ld b,a : xor a
.razLine
push de : ld (de),a : inc de : ld (de),a : pop de : exa : expandNextLineDE (void) : exa
djnz .razLine
.displaySprite
inc l : ld a,(hl) : or a : jr z,.skipChar ; espace...
ld b,a : inc l : ld a,(hl) : inc l : ld h,(hl) : ld l,a ; B=hauteur
add lo(referenceSprite) : ld l,a : ld a,h : adc hi(referenceSprite) : ld h,a ; HL=sprite du caractère
.spriteLine
push de : ld a,(hl) : ld (de),a : inc l : inc de : ld a,(hl) : inc hl : ld (de),a : pop de : expandNextLineDE (void)
djnz .spriteLine
.skipChar
; compléter le bas si besoin
pop hl : ld a,(hl) : inc l : add (hl) : ld b,a : ld a,21 : sub b : jr z,.dejaComplet
ld b,a : xor a
.razLine2
push de : ld (de),a : inc de : ld (de),a : pop de : exa : expandNextLineDE (void) : exa
djnz .razLine2
.dejaComplet
pop de : inc de : inc de
jp GUIDisplayString

align 2
fonte_data incbin 'FONTE21.DAT'
align 4
fonte_idx incbin 'FONTE21.IDX' ; encodée avec des lettres en #4000 (optimisée pour de la RAM à banker)

referenceSprite=fonte_data-#4000


struct s_checkbox uneCheck,1,#0000,1,#C000,0,'Pour test!'

include 'GUIkeyboard.asm'


Notre exemple semble fonctionnel, maintenant on va se servir de tous les champs de la structure et ajouter 2 autres checkBox pour voir comment gérer le passage de l'une à l'autre, si le sprite change bien, et on va voir ça dans [ l'article suivant! ]