fixing button

This commit is contained in:
Frater 2026-02-05 16:59:41 +01:00
commit c5b2970fe9
4 changed files with 663 additions and 522 deletions

View file

@ -135,10 +135,10 @@ build_interface:
mov word [gs:si + widget.w], 80 mov word [gs:si + widget.w], 80
mov word [gs:si + widget.h], 20 mov word [gs:si + widget.h], 20
mov word [gs:si + widget.text_ofs], str_quit mov word [gs:si + widget.text_ofs], str_quit
mov byte [gs:si + widget.user_id], 1 ; Style "Bouton par défaut" (OK) ; mov byte [gs:si + widget.user_id], 1 ; Style "Bouton par défaut" (OK)
mov word [gs:si + widget.text_seg], cs ; Texte est dans la ROM mov word [gs:si + widget.text_seg], cs ; Texte est dans la ROM
mov word [gs:si + widget.event_click], on_click_quit ; Fonction à appeler mov word [gs:si + widget.event_click], on_click_quit ; Fonction à appeler
mov byte [gs:si + widget.type], WIDGET_TYPE_BUTTON mov byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
; Créer Bouton 2 "HELLO" ; Créer Bouton 2 "HELLO"
call gui_alloc_widget call gui_alloc_widget
@ -150,7 +150,19 @@ build_interface:
mov word [gs:si + widget.h], 20 mov word [gs:si + widget.h], 20
mov word [gs:si + widget.text_ofs], str_hello mov word [gs:si + widget.text_ofs], str_hello
mov word [gs:si + widget.text_seg], cs mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_BUTTON mov byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
; Créer Bouton 2 "HELLO"
call gui_alloc_widget
jc .mem_full
mov word [gs:si + widget.x], 100
mov word [gs:si + widget.y], 150
mov word [gs:si + widget.w], 80
mov word [gs:si + widget.h], 20
mov word [gs:si + widget.text_ofs], str_hello
mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
; Pas de callback ; Pas de callback
; Créer Slider (Drag) ; Créer Slider (Drag)

View file

