checkboxes & read-me update

This commit is contained in:
Frater 2026-02-05 20:41:11 +01:00
commit 1669788929
4 changed files with 187 additions and 21 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -13,8 +13,13 @@ Rather than booting an operating system from disk, the PC starts **directly from
The project is intentionally educational, experimental, and minimalist. The project is intentionally educational, experimental, and minimalist.
![Screenshot of the boot + text test](/doc/assets/Capture-2026-01-29-210122.png) ![Screenshot of the boot + text test](/doc/assets/Capture-2026-01-29-210122.png)
Screenshot of early boot version + Text functions
![Screenshot WIP - Buttons & Sliders](/doc/assets/Capture-2026-02-03-213148.png) ![Screenshot WIP - Buttons & Sliders](/doc/assets/Capture-2026-02-03-213148.png)
Screenshot of early buttons & sliders
![Screenshot WIP - Rounded Buttons & Checkboxes ](/doc/assets/Capture-2026-01-29-210122.png)
Screenshot of rounded buttons & checkboxes
--- ---
@ -138,8 +143,13 @@ Au lieu de charger un système d’exploitation depuis un disque, le PC **démar
Le projet est volontairement **éducatif, expérimental et minimaliste**. Le projet est volontairement **éducatif, expérimental et minimaliste**.
![Screenshot of the boot + text test](/doc/assets/Capture-2026-01-29-210122.png) ![Screenshot of the boot + text test](/doc/assets/Capture-2026-01-29-210122.png)
Screenshot of early boot version + Text functions
![Screenshot WIP - Buttons & Sliders](/doc/assets/Capture-2026-02-03-213148.png) ![Screenshot WIP - Buttons & Sliders](/doc/assets/Capture-2026-02-03-213148.png)
Screenshot of early buttons & sliders
![Screenshot WIP - Rounded Buttons & Checkboxes ](/doc/assets/Capture-2026-01-29-210122.png)
Screenshot of rounded buttons & checkboxes
--- ---

View file

@ -47,8 +47,7 @@ section .text
%include "./common/bda.asm" %include "./common/bda.asm"
; %include "./common/debug_cga.asm" ; %include "./common/debug_cga.asm"
; %include "./drivers/gfx_cgam.asm" %include "./drivers/gfx_cgam.asm"
%include "./drivers/gfx_egam.asm"
%include "./services/gui_lib.asm" %include "./services/gui_lib.asm"
%include "./drivers/mouse_ps2.asm" %include "./drivers/mouse_ps2.asm"
%include "./drivers/keyboard_ps2.asm" %include "./drivers/keyboard_ps2.asm"
@ -134,7 +133,7 @@ build_interface:
mov word [gs:si + widget.x], 10 mov word [gs:si + widget.x], 10
mov word [gs:si + widget.y], 10 mov word [gs:si + widget.y], 10
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], 16
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
@ -148,24 +147,48 @@ build_interface:
mov word [gs:si + widget.x], 100 mov word [gs:si + widget.x], 100
mov word [gs:si + widget.y], 50 mov word [gs:si + widget.y], 50
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], 16
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_ROUND_BUTTON mov byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
; Créer Bouton 2 "HELLO" ; Créer checkbox 3 "option 1"
call gui_alloc_widget call gui_alloc_widget
jc .mem_full jc .mem_full
mov word [gs:si + widget.x], 100 mov word [gs:si + widget.x], 200
mov word [gs:si + widget.y], 150 mov word [gs:si + widget.y], 50
mov word [gs:si + widget.w], 80 mov word [gs:si + widget.w], 100
mov word [gs:si + widget.h], 20 mov word [gs:si + widget.h], 15
mov word [gs:si + widget.text_ofs], str_hello mov word [gs:si + widget.text_ofs], str_option1
mov word [gs:si + widget.text_seg], cs mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON mov byte [gs:si + widget.type], WIDGET_TYPE_CHECKBOX
; Pas de callback ; Pas de callback
; Créer checkbox 3 "option 2"
call gui_alloc_widget
jc .mem_full
mov word [gs:si + widget.x], 200
mov word [gs:si + widget.y], 50+16
mov word [gs:si + widget.w], 100
mov word [gs:si + widget.h], 15
mov word [gs:si + widget.text_ofs], str_option2
mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_CHECKBOX
; Créer checkbox 3 "option 2"
call gui_alloc_widget
jc .mem_full
mov word [gs:si + widget.x], 200
mov word [gs:si + widget.y], 50+16*2
mov word [gs:si + widget.w], 100
mov word [gs:si + widget.h], 15
mov word [gs:si + widget.text_ofs], str_option3
mov word [gs:si + widget.text_seg], cs
mov byte [gs:si + widget.type], WIDGET_TYPE_CHECKBOX
; Créer Slider (Drag) ; Créer Slider (Drag)
call gui_alloc_widget call gui_alloc_widget
jc .mem_full jc .mem_full
@ -188,8 +211,11 @@ build_interface:
; --- Données ROM --- ; --- Données ROM ---
str_quit db "QUITTER", 0 str_quit db "Quitter", 0
str_hello db "HELLO", 0 str_hello db "Hello", 0
str_option1 db "option 1", 0
str_option2 db "option 2", 0
str_option3 db "option 3", 0
str_drag db "->", 0 str_drag db "->", 0
; ----------------------------------------------------------- ; -----------------------------------------------------------

