sliders H & V
This commit is contained in:
parent
c930c0dfa7
commit
ac89c58ddb
4 changed files with 360 additions and 93 deletions
BIN
doc/assets/Capture-2026-02-06-232336.png
Normal file
BIN
doc/assets/Capture-2026-02-06-232336.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
22
src/boot.asm
22
src/boot.asm
|
|
@ -195,17 +195,30 @@ build_interface:
|
|||
mov word [gs:si + widget.x], 10
|
||||
mov word [gs:si + widget.y], 100
|
||||
mov word [gs:si + widget.w], 150
|
||||
mov word [gs:si + widget.h], 20
|
||||
mov word [gs:si + widget.text_ofs], str_drag
|
||||
mov word [gs:si + widget.text_seg], cs
|
||||
mov word [gs:si + widget.h], 12
|
||||
mov byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
|
||||
mov byte [gs:si + widget.attr_mode], 1 ; Horizontal
|
||||
mov byte [gs:si + widget.attr_mode], SLIDER_HORIZONTAL
|
||||
mov word [gs:si + widget.attr_min], 10 ; X Min
|
||||
mov word [gs:si + widget.attr_max], 140 ; X Max (Widget.x + W - ThumbW)
|
||||
mov word [gs:si + widget.attr_val], 10 ; Position initiale
|
||||
mov byte [gs:si + widget.thumb_pct], 15 ; Curseur fait 15% de la largeur
|
||||
; mov word [gs:si + widget.event_drag], on_drag_slider
|
||||
|
||||
; Créer Slider (Drag)
|
||||
call gui_alloc_widget
|
||||
jc .mem_full
|
||||
mov word [gs:si + widget.x], 400
|
||||
mov word [gs:si + widget.y], 10
|
||||
mov word [gs:si + widget.w], 16
|
||||
mov word [gs:si + widget.h], 150
|
||||
mov byte [gs:si + widget.type], WIDGET_TYPE_SLIDER
|
||||
mov byte [gs:si + widget.attr_mode], SLIDER_VERTICAL
|
||||
mov word [gs:si + widget.attr_min], 10 ; X Min
|
||||
mov word [gs:si + widget.attr_max], 140 ; X Max (Widget.x + W - ThumbW)
|
||||
mov word [gs:si + widget.attr_val], 140 ; Position initiale
|
||||
mov byte [gs:si + widget.thumb_pct], 25 ; Curseur fait 15% de la largeur
|
||||
; mov word [gs:si + widget.event_drag], on_drag_slider
|
||||
|
||||
.mem_full:
|
||||
ret
|
||||
|
||||
|
|
@ -216,7 +229,6 @@ 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
|
||||
|
||||
; -----------------------------------------------------------
|
||||
; timer ISR (IRQ -> INT)
|
||||
|
|
|
|||
|
|
@ -71,15 +71,13 @@
|
|||
%define TXT_MODE 4
|
||||
%define PUTCH 5
|
||||
%define WRITE 6
|
||||
%define LINE_VERT 7
|
||||
%define LINE_HORIZ 8
|
||||
%define RECTANGLE 9
|
||||
%define RECTANGLE_FILL 10
|
||||
%define RECTANGLE_ROUND 11
|
||||
%define MOUSE_HIDE 12
|
||||
%define MOUSE_SHOW 13
|
||||
%define MOUSE_MOVE 14
|
||||
%define LINE 15
|
||||
%define LINE 7
|
||||
%define RECTANGLE 8
|
||||
%define RECTANGLE_FILL 9
|
||||
%define RECTANGLE_ROUND 10
|
||||
%define MOUSE_HIDE 11
|
||||
%define MOUSE_SHOW 12
|
||||
%define MOUSE_MOVE 13
|
||||
|
||||
; ------------------------------------------------------------
|
||||
; COMMENTAIRE SUR LA MÉTHODE D'APPEL
|
||||
|
|
@ -100,15 +98,14 @@ graph_driver:
|
|||
dw cga_set_writemode ; mode texte
|
||||
dw cga_putc ; dessin d'un caractère
|
||||
dw cga_write ; dessin d'une chaine de caractère
|
||||
dw cga_line_vertical ; dessin d'une ligne verticale
|
||||
dw cga_line_horizontal ; dessin d'une ligne horizontale
|
||||
dw cga_line ; dessin d'une ligne (Bresenham) avec décision horizontale/verticale
|
||||
dw cga_draw_rect ; dessin d'un rectangle
|
||||
dw cga_fill_rect ; dessin d'un rectangle plein
|
||||
dw cga_draw_rounded_frame ; dessin d'un rectangle arrondi
|
||||
dw cga_mouse_hide ; déplacement du curseur
|
||||
dw cga_mouse_show ; déplacement du curseur
|
||||
dw cga_mouse_cursor_move ; déplacement du curseur
|
||||
dw cga_line ; dessin d'une ligne (Bresenham)
|
||||
|
||||
|
||||
; =============================================================================
|
||||
; SECTION : PATTERNS & FILL
|
||||
|
|
@ -790,6 +787,7 @@ cga_line_horizontal:
|
|||
%undef .x1
|
||||
%undef .x2
|
||||
%undef .y
|
||||
|
||||
; ------------------------------------------------------------
|
||||
; cga_line (x1, y1, x2, y2, color)
|
||||
; Algorithme de Bresenham pour tracer une ligne arbitraire
|
||||
|
|
@ -803,6 +801,8 @@ cga_line_horizontal:
|
|||
cga_line:
|
||||
push bp
|
||||
mov bp, sp
|
||||
pusha ; Sauvegarde de tous les registres (AX, BX, CX, DX, SI, DI)
|
||||
push es ; Sauvegarde ES
|
||||
|
||||
; --- Optimisation : Lignes H/V ---
|
||||
mov ax, .y1
|
||||
|
|
@ -812,15 +812,24 @@ cga_line:
|
|||
cmp ax, .x2
|
||||
je .do_vert
|
||||
|
||||
sub sp, 10 ; Variables locales: dx, dy, sx, sy, err
|
||||
pusha
|
||||
push es
|
||||
|
||||
; --- Bresenham ---
|
||||
mov ax, VIDEO_SEG
|
||||
mov es, ax
|
||||
|
||||
call cga_mouse_hide
|
||||
|
||||
sub sp, 10 ; Variables locales: dx, dy, sx, sy, err
|
||||
|
||||
; --- Definitions locales ---
|
||||
; BP pointe sur l'ancien BP.
|
||||
; PUSHA (16 octets) + PUSH ES (2 octets) = 18 octets
|
||||
; Les variables locales commencent donc à BP-18
|
||||
%define .dx word [bp-20]
|
||||
%define .dy word [bp-22]
|
||||
%define .sx word [bp-24]
|
||||
%define .sy word [bp-26]
|
||||
%define .err word [bp-28]
|
||||
|
||||
; --- Initialisation Bresenham ---
|
||||
; dx = abs(x2 - x1), sx = sign(x2 - x1)
|
||||
mov ax, .x2
|
||||
|
|
@ -830,8 +839,8 @@ cga_line:
|
|||
neg ax
|
||||
neg bx ; sx = -1
|
||||
.calc_dx:
|
||||
mov [bp-2], ax ; save dx
|
||||
mov [bp-6], bx ; save sx
|
||||
mov .dx, ax ; save dx
|
||||
mov .sx, bx ; save sx
|
||||
|
||||
; dy = abs(y2 - y1), sy = sign(y2 - y1)
|
||||
mov ax, .y2
|
||||
|
|
@ -841,13 +850,13 @@ cga_line:
|
|||
neg ax
|
||||
neg bx ; sy = -1
|
||||
.calc_dy:
|
||||
mov [bp-4], ax ; save dy
|
||||
mov [bp-8], bx ; save sy
|
||||
mov .dy, ax ; save dy
|
||||
mov .sy, bx ; save sy
|
||||
|
||||
; err = dx - dy
|
||||
mov ax, [bp-2] ; dx
|
||||
sub ax, [bp-4] ; dy
|
||||
mov [bp-10], ax ; err
|
||||
mov ax, .dx ; dx
|
||||
sub ax, .dy ; dy
|
||||
mov .err, ax ; err
|
||||
|
||||
; Coordonnées courantes
|
||||
mov cx, .x1
|
||||
|
|
@ -878,32 +887,30 @@ cga_line:
|
|||
je .done
|
||||
|
||||
.step:
|
||||
mov ax, [bp-10] ; e2 = err
|
||||
mov ax, .err ; e2 = err
|
||||
shl ax, 1 ; e2 = 2*err
|
||||
|
||||
mov bx, [bp-4] ; dy
|
||||
mov bx, .dy ; dy
|
||||
neg bx ; -dy
|
||||
cmp ax, bx
|
||||
jle .check_y
|
||||
|
||||
add word [bp-10], bx ; err += -dy
|
||||
add cx, [bp-6] ; x += sx
|
||||
add .err, bx ; err += -dy
|
||||
add cx, .sx ; x += sx
|
||||
|
||||
.check_y:
|
||||
mov bx, [bp-2] ; dx
|
||||
mov bx, .dx ; dx
|
||||
cmp ax, bx
|
||||
jge .loop ; if e2 >= dx, skip y step
|
||||
|
||||
add word [bp-10], bx ; err += dx
|
||||
add dx, [bp-8] ; y += sy
|
||||
add .err, bx ; err += dx
|
||||
add dx, .sy ; y += sy
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
call cga_mouse_show
|
||||
pop es
|
||||
popa
|
||||
leave
|
||||
ret
|
||||
add sp, 10 ; Libération variables locales
|
||||
jmp .exit
|
||||
|
||||
.do_horiz:
|
||||
push word [bp+12] ; color
|
||||
|
|
@ -912,8 +919,7 @@ cga_line:
|
|||
push word [bp+4] ; x1
|
||||
call cga_line_horizontal
|
||||
add sp, 8
|
||||
pop bp
|
||||
ret
|
||||
jmp .exit
|
||||
|
||||
.do_vert:
|
||||
push word [bp+12] ; color
|
||||
|
|
@ -922,13 +928,23 @@ cga_line:
|
|||
push word [bp+4] ; x
|
||||
call cga_line_vertical
|
||||
add sp, 8
|
||||
|
||||
.exit:
|
||||
pop es
|
||||
popa
|
||||
pop bp
|
||||
ret
|
||||
|
||||
%undef .x1
|
||||
%undef .y1
|
||||
%undef .x2
|
||||
%undef .y2
|
||||
%undef .color
|
||||
%undef .dx
|
||||
%undef .dy
|
||||
%undef .sx
|
||||
%undef .sy
|
||||
%undef .err
|
||||
|
||||
; ------------------------------------------------------------
|
||||
; cga_draw_rect
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
;
|
||||
; =============================================================================
|
||||
|
||||
;
|
||||
; https://github.com/buserror/libmui
|
||||
;
|
||||
|
||||
; --- Configuration ---
|
||||
%define GUI_RAM_SEG 0x0A00 ; Segment de données UI
|
||||
%define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés
|
||||
|
|
@ -44,6 +48,9 @@
|
|||
; --- Widgets attributs ---
|
||||
%define BUTTON_OK 1
|
||||
|
||||
%define SLIDER_HORIZONTAL 1
|
||||
%define SLIDER_VERTICAL 2
|
||||
|
||||
; --- Structure d'un OBJET (Bouton, etc) ---
|
||||
struc widget
|
||||
.state resb 1 ; État (0=libre, >0=utilisé)
|
||||
|
|
@ -371,55 +378,157 @@ gui_logic_slider:
|
|||
|
||||
mov byte [gs:si + widget.state], GUI_STATE_PRESSED
|
||||
|
||||
; Calcul de l'ancrage
|
||||
; --- CALCUL TAILLE THUMB POUR HIT TEST ---
|
||||
; On doit savoir si le clic est SUR le curseur ou SUR la piste
|
||||
push ax
|
||||
push bx
|
||||
push dx
|
||||
|
||||
xor ax, ax
|
||||
xor bx, bx
|
||||
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
je .calc_v
|
||||
|
||||
; --- Horizontal ---
|
||||
mov ax, [gs:si + widget.w]
|
||||
mov bl, [gs:si + widget.thumb_pct]
|
||||
mul bx
|
||||
mov bx, 100
|
||||
div bx ; AX = Thumb Width
|
||||
|
||||
; Check collision avec le thumb actuel
|
||||
mov bx, [gs:si + widget.attr_val]
|
||||
cmp cx, bx
|
||||
jb .click_outside_h ; Click avant le thumb
|
||||
add bx, ax
|
||||
cmp cx, bx
|
||||
ja .click_outside_h ; Click après le thumb
|
||||
|
||||
; Click DANS le thumb : Anchor = MouseX - AttrVal
|
||||
mov ax, cx
|
||||
sub ax, [gs:si + widget.attr_val]
|
||||
mov [gs:si + widget.attr_anchor], ax
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
jne .do_drag
|
||||
jmp .init_done
|
||||
|
||||
.click_outside_h:
|
||||
; Click HORS du thumb : On centre le thumb sur la souris
|
||||
shr ax, 1
|
||||
mov [gs:si + widget.attr_anchor], ax
|
||||
jmp .init_done
|
||||
|
||||
.calc_v:
|
||||
; --- Vertical ---
|
||||
mov ax, [gs:si + widget.h]
|
||||
mov bl, [gs:si + widget.thumb_pct]
|
||||
mul bx
|
||||
mov bx, 100
|
||||
div bx ; AX = Thumb Height
|
||||
|
||||
; Check collision avec le thumb actuel
|
||||
mov bx, [gs:si + widget.attr_val]
|
||||
cmp dx, bx
|
||||
jb .click_outside_v
|
||||
add bx, ax
|
||||
cmp dx, bx
|
||||
ja .click_outside_v
|
||||
|
||||
; Click DANS le thumb
|
||||
mov ax, dx
|
||||
sub ax, [gs:si + widget.attr_val]
|
||||
mov [gs:si + widget.attr_anchor], ax
|
||||
jmp .init_done
|
||||
|
||||
.click_outside_v:
|
||||
; Click HORS du thumb
|
||||
shr ax, 1
|
||||
mov [gs:si + widget.attr_anchor], ax
|
||||
|
||||
.init_done:
|
||||
pop dx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
.do_drag:
|
||||
; --- LOGIQUE DE DÉPLACEMENT ---
|
||||
; On calcule les limites dynamiquement pour éviter que le curseur ne sorte
|
||||
push ax
|
||||
push bx
|
||||
push dx
|
||||
|
||||
xor ax, ax
|
||||
xor bx, bx
|
||||
|
||||
cmp byte [gs:si + widget.attr_mode], 1
|
||||
je .drag_h
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
je .drag_v
|
||||
|
||||
pop dx
|
||||
pop bx
|
||||
pop ax
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
.drag_h:
|
||||
; 1. Thumb Width -> AX
|
||||
mov ax, [gs:si + widget.w]
|
||||
mov bl, [gs:si + widget.thumb_pct]
|
||||
mul bx
|
||||
mov bx, 100
|
||||
div bx ; AX = Thumb Width
|
||||
|
||||
; 2. Max Pos = X + W - ThumbWidth
|
||||
mov bx, [gs:si + widget.x]
|
||||
add bx, [gs:si + widget.w]
|
||||
sub bx, ax ; BX = Max Pos
|
||||
|
||||
; 3. Min Pos = X
|
||||
mov dx, [gs:si + widget.x] ; DX = Min Pos
|
||||
|
||||
; 4. Target Pos = MouseX - Anchor
|
||||
mov ax, cx
|
||||
sub ax, [gs:si + widget.attr_anchor] ; Nouvelle pos = MouseX - Anchor
|
||||
; Clamp Min
|
||||
cmp ax, [gs:si + widget.attr_min]
|
||||
jge .chk_max_h
|
||||
mov ax, [gs:si + widget.attr_min]
|
||||
.chk_max_h:
|
||||
; Clamp Max
|
||||
cmp ax, [gs:si + widget.attr_max]
|
||||
jle .apply_pos
|
||||
mov ax, [gs:si + widget.attr_max]
|
||||
jmp .apply_pos
|
||||
sub ax, [gs:si + widget.attr_anchor]
|
||||
jmp .apply_clamp
|
||||
|
||||
.drag_v:
|
||||
mov ax, dx
|
||||
sub ax, [gs:si + widget.attr_anchor]
|
||||
; Clamp Min
|
||||
cmp ax, [gs:si + widget.attr_min]
|
||||
jge .chk_max_v
|
||||
mov ax, [gs:si + widget.attr_min]
|
||||
; 1. Thumb Height -> AX
|
||||
mov ax, [gs:si + widget.h]
|
||||
mov bl, [gs:si + widget.thumb_pct]
|
||||
mul bx
|
||||
mov bx, 100
|
||||
div bx ; AX = Thumb Height
|
||||
|
||||
.chk_max_v:
|
||||
; Clamp Max
|
||||
cmp ax, [gs:si + widget.attr_max]
|
||||
jle .apply_pos
|
||||
mov ax, [gs:si + widget.attr_max]
|
||||
; 2. Max Pos = Y + H - ThumbHeight
|
||||
mov bx, [gs:si + widget.y]
|
||||
add bx, [gs:si + widget.h]
|
||||
sub bx, ax ; BX = Max Pos
|
||||
|
||||
; 3. Min Pos = Y
|
||||
mov dx, [gs:si + widget.y] ; DX = Min Pos
|
||||
|
||||
; 4. Target Pos = MouseY - Anchor
|
||||
; MouseY est sur la pile (push dx initial), on le recupere via SP
|
||||
mov bp, sp
|
||||
mov ax, [bp] ; [bp] = Saved DX (MouseY)
|
||||
sub ax, [gs:si + widget.attr_anchor]
|
||||
|
||||
.apply_clamp:
|
||||
; AX = Target, DX = Min, BX = Max
|
||||
cmp ax, dx
|
||||
jge .chk_max
|
||||
mov ax, dx
|
||||
jmp .apply_pos
|
||||
.chk_max:
|
||||
cmp ax, bx
|
||||
jle .apply_pos
|
||||
mov ax, bx
|
||||
|
||||
.apply_pos:
|
||||
pop dx
|
||||
pop bx
|
||||
add sp, 2 ; Clean AX from stack
|
||||
|
||||
cmp ax, [gs:si + widget.attr_val]
|
||||
je .no_change
|
||||
mov [gs:si + widget.attr_val], ax
|
||||
|
|
@ -471,7 +580,6 @@ gui_logic_checkbox:
|
|||
ret
|
||||
|
||||
|
||||
|
||||
; Dessine le widget pointé par SI
|
||||
gui_draw_single_widget:
|
||||
pusha
|
||||
|
|
@ -525,23 +633,36 @@ gui_draw_single_widget:
|
|||
.case_5:
|
||||
|
||||
|
||||
|
||||
.done:
|
||||
GFX MOUSE_SHOW ; On réaffiche la souris APRES, capturant le widget fini
|
||||
popa
|
||||
ret
|
||||
|
||||
; --- Locals Mapping ---
|
||||
%define .thumb_x1 word [bp-2]
|
||||
%define .thumb_y1 word [bp-4]
|
||||
%define .thumb_x2 word [bp-6]
|
||||
%define .thumb_y2 word [bp-8]
|
||||
%define .track_x1 word [bp-10]
|
||||
%define .track_y1 word [bp-12]
|
||||
%define .track_x2 word [bp-14]
|
||||
%define .track_y2 word [bp-16]
|
||||
draw_slider:
|
||||
push bp
|
||||
mov bp, sp
|
||||
sub sp, 16 ; Reserve space for locals
|
||||
|
||||
; Save track coords (Arguments passed in AX, BX, CX, DX)
|
||||
mov .track_x1, ax
|
||||
mov .track_y1, bx
|
||||
mov .track_x2, cx
|
||||
mov .track_y2, dx
|
||||
|
||||
; 1. Dessiner la piste (Track)
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE_LIGHT
|
||||
GFX RECTANGLE, ax, bx, cx, dx, 0
|
||||
GFX RECTANGLE_FILL, .track_x1, .track_y1, .track_x2, .track_y2, PATTERN_WHITE_LIGHT
|
||||
GFX RECTANGLE, .track_x1, .track_y1, .track_x2, .track_y2, 0
|
||||
|
||||
; 2. Calculer la taille du curseur (Thumb)
|
||||
push ax ; Sauvegarde coords track (X1, Y1, X2, Y2)
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
je .calc_v
|
||||
|
||||
|
|
@ -553,12 +674,34 @@ draw_slider:
|
|||
mov bx, 100
|
||||
div bx ; AX = Thumb Width
|
||||
|
||||
mov bx, [gs:si + widget.y] ; BX = Y1
|
||||
mov dx, bx
|
||||
add dx, [gs:si + widget.h] ; DX = Y2
|
||||
mov cx, [gs:si + widget.attr_val] ; CX = X1
|
||||
add ax, cx ; AX = X1 + Width = X2
|
||||
xchg ax, cx ; AX = X1, CX = X2
|
||||
; Thumb X1 = attr_val
|
||||
mov cx, [gs:si + widget.attr_val]
|
||||
|
||||
; --- CLAMP X1 (Fix Overflow) ---
|
||||
; Max X1 = TrackX2 - ThumbW
|
||||
mov dx, .track_x2
|
||||
sub dx, ax ; DX = Max X1
|
||||
cmp cx, dx
|
||||
jle .chk_min_x
|
||||
mov cx, dx
|
||||
.chk_min_x:
|
||||
cmp cx, .track_x1
|
||||
jge .ok_x1
|
||||
mov cx, .track_x1
|
||||
.ok_x1:
|
||||
mov .thumb_x1, cx
|
||||
|
||||
; Thumb X2 = X1 + Width
|
||||
add cx, ax
|
||||
mov .thumb_x2, cx
|
||||
|
||||
; Thumb Y1 = Track Y1
|
||||
mov ax, .track_y1
|
||||
mov .thumb_y1, ax
|
||||
|
||||
; Thumb Y2 = Track Y2
|
||||
mov ax, .track_y2
|
||||
mov .thumb_y2, ax
|
||||
jmp .draw_thumb
|
||||
|
||||
.calc_v:
|
||||
|
|
@ -570,23 +713,119 @@ draw_slider:
|
|||
mov bx, 100
|
||||
div bx ; AX = Thumb Height
|
||||
|
||||
mov bx, [gs:si + widget.attr_val] ; BX = Y1
|
||||
mov dx, bx
|
||||
add dx, ax ; DX = Y2
|
||||
mov ax, [gs:si + widget.x] ; AX = X1
|
||||
mov cx, ax
|
||||
add cx, [gs:si + widget.w] ; CX = X2
|
||||
; Thumb Y1 = attr_val
|
||||
mov cx, [gs:si + widget.attr_val]
|
||||
|
||||
; --- CLAMP Y1 (Fix Overflow) ---
|
||||
; Max Y1 = TrackY2 - ThumbH
|
||||
mov dx, .track_y2
|
||||
sub dx, ax ; DX = Max Y1
|
||||
cmp cx, dx
|
||||
jle .chk_min_y
|
||||
mov cx, dx
|
||||
.chk_min_y:
|
||||
cmp cx, .track_y1
|
||||
jge .ok_y1
|
||||
mov cx, .track_y1
|
||||
.ok_y1:
|
||||
mov .thumb_y1, cx
|
||||
|
||||
; Thumb Y2 = Y1 + Height
|
||||
add cx, ax
|
||||
mov .thumb_y2, cx
|
||||
|
||||
; Thumb X1 = Track X1
|
||||
mov ax, .track_x1
|
||||
mov .thumb_x1, ax
|
||||
|
||||
; Thumb X2 = Track X2
|
||||
mov ax, .track_x2
|
||||
mov .thumb_x2, ax
|
||||
|
||||
.draw_thumb:
|
||||
; 3. Dessiner le curseur (Thumb)
|
||||
GFX RECTANGLE_FILL, ax, bx, cx, dx, PATTERN_WHITE
|
||||
GFX RECTANGLE, ax, bx, cx, dx, 0
|
||||
add sp, 8 ; Nettoyer la pile des push ax..dx
|
||||
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
|
||||
call draw_text
|
||||
GFX RECTANGLE_FILL, .thumb_x1, .thumb_y1, .thumb_x2, .thumb_y2, PATTERN_WHITE
|
||||
GFX RECTANGLE, .thumb_x1, .thumb_y1, .thumb_x2, .thumb_y2, 0
|
||||
|
||||
; --- Grip Lines (3 lignes pour un look moderne) ---
|
||||
cmp byte [gs:si + widget.attr_mode], 2
|
||||
je .grip_v
|
||||
|
||||
; --- Grip Horizontal (Lignes verticales) ---
|
||||
; Center X
|
||||
mov ax, .thumb_x1
|
||||
add ax, .thumb_x2
|
||||
shr ax, 1 ; AX = Center X
|
||||
|
||||
; Y bounds (padding 3px)
|
||||
mov bx, .thumb_y1
|
||||
add bx, 3
|
||||
mov dx, .thumb_y2
|
||||
sub dx, 3
|
||||
|
||||
; Center Line
|
||||
GFX LINE, ax, bx, ax, dx, 0
|
||||
|
||||
; Left Line
|
||||
mov cx, ax
|
||||
sub cx, 2
|
||||
cmp cx, .thumb_x1
|
||||
jle .skip_left
|
||||
GFX LINE, cx, bx, cx, dx, 0
|
||||
.skip_left:
|
||||
|
||||
; Right Line
|
||||
mov cx, ax
|
||||
add cx, 2
|
||||
cmp cx, .thumb_x2
|
||||
jge .grip_done
|
||||
GFX LINE, cx, bx, cx, dx, 0
|
||||
jmp .grip_done
|
||||
|
||||
.grip_v:
|
||||
; --- Grip Vertical (Lignes horizontales) ---
|
||||
; Center Y
|
||||
mov bx, .thumb_y1
|
||||
add bx, .thumb_y2
|
||||
shr bx, 1 ; BX = Center Y
|
||||
|
||||
; X bounds (padding 3px)
|
||||
mov ax, .thumb_x1
|
||||
add ax, 3
|
||||
mov cx, .thumb_x2
|
||||
sub cx, 3
|
||||
|
||||
; Center Line
|
||||
GFX LINE, ax, bx, cx, bx, 0
|
||||
|
||||
; Top Line
|
||||
mov dx, bx
|
||||
sub dx, 2
|
||||
cmp dx, .thumb_y1
|
||||
jle .skip_top
|
||||
GFX LINE, ax, dx, cx, dx, 0
|
||||
.skip_top:
|
||||
|
||||
; Bottom Line
|
||||
mov dx, bx
|
||||
add dx, 2
|
||||
cmp dx, .thumb_y2
|
||||
jge .grip_done
|
||||
GFX LINE, ax, dx, cx, dx, 0
|
||||
|
||||
.grip_done:
|
||||
leave
|
||||
ret
|
||||
|
||||
|
||||
; Clean up defines
|
||||
%undef .thumb_x1
|
||||
%undef .thumb_y1
|
||||
%undef .thumb_x2
|
||||
%undef .thumb_y2
|
||||
%undef .track_x1
|
||||
%undef .track_y1
|
||||
%undef .track_x2
|
||||
%undef .track_y2
|
||||
|
||||
draw_button:
|
||||
; Dispatch selon état
|
||||
|
|
|
|||
Loading…
Reference in a new issue