@ -73,7 +73,7 @@
%define WRITE 6 %define WRITE 6
%define LINE_VERT 7 %define LINE_VERT 7
%define LINE_HORIZ 8 %define LINE_HORIZ 8
%define RECTANGLE_DRAW 9 %define RECTANGLE 9
%define RECTANGLE_FILL 10 %define RECTANGLE_FILL 10
%define RECTANGLE_ROUND 11 %define RECTANGLE_ROUND 11
%define MOUSE_HIDE 12 %define MOUSE_HIDE 12
@ -90,7 +90,7 @@
; Si vous changez le code du driver, tant que la table au début ; Si vous changez le code du driver, tant que la table au début
; ne change pas d'ordre, la GUI n'a pas besoin d'être recompilée. ; ne change pas d'ordre, la GUI n'a pas besoin d'être recompilée.
; ------------------------------------------------------------ ; ------------------------------------------------------------
align 2
graph_driver: graph_driver:
dw cga_init ; init de la carte graphique dw cga_init ; init de la carte graphique
dw cga_putpixel ; dessin d'un pixel dw cga_putpixel ; dessin d'un pixel
@ -107,26 +107,28 @@ graph_driver:
dw cga_mouse_hide ; déplacement du curseur dw cga_mouse_hide ; déplacement du curseur
dw cga_mouse_show ; déplacement du curseur dw cga_mouse_show ; déplacement du curseur
dw cga_mouse_cursor_move ; déplacement du curseur dw cga_mouse_cursor_move ; déplacement du curseur
;
; convert al -> AX aligned with "cl"
%macro ALING_BYTE 0
mov ah,al
xor al,al
shr ax,cl
xchg ah,al
%endmacro
; ============================================================================= ; =============================================================================
; SECTION : PATTERNS & FILL ; SECTION : PATTERNS & FILL
; https://paulsmith.github.io/classic-mac-patterns/
; ============================================================================= ; =============================================================================
;
; pattern ID
%define PATTERN_BLACK 0
%define PATTERN_GRAY_DARK 1
%define PATTERN_GRAY_MID 2
%define PATTERN_GRAY_LIGHT 3
%define PATTERN_WHITE_LIGHT 4
%define PATTERN_WHITE 5
align 8 align 8
pattern_black dq 0x0000000000000000 pattern_8x8:
pattern_gray_dark dq 0xDDFF77FFDDFF77FF dq 0x0000000000000000 ; pattern_black (Tout à 0 = Noir)
pattern_gray_mid dq 0xDD77DD77DD77DD77 dq 0x2200880022008800 ; pattern_gray_dark (Majorité de 0)
pattern_gray_light dq 0xAA55AA55AA55AA55 dq 0x2288228822882288 ; pattern_gray_mid
pattern_white_light dq 0x8800220088002200 dq 0xAA55AA55AA55AA55 ; pattern_gray_light (50/50)
pattern_white dq 0xFFFFFFFFFFFFFFFF dq 0x77DD77DD77DD77DD ; pattern_white_light (Majorité de 1 = Clair)
dq 0xFFFFFFFFFFFFFFFF ; pattern_white (Tout à 1 = Blanc)
; ------------------------------------------------------------ ; ------------------------------------------------------------
; initialise le mode graphique (via l'int 10h) ; initialise le mode graphique (via l'int 10h)
@ -141,7 +143,6 @@ cga_init:
mov ah, 0x00 ; AH=00h set video mode mov ah, 0x00 ; AH=00h set video mode
mov al, GFX_MODE mov al, GFX_MODE
int 0x10 int 0x10
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
; mov byte [BDA_GFX + gfx.cur_mode], 1 ; mov byte [BDA_GFX + gfx.cur_mode], 1
; dessine un background "check-board" ; dessine un background "check-board"
@ -184,6 +185,7 @@ cga_calc_addr:
shr ah, cl shr ah, cl
ret ret
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; gfx_set_writemode (mode) ; gfx_set_writemode (mode)
; Défini le mode d'écriture : ; Défini le mode d'écriture :
@ -311,6 +313,14 @@ get_glyph_offset:
; - x non aligné (x&7 != 0) ; - x non aligné (x&7 != 0)
; - écrit sur 2 bytes (di et di+1) dans chaque banque ; - écrit sur 2 bytes (di et di+1) dans chaque banque
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; convert al -> AX aligned with "cl"
%macro ALING_BYTE 0
mov ah,al
xor al,al
shr ax,cl
xchg ah,al
%endmacro
cga_putc: cga_putc:
push bp push bp
mov bp, sp mov bp, sp
@ -466,6 +476,10 @@ cga_putpixel:
push bp push bp
mov bp, sp mov bp, sp
pusha pusha
mov ax, VIDEO_SEG
mov es, ax
call cga_mouse_hide ; Protection souris call cga_mouse_hide ; Protection souris
mov cx, .x mov cx, .x
mov dx, .y mov dx, .y
@ -513,7 +527,10 @@ cga_getpixel:
mov cx, .x mov cx, .x
mov dx, .y mov dx, .y
mov ax, VIDEO_SEG
mov es, ax
call cga_calc_addr call cga_calc_addr
mov al, [es:di] mov al, [es:di]
and al, ah and al, ah
setnz al setnz al
@ -839,21 +856,29 @@ cga_draw_rect:
%define .y1 word [bp+6] %define .y1 word [bp+6]
%define .x2 word [bp+8] %define .x2 word [bp+8]
%define .y2 word [bp+10] %define .y2 word [bp+10]
%define .pat word [bp+12] %define .pat_id word [bp+12]
; Variable locale pour l'index du motif (y % 8) ; Variable locale pour l'index du motif (y % 8)
%define .pat_idx word [bp-2] %define .pat_idx word [bp-2]
%define .x_end_idx word [bp-4]
%define .pattern_offset word [bp-6]
cga_fill_rect: cga_fill_rect:
push bp push bp
mov bp, sp mov bp, sp
sub sp, 2 ; Reserve espace pour .pat_idx sub sp, 6 ; Reserve espace pour .pat_idx et .x_end_idx
pusha pusha
push es push es
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
mov es, ax mov es, ax
; calcul de l'offset de départ du pattern
mov ax, .pat_id
shl ax, 3 ; * 8
add ax, pattern_8x8
mov .pattern_offset, ax
call cga_mouse_hide call cga_mouse_hide
; --- 1. Tri des coordonnées (X et Y) --- ; --- 1. Tri des coordonnées (X et Y) ---
@ -893,6 +918,7 @@ cga_fill_rect:
mov cx, .x1 mov cx, .x1
mov dx, .y1 mov dx, .y1
; Note: cga_calc_addr attend CX=x, DX=y et retourne DI ; Note: cga_calc_addr attend CX=x, DX=y et retourne DI
; Si cga_calc_addr modifie BX, la sauvegarde [STACK A] est vitale. ; Si cga_calc_addr modifie BX, la sauvegarde [STACK A] est vitale.
call cga_calc_addr ; DI = Offset début ligne call cga_calc_addr ; DI = Offset début ligne
@ -917,6 +943,7 @@ cga_fill_rect:
shr si, 3 ; SI = Index start byte shr si, 3 ; SI = Index start byte
mov cx, .x2 mov cx, .x2
shr cx, 3 ; CX = Index end byte shr cx, 3 ; CX = Index end byte
mov .x_end_idx, cx ; Sauvegarde de l'index de fin pour la boucle horizontale
; --- 5. Récupérer la hauteur dans un registre sûr --- ; --- 5. Récupérer la hauteur dans un registre sûr ---
pop bx ; RESTAURER HAUTEUR DANS BX [STACK A] pop bx ; RESTAURER HAUTEUR DANS BX [STACK A]
@ -930,16 +957,13 @@ cga_fill_rect:
push bx push bx
mov bx, .pat_idx mov bx, .pat_idx
push si push si
mov si, .pat mov si, .pattern_offset
mov dl, [cs:si + bx] ; DL = Pattern Byte mov dl, [cs:si + bx] ; DL = Pattern Byte
pop si pop si
pop bx pop bx
; Incrémenter index motif pour la prochaine ligne
inc word .pat_idx
and word .pat_idx, 7
; --- Remplissage Horizontal --- ; --- Remplissage Horizontal ---
mov cx, .x_end_idx ; Restaurer l'index de fin pour la ligne
; Cas Single Byte (Start == End) ; Cas Single Byte (Start == End)
cmp si, cx cmp si, cx
@ -975,6 +999,10 @@ cga_fill_rect:
pop si pop si
pop di pop di
; Incrémenter index motif pour la prochaine ligne
inc word .pat_idx
and word .pat_idx, 7
; --- Passage ligne suivante (CGA Bank Switch) --- ; --- Passage ligne suivante (CGA Bank Switch) ---
xor di, 0x2000 xor di, 0x2000
test di, 0x2000 test di, 0x2000
@ -1008,7 +1036,6 @@ cga_fill_rect:
%undef .y2 %undef .y2
%undef .pat_idx %undef .pat_idx
; ------------------------------------------------------------ ; ------------------------------------------------------------
; cga_draw_rounded_frame ; cga_draw_rounded_frame
; dessiner un cadre arrondi ; dessiner un cadre arrondi
@ -1024,9 +1051,9 @@ cga_draw_rounded_frame:
mov bp, sp mov bp, sp
pusha pusha
; call cga_mouse_hide call cga_mouse_hide
; Lignes horizontales (raccourcies de 2px de chaque côté) ; Lignes horizontales (raccourcies de 2px pour laisser place à l'arrondi)
mov ax, .x1 mov ax, .x1
add ax, 2 add ax, 2
mov bx, .x2 mov bx, .x2
@ -1034,7 +1061,7 @@ cga_draw_rounded_frame:
GFX LINE_HORIZ, ax, bx, .y1, .color GFX LINE_HORIZ, ax, bx, .y1, .color
GFX LINE_HORIZ, ax, bx, .y2, .color GFX LINE_HORIZ, ax, bx, .y2, .color
; Lignes verticales (raccourcies de 2px) ; Lignes verticales (raccourcies de 1px en haut et en bas)
mov cx, .y1 mov cx, .y1
add cx, 2 add cx, 2
mov dx, .y2 mov dx, .y2
@ -1042,23 +1069,32 @@ cga_draw_rounded_frame:
GFX LINE_VERT, .x1, cx, dx, .color GFX LINE_VERT, .x1, cx, dx, .color
GFX LINE_VERT, .x2, cx, dx, .color GFX LINE_VERT, .x2, cx, dx, .color
; Pixels de coins pour l'arrondi ; Ajout des pixels de transition pour adoucir les coins (chanfrein)
mov ax, .x1
inc ax ; x1 + 1
mov bx, .y1
inc bx ; y1 + 1
GFX PUTPIXEL, ax, bx, .color ; Coin haut-gauche
mov ax, .x1 mov ax, .x1
inc ax inc ax
mov bx, .y2
dec bx ; y2 - 1
GFX PUTPIXEL, ax, bx, .color ; Coin bas-gauche
mov ax, .x2
dec ax ; x2 - 1
mov bx, .y1 mov bx, .y1
inc bx inc bx ; y1 + 1
GFX PUTPIXEL, ax, bx, .color ; top left GFX PUTPIXEL, ax, bx, .color ; Coin haut-droite
mov ax, .x2 mov ax, .x2
dec ax dec ax
GFX PUTPIXEL, ax, bx, .color ; Top-right
mov bx, .y2 mov bx, .y2
dec bx dec bx ; y2 - 1
GFX PUTPIXEL, ax, bx, .color ; bottom-right GFX PUTPIXEL, ax, bx, .color ; Coin bas-droite
mov ax, .x1
inc ax
GFX PUTPIXEL, ax, bx, .color ; bottom-left
; call cga_mouse_show call cga_mouse_show
popa popa
leave leave
@ -1082,7 +1118,7 @@ cga_draw_rounded_frame:
cga_mouse_hide: cga_mouse_hide:
pushf ; Sauver l'état des flags (interrupts) pushf ; Sauver l'état des flags (interrupts)
cli ; Désactiver les interruptions (CRITIQUE) cli ; Désactiver les interruptions (CRITIQUE)
push ax pushad ; Sauvegarder TOUS les registres 32-bits
push ds push ds
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
@ -1095,14 +1131,11 @@ cga_mouse_hide:
cmp byte [BDA_MOUSE + mouse.cur_counter], -1 cmp byte [BDA_MOUSE + mouse.cur_counter], -1
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
; C'est la transition Visible -> Caché : On efface le curseur
call cga_cursor_restorebg call cga_cursor_restorebg
; On marque qu'on ne dessine plus
mov byte [BDA_MOUSE + mouse.bkg_saved], 0
.skip_restore: .skip_restore:
pop ds pop ds
pop ax popad
popf ; Restaure les interruptions (STI si elles étaient là) popf ; Restaure les interruptions (STI si elles étaient là)
ret ret
@ -1113,7 +1146,7 @@ cga_mouse_hide:
cga_mouse_show: cga_mouse_show:
pushf pushf
cli cli
push ax pushad
push ds push ds
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
@ -1133,7 +1166,7 @@ cga_mouse_show:
.skip_draw: .skip_draw:
pop ds pop ds
pop ax popad
popf popf
ret ret
@ -1143,7 +1176,7 @@ cga_mouse_show:
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_mouse_cursor_move: cga_mouse_cursor_move:
push ax pushad
push ds push ds
push es push es
@ -1171,7 +1204,7 @@ cga_mouse_cursor_move:
.done: .done:
pop es pop es
pop ds pop ds
pop ax popad
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -1183,7 +1216,9 @@ cga_cursor_savebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 ; le buffer n'a pas encore été restauré cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 ; le buffer n'a pas encore été restauré
jne .done jne .done
mov byte [BDA_MOUSE + mouse.bkg_saved], 1 push es
mov ax, VIDEO_SEG
mov es, ax
; mémoriser position courante (utilisée pour restore) ; mémoriser position courante (utilisée pour restore)
mov cx, [BDA_MOUSE + mouse.x] mov cx, [BDA_MOUSE + mouse.x]
@ -1213,7 +1248,10 @@ cga_cursor_savebg:
.next_line: .next_line:
loop .row_loop loop .row_loop
pop es
.done: .done:
mov byte [BDA_MOUSE + mouse.bkg_saved], 1 ; Flag mis à jour après la copie
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -1224,7 +1262,9 @@ cga_cursor_restorebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 cmp byte [BDA_MOUSE + mouse.bkg_saved], 0
je .done je .done
mov byte [BDA_MOUSE + mouse.bkg_saved], 0 push es
mov ax, VIDEO_SEG
mov es, ax
; restaurer depuis la dernière position sauvegardée ; restaurer depuis la dernière position sauvegardée
mov di, [BDA_MOUSE + mouse.cur_addr_start] mov di, [BDA_MOUSE + mouse.cur_addr_start]
@ -1245,7 +1285,9 @@ cga_cursor_restorebg:
.next_line: .next_line:
loop .row_loop loop .row_loop
pop es
.done: .done:
mov byte [BDA_MOUSE + mouse.bkg_saved], 0 ; Flag mis à jour après la restauration
ret ret
; ============================================================ ; ============================================================
@ -1405,4 +1447,3 @@ cga_cursor_draw:
pop ds pop ds
popad popad
ret ret

View file

@ -55,10 +55,13 @@ mouse_reset:
mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre
mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre
mov byte [fs:BDA_MOUSE + mouse.cur_counter], 0
mov word [fs:BDA_MOUSE + mouse.cur_x], 0 mov word [fs:BDA_MOUSE + mouse.cur_x], 0
mov word [fs:BDA_MOUSE + mouse.cur_y], 0 mov word [fs:BDA_MOUSE + mouse.cur_y], 0
mov byte [fs:BDA_MOUSE + mouse.cur_drawing], 0
mov byte [BDA_MOUSE + mouse.cur_counter], -1 ; Force l'état caché au départ
mov byte [BDA_MOUSE + mouse.cur_drawing], 0 ; Reset du verrou de dessin
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
mov ax, cs mov ax, cs
mov word [fs:BDA_MOUSE + mouse.cur_seg], ax mov word [fs:BDA_MOUSE + mouse.cur_seg], ax

View file

@ -35,6 +35,10 @@
%define WIDGET_TYPE_BUTTON 0 %define WIDGET_TYPE_BUTTON 0
%define WIDGET_TYPE_SLIDER 1 %define WIDGET_TYPE_SLIDER 1
%define WIDGET_TYPE_LABEL 2 %define WIDGET_TYPE_LABEL 2
%define WIDGET_TYPE_ROUND_BUTTON 3
; --- Widgets attributs ---
%define BUTTON_OK 1
; --- Structure d'un OBJET (Bouton, etc) --- ; --- Structure d'un OBJET (Bouton, etc) ---
struc widget struc widget
@ -44,6 +48,8 @@ struc widget
.user_id resb 1 ; ID unique utilisateur .user_id resb 1 ; ID unique utilisateur
.x resw 1 ; Position X .x resw 1 ; Position X
.y resw 1 ; Position Y .y resw 1 ; Position Y
.x2 resw 1 ; Position X2 calculée
.y2 resw 1 ; Position Y2 calculée
.w resw 1 ; Largeur .w resw 1 ; Largeur
.h resw 1 ; Hauteur .h resw 1 ; Hauteur
.text_ofs resw 1 ; Offset du texte .text_ofs resw 1 ; Offset du texte
@ -280,27 +286,38 @@ gui_update_logic:
cmp dx, bx cmp dx, bx
jg .miss ; mouse.y >= widget.y ? jg .miss ; mouse.y >= widget.y ?
mov bl, [BDA_MOUSE + mouse.status]
; Dispatch selon le type ; Dispatch selon le type
cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
je .call_slider_logic jne .case_2
call gui_logic_button
jmp .done
.call_slider_logic:
call gui_logic_slider call gui_logic_slider
jmp .done jmp .done
.case_2:
cmp byte [gs:si + widget.type], WIDGET_TYPE_BUTTON
jne .case_3
call gui_logic_button
jmp .done
.case_3:
cmp byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
jne .case_4
call gui_logic_button
jmp .done
.case_4:
jmp .done
.miss: .miss:
; Si on n'est plus dessus, mais qu'on l'était avant (HOVER/PRESSED), il faut redessiner ! ; Si on n'est plus dessus, mais qu'on l'était avant (HOVER/PRESSED), il faut redessiner !
cmp byte [gs:si + widget.state], GUI_STATE_NORMAL cmp byte [gs:si + widget.state], GUI_STATE_NORMAL
je .done ; Déjà normal, rien à faire je .done ; Déjà normal, rien à faire
; Cas particulier : si c'est un slider en cours de drag, on continue la logique ; Cas particulier : si c'est un slider en cours de drag, on continue la logique
cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER ; cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
jne .reset_state ; jne .reset_state
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED ; cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
je .call_slider_logic ; je .gui_logic_slider
.reset_state: .reset_state:
mov byte [gs:si + widget.state], GUI_STATE_NORMAL mov byte [gs:si + widget.state], GUI_STATE_NORMAL
@ -417,10 +434,14 @@ gui_logic_slider:
xor ax, ax xor ax, ax
ret ret
; (Interne) Dessine le widget pointé par SI
; Dessine le widget pointé par SI
gui_draw_single_widget: gui_draw_single_widget:
pusha pusha
GFX MOUSE_HIDE ; On cache la souris AVANT de commencer le dessin du widget
mov al, [gs:si + widget.state] mov al, [gs:si + widget.state]
cmp al, [gs:si + widget.oldstate] cmp al, [gs:si + widget.oldstate]
je .done je .done
@ -438,25 +459,40 @@ gui_draw_single_widget:
add cx, ax add cx, ax
add dx, bx add dx, bx
mov [gs:si + widget.x2], cx
mov [gs:si + widget.y2], dx
; Dispatch selon le type ; Dispatch selon le type
cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER cmp byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
jne .not_slider jne .case_2
call draw_slider call draw_slider
jmp .done jmp .done
.not_slider: .case_2:
cmp byte [gs:si + widget.type], WIDGET_TYPE_BUTTON cmp byte [gs:si + widget.type], WIDGET_TYPE_BUTTON
jne .done jne .case_3
call draw_button call draw_button
jmp .done
.case_3:
cmp byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
jne .case_4
call draw_round_button
; jmp .done
.case_4:
.done: .done:
GFX MOUSE_SHOW ; On réaffiche la souris APRES, capturant le widget fini
popa popa
ret ret
draw_slider: draw_slider:
; 1. Dessiner la piste (Track) ; 1. Dessiner la piste (Track)
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_gray_mid GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE_LIGHT
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 GFX RECTANGLE, ax, bx, cx, dx, 0
; 2. Calculer la taille du curseur (Thumb) ; 2. Calculer la taille du curseur (Thumb)
push ax ; Sauvegarde coords track (X1, Y1, X2, Y2) push ax ; Sauvegarde coords track (X1, Y1, X2, Y2)
@ -501,8 +537,8 @@ draw_slider:
.draw_thumb: .draw_thumb:
; 3. Dessiner le curseur (Thumb) ; 3. Dessiner le curseur (Thumb)
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_white GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
GFX RECTANGLE_DRAW, ax, bx, cx, dx, 0 GFX RECTANGLE, ax, bx, cx, dx, 0
add sp, 8 ; Nettoyer la pile des push ax..dx add sp, 8 ; Nettoyer la pile des push ax..dx
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
call draw_text call draw_text
@ -517,62 +553,111 @@ draw_button:
cmp byte [gs:si + widget.state], GUI_STATE_HOVER cmp byte [gs:si + widget.state], GUI_STATE_HOVER
je .paint_hover je .paint_hover
.paint_normal: ; .paint_normal:
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_white ; GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
; Si user_id == 1, on dessine le style "OK" (Double bordure épaisse) ; Si user_id == 1, on dessine le style "OK" (Double bordure épaisse)
test byte [gs:si + widget.user_id], 1 ;test byte [gs:si + widget.attr_mode], BUTTON_OK
jnz .draw_default_style ;jnz .draw_default_style
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0 ; GFX RECTANGLE, ax, bx, cx, dx, 0
jmp .draw_text_now ; jmp .done
.draw_default_style: .draw_default_style:
; Bordure extérieure épaisse (2px) ; Bordure extérieure épaisse (2px)
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0 GFX RECTANGLE, ax, bx, cx, dx, 0
inc ax inc ax
inc bx inc bx
dec cx dec cx
dec dx dec dx
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0 GFX RECTANGLE, ax, bx, cx, dx, 0
; Bordure intérieure fine (après un gap de 1px blanc) ; Bordure intérieure fine (après un gap de 1px blanc)
add ax, 2 add ax, 2
add bx, 2 add bx, 2
sub cx, 2 sub cx, 2
sub dx, 2 sub dx, 2
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0 GFX RECTANGLE, ax, bx, cx, dx, 0
jmp .done
.draw_text_now: .paint_hover:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE_LIGHT
GFX RECTANGLE, ax, bx, cx, dx, 0
jmp .done
.paint_pressed:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_BLACK
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
.done:
; on affiche le texte
; Recharger les coordonnées de base pour le texte ; Recharger les coordonnées de base pour le texte
mov ax, [gs:si + widget.x] mov ax, [gs:si + widget.x]
mov bx, [gs:si + widget.y] mov bx, [gs:si + widget.y]
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
call draw_text call draw_text
jmp .done ret
;
; dessine un bouton arrondi
;
draw_round_button:
; Dispatch selon état
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
je .paint_pressed
cmp byte [gs:si + widget.state], GUI_STATE_HOVER
je .paint_hover
.paint_normal:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
mov di, 0 ; Couleur Noire
call .draw_round_borders
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
jmp .draw_text_now
.paint_hover: .paint_hover:
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_gray_mid GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0 mov di, 0 ; Couleur Noire
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE_LIGHT
call .draw_round_borders
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
jmp .draw_text_now
; Restauration coords pour le texte .paint_pressed:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_BLACK
mov di, 1 ; Bordure Blanche sur fond noir
call .draw_round_borders
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
jmp .draw_text_now
.draw_text_now:
; Recharger les coordonnées de base pour le texte
mov ax, [gs:si + widget.x] mov ax, [gs:si + widget.x]
mov bx, [gs:si + widget.y] mov bx, [gs:si + widget.y]
call draw_text call draw_text
jmp .done jmp .done
.paint_pressed:
GFX RECTANGLE_FILL, ax, bx, cx, dx, pattern_black
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
; Recharger les coordonnées car GFX a pu modifier les registres
mov ax, [gs:si + widget.x]
mov bx, [gs:si + widget.y]
call draw_text
.done: .done:
ret ret
.draw_round_borders:
; Bordure principale
GFX RECTANGLE_ROUND, ax, bx, cx, dx, di
; Si style "OK" (attr_mode & BUTTON_OK), on ajoute la double bordure
;test byte [gs:si + widget.attr_mode], BUTTON_OK
;jz .done_borders
add ax, 2
add bx, 2
sub cx, 2
sub dx, 2
GFX RECTANGLE_ROUND, ax, bx, cx, dx, di
.done_borders:
ret
;
; affiche le texte au centre du widget gs:si
;
draw_text: draw_text:
; Petit hack pour recentrer le texte après l'effet gras ; Petit hack pour recentrer le texte après l'effet gras
mov cx, [gs:si + widget.w] mov cx, [gs:si + widget.w]