View file

@ -20,10 +20,13 @@
; ;
; ============================================================================= ; =============================================================================
; --- Configuration Mémoire --- ; --- Configuration ---
%define GUI_RAM_SEG 0x0A00 ; Segment de données UI %define GUI_RAM_SEG 0x0A00 ; Segment de données UI
%define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés %define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés
; Dimensions
%define GUI_CHECKBOX_SIZE 10 ;
; --- Drapeaux & États --- ; --- Drapeaux & États ---
%define GUI_STATE_FREE 0 ; Le slot est vide (mémoire dispo) %define GUI_STATE_FREE 0 ; Le slot est vide (mémoire dispo)
%define GUI_STATE_NORMAL 1 ; Affiché, repos %define GUI_STATE_NORMAL 1 ; Affiché, repos
@ -36,6 +39,7 @@
%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 %define WIDGET_TYPE_ROUND_BUTTON 3
%define WIDGET_TYPE_CHECKBOX 4
; --- Widgets attributs --- ; --- Widgets attributs ---
%define BUTTON_OK 1 %define BUTTON_OK 1
@ -307,6 +311,11 @@ gui_update_logic:
jmp .done jmp .done
.case_4: .case_4:
cmp byte [gs:si + widget.type], WIDGET_TYPE_CHECKBOX
jne .case_5
call gui_logic_checkbox
.case_5:
jmp .done 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 !
@ -434,6 +443,33 @@ gui_logic_slider:
xor ax, ax xor ax, ax
ret ret
; --- Logique spécifique Checkbox ---
gui_logic_checkbox:
test bl, 1 ; Clic gauche ?
jz .released
; Clic enfoncé
mov byte [gs:si + widget.state], GUI_STATE_PRESSED
xor ax, ax
ret
.released:
cmp byte [gs:si + widget.state], GUI_STATE_PRESSED
jne .hover
; Clic validé ! Toggle value
xor word [gs:si + widget.attr_val], 1
mov byte [gs:si + widget.oldstate], 255 ; Force redraw
mov al, 1
mov byte [gs:si + widget.state], GUI_STATE_HOVER
ret
.hover:
mov byte [gs:si + widget.state], GUI_STATE_HOVER
xor ax, ax
ret
; Dessine le widget pointé par SI ; Dessine le widget pointé par SI
@ -478,9 +514,15 @@ gui_draw_single_widget:
cmp byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON cmp byte [gs:si + widget.type], WIDGET_TYPE_ROUND_BUTTON
jne .case_4 jne .case_4
call draw_round_button call draw_round_button
; jmp .done jmp .done
.case_4: .case_4:
cmp byte [gs:si + widget.type], WIDGET_TYPE_CHECKBOX
jne .case_5
call draw_checkbox
jmp .done
.case_5:
@ -612,22 +654,23 @@ draw_round_button:
.paint_normal: .paint_normal:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
mov di, 0 ; Couleur Noire mov di, 0 ; Couleur Noire
call .draw_round_borders call draw_round_borders
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
jmp .draw_text_now jmp .draw_text_now
.paint_hover: .paint_hover:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0
; GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE_LIGHT
mov di, 0 ; Couleur Noire mov di, 0 ; Couleur Noire
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE_LIGHT call draw_round_borders
call .draw_round_borders
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
jmp .draw_text_now jmp .draw_text_now
.paint_pressed: .paint_pressed:
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_BLACK GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_BLACK
mov di, 1 ; Bordure Blanche sur fond noir mov di, 1 ; Bordure Blanche sur fond noir
call .draw_round_borders call draw_round_borders
GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT GFX TXT_MODE, GFX_TXT_WHITE_TRANSPARENT
jmp .draw_text_now jmp .draw_text_now
@ -641,9 +684,8 @@ draw_round_button:
.done: .done:
ret ret
.draw_round_borders: draw_round_borders:
; Bordure principale ; Bordure principale
GFX RECTANGLE_ROUND, ax, bx, cx, dx, di
; Si style "OK" (attr_mode & BUTTON_OK), on ajoute la double bordure ; Si style "OK" (attr_mode & BUTTON_OK), on ajoute la double bordure
;test byte [gs:si + widget.attr_mode], BUTTON_OK ;test byte [gs:si + widget.attr_mode], BUTTON_OK
;jz .done_borders ;jz .done_borders
@ -655,6 +697,93 @@ draw_round_button:
.done_borders: .done_borders:
ret ret
draw_checkbox:
; met un "fond" blanc
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
cmp byte [gs:si + widget.state], GUI_STATE_HOVER
jne .no_hover
GFX RECTANGLE_ROUND, ax, bx, cx, dx, 0
.no_hover:
; Calcul coords box (centré verticalement)
mov ax, [gs:si + widget.x]
add ax, 4
mov bx, [gs:si + widget.y]
mov cx, [gs:si + widget.h]
mov dx, [gs:si + widget.w]
sub cx, GUI_CHECKBOX_SIZE
shr cx, 1
add bx, cx ; Y1
mov cx, ax
add cx, GUI_CHECKBOX_SIZE ; X2
mov dx, bx
add dx, GUI_CHECKBOX_SIZE ; Y2
; Sauvegarde coords pour le X
push ax
push bx
push cx
push dx
; Fond blanc + Bordure noire
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
GFX RECTANGLE, ax, bx, cx, dx, 0
; Check if checked
cmp word [gs:si + widget.attr_val], 0
je .draw_label
; Dessin du X (Diagonales)
add ax, 2
add bx, 2
sub cx, 2
sub dx, 2
push ax
push bx
push dx
.loop_x:
cmp ax, cx
jg .end_x
GFX PUTPIXEL, ax, bx, 0
GFX PUTPIXEL, ax, dx, 0
inc ax
inc bx
dec dx
jmp .loop_x
.end_x:
pop dx
pop bx
pop ax
.draw_label:
pop dx
pop cx
pop bx
pop ax
; Dessin du texte à droite (BoxX2 + 6)
add cx, 6
; Y = Centré par rapport au widget
mov bx, [gs:si + widget.y]
mov ax, [gs:si + widget.h]
sub ax, 8
shr ax, 1
add bx, ax
inc bx
GFX GOTOXY, cx, bx
mov dx, [gs:si + widget.text_seg]
mov ax, [gs:si + widget.text_ofs]
GFX WRITE, dx, ax
ret
; ;
; affiche le texte au centre du widget gs:si ; affiche le texte au centre du widget gs:si
; ;
@ -691,6 +820,7 @@ draw_text:
sub bx, 8 sub bx, 8
shr bx, 1 shr bx, 1
add bx, [gs:si + widget.y] ; Y final add bx, [gs:si + widget.y] ; Y final
inc bx
pop cx ; CX = X Final, BX = Y Final pop cx ; CX = X Final, BX = Y Final