Implement clickable icon on desktop

This commit is contained in:
Juhani Krekelä 2023-03-22 20:41:02 +02:00
parent b0cebaee4b
commit 59535b12f9
1 changed files with 135 additions and 59 deletions

194
shell.asm
View File

@ -7,6 +7,8 @@ struc window
.x resw 1
.y resw 1
.data resw 1
.icon resb 1
.mouse_released_inside resb 1
.size:
endstruc
@ -36,39 +38,34 @@ initialize:
xor di, di ; read
call PONYDOS_SEG:SYS_MODIFY_SECTORS
; Create window 1
; Create icon for the disk on the desktop
mov ax, cs
add ax, 0x000
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
mov [windows + 0*window.size + window.next], ax
mov word [windows + 0*window.size + window.width], 16
mov word [windows + 0*window.size + window.height], 4
mov word [windows + 0*window.size + window.x], 10
mov word [windows + 0*window.size + window.y], 3
mov word [windows + 0*window.size + window.data], window_1
mov word [windows + 0*window.size + window.width], 5
mov word [windows + 0*window.size + window.height], 3
mov word [windows + 0*window.size + window.x], 1
mov word [windows + 0*window.size + window.y], 1
mov word [windows + 0*window.size + window.data], disk_icon
mov byte [windows + 0*window.size + window.icon], 1
mov byte [windows + 0*window.size + window.mouse_released_inside], 0
; Create window 2
mov ax, cs
add ax, 0x001
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
mov [windows + 1*window.size + window.next], ax
; Initialize file window but don't show it
mov word [windows + 1*window.size + window.width], 40
mov word [windows + 1*window.size + window.height], 4
mov word [windows + 1*window.size + window.x], 14
mov word [windows + 1*window.size + window.y], 6
mov word [windows + 1*window.size + window.data], window_2
mov word [windows + 1*window.size + window.data], file_window
mov byte [windows + 1*window.size + window.icon], 0
mov byte [windows + 1*window.size + window.mouse_released_inside], 0
call request_redraw
; Temporary testing
mov ax, cs
mov es, ax
mov di, window_1 + 32
mov cx, 3
mov dx, 16
call print_ls
mov di, window_2 + 80
mov di, file_window + 80
mov cx, 3
mov dx, 40
call print_ls
@ -124,6 +121,11 @@ process_event:
pop bx
retf
; in:
; al = WM_PAINT
; bx = window ID
; out:
; trashes everything
paint:
call get_window
@ -141,12 +143,20 @@ paint:
ret
; in:
; al = WM_MOUSE
; bx = window ID
; cl = X
; ch = Y
; dl = mouse buttons held down
; out:
; trashes everything
mouse:
call get_window
push cx
mov ax, bx
push bx
push cx
; Y
xor bx, bx
@ -167,39 +177,91 @@ mouse:
cmp [si + window.height], bx
jle .outside
pop bx
mov si, [si + window.data]
add si, 18
test dl, MOUSE_PRIMARY
cmp byte [si + window.mouse_released_inside], 0
je .not_clicking
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
jz .not_clicking
.clicking:
call raise_window
mov al, '*'
xchg byte [si], al
cmp al, '*'
je .end
call request_redraw
jmp .end
call click
.not_clicking:
mov al, ' '
xchg byte [si], al
cmp al, ' '
je .end
call request_redraw
.end:
pop cx
ret
test dl, MOUSE_PRIMARY | MOUSE_SECONDARY
jz .not_primary_held
.primary_held:
mov byte [si + window.mouse_released_inside], 0
jmp .inside
.not_primary_held:
mov byte [si + window.mouse_released_inside], 1
.outside:
pop bx
.inside:
pop cx
; Use coördinates (255,255) to make sure other windows in
; the chain don't think the cursor is inside them
mov cx, 0xffff
mov bx, [si + window.next]
mov al, WM_MOUSE
call forward_event
ret
.outside:
mov byte [si + window.mouse_released_inside], 0
pop cx
mov bx, [si + window.next]
mov al, WM_MOUSE
call forward_event
ret
; in:
; ax = window ID
; bx = X coördinate
; cx = Y coördinate
; dl = which buttons are held down
; si = pointer to window structure
; out:
; trashes everything
click:
cmp byte [si + window.icon], 0
je .file_window
.icon:
call show_file_window
jmp .end
.file_window:
call raise_window
.end:
ret
show_file_window:
cmp byte [file_window_visible], 0
jne .already_visible
push ax
mov ax, PONYDOS_SEG
mov es, ax
mov ax, cs
add ax, 0x001
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
mov [windows + 1*window.size + window.next], ax
pop ax
mov byte [file_window_visible], 1
call request_redraw
.already_visible:
ret
; in:
; al = WM_KEYBOARD
; bx = window ID
; cl = typed character
; cl = typed key
; out:
; trashes everything
keyboard:
call get_window
mov si, [si + window.data]
@ -208,6 +270,14 @@ keyboard:
call request_redraw
ret
; in:
; al = WM_UNHOOK
; bx = window ID
; cx = window to unhook
; out:
; ax = own ID if not the window to unhook
; next ID if the window to unhook
; trashes everything else
unhook:
call get_window
@ -292,23 +362,29 @@ unhook_window:
ret
; in:
; bx = window ID to raise
; ax = window ID to raise
raise_window:
push cx
push si
push es
call get_window
mov cx, bx
call unhook_window
mov cx, PONYDOS_SEG
mov es, cx
mov cx, bx
cmp [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
je .already_top
call get_window
mov cx, ax
call unhook_window
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], cx
mov [si + window.next], cx
call request_redraw
.already_top:
pop es
pop si
pop cx
@ -504,16 +580,16 @@ wallpaper_name db 'ponydos.wall', 0
%include "debug.inc"
window_1:
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '1', 0x0f
times 8 db ' ', 0x0f
times 16 db ' ', 0xf0
times 16 db ' ', 0xf0
times 16 db ' ', 0xf0
file_window_visible db 0
window_2:
db 'W', 0x0f, 'i', 0x0f, 'n', 0x0f, 'd', 0x0f, 'o', 0x0f, 'w', 0x0f, ' ', 0x0f, '2', 0x0f
times 32 db ' ', 0x0f
disk_icon:
db 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f
db 0x00, 0x0f, 0x00, 0x0f, 0x09, 0x0f, 0x00, 0x0f, 0x00, 0x0f
db 0x00, 0x0f, 0x00, 0x0f, '|', 0x0f, 0x00, 0x0f, 0x00, 0x0f
file_window:
db 'A', 0x0f, ':', 0x0f
times 38 db ' ', 0x0f
times 40 db ' ', 0xf0
times 40 db ' ', 0xf0
times 40 db ' ', 0xf0