Gestion d'un champ texteOn conserve notre structure s_gui commune et on voit ce dont nous allons avoir besoin pour gérer un champ texte. struct s_gui gestion defw ; routine de gestion selectionne defb ; objet sélectionné ou non suivant defw ; champ suivant precedent defw ; champ precedent endstructstruct s_saisietexte struct s_gui gui ; commun à tous les objets de la GUI adresse_ecran defw ; position écran contenu defs 20 ; contenu texte terminateur defb 0 ; terminateur du contenu longueur defb 20 endstruct struct s_checkbox struct s_gui gui ; commun à tous les objets de la GUI adresse_ecran defw ; position écran valeur defb ; cochée ou pas cochée checkboxchar defb ; caractère réservé pour afficher la checkbox libelle defs 20 endstructContrairement à la checkbox, la gestion d'une saisie texte va évidemment être plus complexe. On change le contenu de notre objet! Il vafalloir gérer un curseur (simple) pour l'édition, pouvoir effacer, limiter à la taille du contenu... Par contre, la gestion du curseur, du moinsses coordonnées peuvent être mutualisées entre tous les objets ayant besoin d'un curseur, on le placera dans le code de gestion générale. Pour la récupération du curseur, j'ai fait un truc qui me plait moyen pour le moment, à voir avec la suite de la GUI si on va le garder en l'état : - Le curseur donne l'emplacement du caractère à venir, qui n'est pas encore tapé sauf... - Sauf si le curseur est au maximum de la chaine, alors il vaut 1 de moins, pour écraser le dernier et ne pas déborder. On a donc deux curseurs, le premier qui est celui des caractères à venir et celui réel, dont on a besoin pour effacer. GUISaisieTexteGestion cp CODE_MORT : ret z cp CODE_INIT : jr z,GUIsaisieTexteAffiche cp CODE_DEL : jp z,.suppressionChar cp CODE_TAB : jp z,GUIObjetSuivant ; si c'est un caractère on essaie de l'ajouter cp 32 : ret c ; c'est un autre code de contrôle ; c'est un caractère, on l'ajoute (ou pas) .ajouteChar exa : call .recupereCurseur cp (ix+s_saisieTexte.longueur) : ret z ; contenu déjà rempli au maximum ld de,ix : ld hl,s_saisieTexte.contenu : add hl,de : add l : ld l,a : ld a,h : adc 0 : ld h,a : exa : ld (hl),a : inc hl : ld (hl),0 jp GUIsaisieTexteAffiche.suppressionChar call .recupereCurseur : ld a,(GUIcurseurDel) or a : ret z ; déjà plus rien dans le contenu dec a : ld de,ix : ld hl,s_saisieTexte.contenu : add hl,de : add l : ld l,a : ld a,h : adc 0 : ld h,a : ld (hl),' ' : push hl : call GUIsaisieTexteAffiche : pop hl : ld (hl),0 : jp GUIsaisieTexteAffiche ret ; s'assurer que le curseur n'est pas en dehors des clous en le maximisant à la position du dernier char .recupereCurseur ld hl,s_saisietexte.contenu : ld de,ix : add hl,de : call strlen ; longueur de chaine dans HL ld a,(ix+s_saisietexte.longueur) : cp l : ld a,l : ld (GUIcurseurDel),a : jr nz,.forceCurseur : dec l : .forceCurseur ld a,l : ld (GUIcurseur),a ret GUIsaisieTexteAffiche ld hl,(ix+s_saisieTexte.adresse_ecran) : ld de,80 : add hl,de ; ligne du dessous pour le surlignage 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) jp GUIDisplayStringLa gestion globale est un peu remaniée (nouvelle fonte, système d'activation/désactivation lors de changement de champ) GUIInitialisation ld ix,(GUIStructureCourante) .chercheDepart ld a,(ix+s_gui.selectionne) : or a : jr nz,.trouve ld de,(ix+s_gui.suivant) : ld ix,de : jr .chercheDepart .trouve ; on est positionné sur le champ à sélectionner 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 retGUIObjetSuivant 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 ld de,(ix+s_gui.suivant) : ld ix,de : ld (ix+s_gui.selectionne),1 : ld (GUIStructureCourante),ix ld a,CODE_INIT : ld hl,(ix+s_gui.gestion) : jp (hl) ; active le suivant GUIStructureCourante defw Check1 GUIStructureTemp defw #1234 GUICurseur defb 0 ; curseur visible (avec saturation) GUICurseurDel defb 0 ; curseur réel GUICheckTMP defb 0,0 ;------------------------------------------------------------------------------------------ ; affichage des chaines de caractères ;------------------------------------------------------------------------------------------ ; HL' libelle ; DE destination écran sur une adresse paire! GUIDisplayString exx : ld a,(hl) : or a : ret z : inc hl : exx ; A=caractère pseudo-ASCII sub 32 : add a : ld l,a : ld a,0 : adc a : ld h,a : add hl,hl : add hl,hl : add hl,hl ; x16 ld bc,fonte_data : add hl,bc ; données du caractère push de ld b,8 .spriteLine push de : ld a,(hl) : ld (de),a : inc l : inc e : ld a,(hl) : inc l : ld (de),a : pop de : expandNextLineDE (void) djnz .spriteLine pop de : inc de : inc de jp GUIDisplayString align 16 fonte_data incbin 'guiFonte.bin' caractere_etendu='}'+1 ; les caractères étendus commencent après le dernier caractère ASCII standard utf8remap 'â',caractere_etendu : caractere_etendu+=1 ; et on incrémente pour le suivant utf8remap 'à',caractere_etendu : caractere_etendu+=1 ; etc. utf8remap 'é',caractere_etendu : caractere_etendu+=1 utf8remap 'è',caractere_etendu : caractere_etendu+=1 utf8remap 'ê',caractere_etendu : caractere_etendu+=1 utf8remap 'ë',caractere_etendu : caractere_etendu+=1 utf8remap 'ô',caractere_etendu : caractere_etendu+=1 utf8remap 'ö',caractere_etendu : caractere_etendu+=1 utf8remap 'œ',caractere_etendu : caractere_etendu+=1 utf8remap 'æ',caractere_etendu : caractere_etendu+=1 utf8remap 'î',caractere_etendu : caractere_etendu+=1 utf8remap 'ï',caractere_etendu : caractere_etendu+=1 utf8remap 'ü',caractere_etendu : caractere_etendu+=1 utf8remap 'ù',caractere_etendu : caractere_etendu+=1 utf8remap 'û',caractere_etendu : caractere_etendu+=1 utf8remap 'Ç',caractere_etendu : caractere_etendu+=1 utf8remap '«',caractere_etendu : caractere_etendu+=1 utf8remap '»',caractere_etendu : caractere_etendu+=1 utf8remap '£',caractere_etendu : caractere_etendu+=1 utf8remap 'Æ',caractere_etendu : caractere_etendu+=1 utf8remap 'Œ',caractere_etendu : caractere_etendu+=1 checkBoxsprites=caractere_etendu : caractere_etendu+=4 ; 4 checkboxesOn vient de définir tout ce dont nous aurons besoin pour notre nouveau type d'objet et ce qui va être "magique", c'est que notreprogramme principal ne va pas changer. On a notre boucle qui gère le clavier et appelle une routine de gestion. C'est tout. Avant d'assembler ce source, vous devrez télécharger les fichiers [ guiStructure.asm ],[ guiGlobal.asm ], [ guiCheckBox.asm ], [ guiSaisieTexte.asm ],[ libChaines.asm ]dans lesquels j'ai mis nos structures, les fonctions communes et la gestion par objet. Et puis la [ fonte ] bien sûr! buildsna : bankset 0 org #38 : ei : ret org #100 : run #100 : ld sp,#100 : eiMACRO 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 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 call GUIInitialisation laBoucle halt 6 : call gererClavier cp CODE_MORT : jr z,laBoucle ld hl,laBoucle : push hl ; adresse de retour ld ix,(GUIStructureCourante) : ld hl,(ix+s_gui.gestion) : jp (hl) include 'guiStructure.asm' include 'guiCheckBox.asm' include 'guiSaisieTexte.asm' include 'guiGlobal.asm' include 'guiKeyboard.asm' include 'libChaines.asm' struct s_checkbox Check1,1,GUICheckBoxGestion ,1,Check2,Check4,#C000+80*0,0,'Première coche' ; première sélectionnée struct s_checkbox Check2,1,GUICheckBoxGestion ,0,Text3,Check1,#C000+80*1,0,'Deuxième coche' struct s_checkbox Text3 ,1,GUISaisieTexteGestion,0,Check4,Check2,#C000+80*2,0,0,20 ; champ vide et longueur 20 struct s_checkbox Check4,1,GUICheckBoxGestion ,0,Check1,Text3,#C000+80*3,0,'Quatrième coche'Et voilà notre interface qui fonctionne "toute seule", avec la gestion des champes, la bascule d'un champ à l'autre quel que soit son type, le surlignage, etc. 
Roudoudou CPCrulez[Content Management System] v8.732-desktop/c Page créée en 709 millisecondes et consultée 24 foisL'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. |
|