CODINGApprendre pas à pas la programmation en assembleur Z80 ★ Programmation avancée, une interface utilisateur complète ★

Faire sa propre IU - Factorisation des actions communes, joli curseur

Factorisation des actions communes et petites améliorations


Au début de nos deux objets, nous testons plusieurs codes pour les mêmes raisons (et nous allons en ajouter d'autres...). On va alléger notre source en se faisant une macro reprenant les actions communes. Cela permet aussi de faire évoluer ces actions sans devoir revenir dans chacun des objets.


macro GuiObjetActionParDefaut
.gestion
cp CODE_MORT : ret z
cp 32 : jr nc,.texte
cp CODE_INIT : jp z,.affiche
cp CODE_TAB : jp z,GUIObjetSuivant
cp CODE_TAB_INVERSE : jp z,GUIObjetPrecedent
mend


Le TAB_INVERSE nous permettra de passer à l'objet précédent si on fait SHIFT+TAB, pour cela nous allons modifier notre table de touches. Le TAB est sur la 8è ligne.

.shift48 defb 'W',CODE_MORT,'Q',CODE_TAB_INVERSE,'A',CODE_ESC,'21'


Il faudra lui attribuer une valeur libre inférieure à 32 dans guiKeyboard.asm

CODE_TAB_INVERSE equ 14


L'apparition de la fonction GUIObjetPrecedent se passe dans la gestion globale qu'on va légèrement modifier. En fonction de l'action, on charge soit l'objet précédent, soit le suivant et tout le reste du code va suivre.

GUIObjetPrecedent ld hl,(ix+s_gui.precedent) : jr GUIObjet
GUIObjetSuivant ld hl,(ix+s_gui.suivant)
GUIObjet
push hl ; on pousse dans la pile l'objet suivant ou précédent
ld hl,.nouvelObjet : push hl
ld (ix+s_gui.selectionne),0 : ld a,CODE_INIT : ld hl,(ix+s_gui.gestion) : jp (hl) ; déselectionne le courant
.nouvelObjet pop ix /* suivant ou précédent */ : ld (ix+s_gui.selectionne),1 : ld (GUIStructureCourante),ix
ld a,CODE_INIT : ld hl,(ix+s_gui.gestion) : jp (hl) ; active l'objet


Pour le moment, nos objet sont organisés dans une liste chainée circulaire. On pourrait définir un objet neutre qui ne définisse qu'un champ suivant et qui affiche du texte, une image, que sais-je. On organiserait notre liste de façon à ce que les objets neutres (ou non interactifs) soient affichés en début de gestion mais ensuite, ils deviendraient automatiquement hors-liste.

Notre fonction d'initialisation ne change (presque) pas car elle sait se caler sur le premier champ actif. Par contre, nous allons appeler chaque fonction de gestion lors du scan de recherche.

;------------------------------------------------------------------------------------------
; gestion de la GUI
; IX=structure d'initialisation
;------------------------------------------------------------------------------------------
GUIInitialisation
ld hl,.chercheDepart : push hl : ld hl,(ix+s_gui.gestion) : ld a,CODE_INIT : jp (hl) : .chercheDepart
ld a,(ix+s_gui.selectionne) : or a : jr nz,.trouve
ld de,(ix+s_gui.suivant) : ld ix,de : jr GUIInitialisation
.trouve ; on est positionné sur le champ à sélectionner

ld (GUIStructureCourante),ix ; la courante pour la gestion
ld (GUIStructureTemp),ix ; référence
.afficheTout
ld hl,.afficheSuivant : push hl : ld hl,(ix+s_gui.gestion) : ld a,CODE_INIT : jp (hl) : .afficheSuivant

ld de,(ix+s_gui.suivant) : ld hl,(GUIStructureTemp) : xor a : sbc hl,de : ld ix,de
jr nz,.afficheTout
ret


Tant que j'y étais, j'ai embelli la saisie texte pour avoir un petit curseur en surimpression, plus lisible. La suppression d'un char n'affiche plus deux fois de suite avec l'espace mais par contre, on va effacer l'ensemble du champ avant de le rafraichir.

GUIsaisieTexteAffiche
ld hl,(ix+s_saisieTexte.adresse_ecran) : ld a,8 : ld de,8
ld c,(ix+s_saisieTexte.longueur) : sla c
.razLine
ld b,c
push hl : .raz ld (hl),d : inc hl : djnz .raz : pop hl : ld a,h : add 8 : ld h,a
dec e : jr nz,.razLine

ld hl,(ix+s_saisieTexte.adresse_ecran) : ld de,80 : add hl,de ; ligne du dessous
ld a,(ix+s_gui.selectionne) : dec a : cpl : ld b,(ix+s_saisieTexte.longueur) : sla b
.surligne ld (hl),a : inc hl : djnz .surligne

ld de,ix : ld hl,s_saisieTexte.contenu : add hl,de : exx
ld de,(ix+s_saisieTexte.adresse_ecran)
call GUIDisplayString

; curseur
call GUISaisieTexteGestion.recupereCurseur
ld a,(ix+s_gui.selectionne) : or a : ret z
ld hl,(ix+s_saisieTexte.adresse_ecran) : ld d,8*4 : ld a,(GUIcurseur) : add a : ld e,a : add hl,de : ld b,4
.inverse
ld a,(hl) : or #F0 : ld (hl),a : inc l : ld a,(hl) : or #F0 : ld (hl),a : dec l : ld a,h : add 8 : ld h,a : djnz .inverse
ret


Et voilà notre nouveau curseur :)

Nous sommes prêts à ajouter de nouveaux objets, si on s'occupait [ d'un nouveau champ numérique ]?

★ ANNÉE: 2025
★ AUTEUR: Roudoudou

Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.732-desktop/c
Page créée en 303 millisecondes et consultée 9 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.