kernel: Add a very basic GUI widget system
This commit is contained in:
parent
5c1a000e24
commit
8ac2d2c0d4
|
@ -7,6 +7,7 @@
|
||||||
mov r4, 32
|
mov r4, 32
|
||||||
mov r5, 32
|
mov r5, 32
|
||||||
mov r6, 0
|
mov r6, 0
|
||||||
|
mov r7, 0
|
||||||
call new_window
|
call new_window
|
||||||
|
|
||||||
call get_unused_task_id
|
call get_unused_task_id
|
||||||
|
@ -85,7 +86,7 @@ close_window:
|
||||||
jmp event_loop_end
|
jmp event_loop_end
|
||||||
|
|
||||||
window_title: data.str "Terminal" data.8 0
|
window_title: data.str "Terminal" data.8 0
|
||||||
window_struct: data.fill 0, 32
|
window_struct: data.fill 0, 36
|
||||||
|
|
||||||
shell_task_id: data.8 0
|
shell_task_id: data.8 0
|
||||||
|
|
||||||
|
|
10
fox32os.def
10
fox32os.def
|
@ -38,3 +38,13 @@ write: jmp [0x00000D20]
|
||||||
|
|
||||||
; shell jump table
|
; shell jump table
|
||||||
new_shell_task: jmp [0x00000E10]
|
new_shell_task: jmp [0x00000E10]
|
||||||
|
|
||||||
|
; widget jump table
|
||||||
|
draw_widgets_to_window: jmp [0x00000F10]
|
||||||
|
handle_widget_click: jmp [0x00000F14]
|
||||||
|
|
||||||
|
; event types
|
||||||
|
const EVENT_TYPE_BUTTON_CLICK: 0x80000000
|
||||||
|
|
||||||
|
; widget types
|
||||||
|
const WIDGET_TYPE_BUTTON: 0x00000000
|
||||||
|
|
|
@ -56,6 +56,11 @@ jump_table:
|
||||||
; shell jump table
|
; shell jump table
|
||||||
org.pad 0x00000610
|
org.pad 0x00000610
|
||||||
data.32 new_shell_task
|
data.32 new_shell_task
|
||||||
|
|
||||||
|
; widget jump table
|
||||||
|
org.pad 0x00000710
|
||||||
|
data.32 draw_widgets_to_window
|
||||||
|
data.32 handle_widget_click
|
||||||
jump_table_end:
|
jump_table_end:
|
||||||
|
|
||||||
; initialization code
|
; initialization code
|
||||||
|
@ -265,6 +270,7 @@ get_os_version:
|
||||||
#include "fxf/fxf.asm"
|
#include "fxf/fxf.asm"
|
||||||
#include "shell/shell.asm"
|
#include "shell/shell.asm"
|
||||||
#include "task.asm"
|
#include "task.asm"
|
||||||
|
#include "widget/widget.asm"
|
||||||
#include "window/window.asm"
|
#include "window/window.asm"
|
||||||
#include "vfs.asm"
|
#include "vfs.asm"
|
||||||
|
|
||||||
|
|
95
kernel/widget/button.asm
Normal file
95
kernel/widget/button.asm
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
; button widget routines
|
||||||
|
|
||||||
|
; button widget struct:
|
||||||
|
; data.32 next_ptr - pointer to next widget, or 0 for none
|
||||||
|
; data.32 id - the ID number of this widget
|
||||||
|
; data.32 type - the type of this widget
|
||||||
|
; data.32 text_ptr - pointer to null-terminated text string
|
||||||
|
; data.32 foreground_color - text foreground color
|
||||||
|
; data.32 background_color - button background color
|
||||||
|
; data.16 width - width of this button
|
||||||
|
; data.16 reserved
|
||||||
|
; data.16 x_pos - X coordinate of this widget
|
||||||
|
; data.16 y_pos - Y coordinate of this widget
|
||||||
|
|
||||||
|
const BUTTON_WIDGET_STRUCT_SIZE: 32 ; 8 words = 32 bytes
|
||||||
|
|
||||||
|
; draw a button widget to a window
|
||||||
|
; FIXME: this needs some major cleanup, this is like register soup
|
||||||
|
; inputs:
|
||||||
|
; r0: pointer to window struct
|
||||||
|
; r1: pointer to a null-terminated string
|
||||||
|
; r2: foreground color
|
||||||
|
; r3: background color
|
||||||
|
; r4: button width
|
||||||
|
; r5: X coordinate
|
||||||
|
; r6: Y coordinate
|
||||||
|
draw_button_widget:
|
||||||
|
push r0
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r3
|
||||||
|
push r4
|
||||||
|
push r5
|
||||||
|
push r10
|
||||||
|
push r20
|
||||||
|
push r30
|
||||||
|
push r31
|
||||||
|
|
||||||
|
push r1
|
||||||
|
mov r20, 0
|
||||||
|
draw_button_widget_strlen_loop:
|
||||||
|
inc r1
|
||||||
|
inc r20
|
||||||
|
cmp.8 [r1], 0
|
||||||
|
ifnz jmp draw_button_widget_strlen_loop
|
||||||
|
pop r1
|
||||||
|
|
||||||
|
mov r30, r5
|
||||||
|
mov r31, r4
|
||||||
|
div r4, 2
|
||||||
|
mul r20, 8
|
||||||
|
div r20, 2
|
||||||
|
sub r4, r20
|
||||||
|
add r5, r4
|
||||||
|
|
||||||
|
call get_window_overlay_number
|
||||||
|
mov r10, r0
|
||||||
|
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r3
|
||||||
|
push r4
|
||||||
|
push r5
|
||||||
|
mov r5, r0
|
||||||
|
mov r2, r31
|
||||||
|
mov r4, r3
|
||||||
|
mov r3, 16
|
||||||
|
mov r0, r30
|
||||||
|
mov r1, r6
|
||||||
|
call draw_filled_rectangle_to_overlay
|
||||||
|
pop r5
|
||||||
|
pop r4
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
|
||||||
|
mov r0, r1
|
||||||
|
mov r4, r3
|
||||||
|
mov r3, r2
|
||||||
|
mov r1, r5
|
||||||
|
mov r2, r6
|
||||||
|
mov r5, r10
|
||||||
|
call draw_str_to_overlay
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r30
|
||||||
|
pop r20
|
||||||
|
pop r10
|
||||||
|
pop r5
|
||||||
|
pop r4
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
pop r0
|
||||||
|
ret
|
194
kernel/widget/widget.asm
Normal file
194
kernel/widget/widget.asm
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
; widget management routines
|
||||||
|
|
||||||
|
; widget types
|
||||||
|
const WIDGET_TYPE_BUTTON: 0x00000000
|
||||||
|
|
||||||
|
; widget struct:
|
||||||
|
; data.32 next_ptr - pointer to next widget, or 0 for none
|
||||||
|
; data.32 id - the ID number of this widget
|
||||||
|
; data.32 type - the type of this widget
|
||||||
|
; remaining entries vary depending on widget type
|
||||||
|
|
||||||
|
; draw all of a window's widgets to a window
|
||||||
|
; inputs:
|
||||||
|
; r0: pointer to window struct
|
||||||
|
; outputs:
|
||||||
|
; none
|
||||||
|
draw_widgets_to_window:
|
||||||
|
push r10
|
||||||
|
|
||||||
|
; get pointer to first widget
|
||||||
|
mov r10, r0
|
||||||
|
add r10, 32
|
||||||
|
mov r10, [r10]
|
||||||
|
draw_widgets_to_window_next:
|
||||||
|
; check widget type
|
||||||
|
add r10, 8
|
||||||
|
cmp [r10], WIDGET_TYPE_BUTTON
|
||||||
|
ifz call draw_widgets_to_window_button
|
||||||
|
|
||||||
|
; point to the next widget, if any
|
||||||
|
sub r10, 8
|
||||||
|
mov r10, [r10]
|
||||||
|
cmp r10, 0
|
||||||
|
ifz jmp draw_widgets_to_window_done
|
||||||
|
jmp draw_widgets_to_window_next
|
||||||
|
draw_widgets_to_window_done:
|
||||||
|
pop r10
|
||||||
|
ret
|
||||||
|
draw_widgets_to_window_button:
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r3
|
||||||
|
push r4
|
||||||
|
push r5
|
||||||
|
push r6
|
||||||
|
push r10
|
||||||
|
|
||||||
|
; put button parameters in registers for the drawing routine
|
||||||
|
add r10, 4
|
||||||
|
mov r1, [r10] ; text_ptr
|
||||||
|
add r10, 4
|
||||||
|
mov r2, [r10] ; foreground_color
|
||||||
|
add r10, 4
|
||||||
|
mov r3, [r10] ; background_color
|
||||||
|
add r10, 4
|
||||||
|
movz.16 r4, [r10] ; width
|
||||||
|
add r10, 4
|
||||||
|
movz.16 r5, [r10] ; x_pos
|
||||||
|
add r10, 2
|
||||||
|
movz.16 r6, [r10] ; y_pos
|
||||||
|
call draw_button_widget
|
||||||
|
|
||||||
|
pop r10
|
||||||
|
pop r6
|
||||||
|
pop r5
|
||||||
|
pop r4
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
|
||||||
|
; check if a widget was clicked and if so, add an event to the window's event queue
|
||||||
|
; inputs:
|
||||||
|
; r0: pointer to window struct
|
||||||
|
; r1: X coordinate of click
|
||||||
|
; r2: Y coordinate of click
|
||||||
|
; outputs:
|
||||||
|
; none
|
||||||
|
handle_widget_click:
|
||||||
|
push r0
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r3
|
||||||
|
push r4
|
||||||
|
push r5
|
||||||
|
push r6
|
||||||
|
push r7
|
||||||
|
push r8
|
||||||
|
push r30
|
||||||
|
|
||||||
|
mov r30, r0
|
||||||
|
|
||||||
|
; get pointer to first widget
|
||||||
|
add r0, 32
|
||||||
|
mov r0, [r0]
|
||||||
|
handle_widget_click_check_type:
|
||||||
|
; check widget type
|
||||||
|
add r0, 8
|
||||||
|
cmp [r0], WIDGET_TYPE_BUTTON
|
||||||
|
ifz jmp handle_widget_click_button
|
||||||
|
handle_widget_click_done:
|
||||||
|
pop r30
|
||||||
|
pop r8
|
||||||
|
pop r7
|
||||||
|
pop r6
|
||||||
|
pop r5
|
||||||
|
pop r4
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
pop r0
|
||||||
|
ret
|
||||||
|
handle_widget_click_button:
|
||||||
|
push r0
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r21
|
||||||
|
push r22
|
||||||
|
|
||||||
|
; get button width
|
||||||
|
add r0, 16
|
||||||
|
movz.16 r10, [r0]
|
||||||
|
|
||||||
|
; get button X coordinate
|
||||||
|
add r0, 4
|
||||||
|
movz.16 r11, [r0]
|
||||||
|
|
||||||
|
; get button Y coordinate
|
||||||
|
add r0, 2
|
||||||
|
movz.16 r12, [r0]
|
||||||
|
|
||||||
|
; calculate button's right side coordinate
|
||||||
|
mov r21, r11
|
||||||
|
add r21, r10
|
||||||
|
|
||||||
|
; calculate button's bottom right corner coordinate
|
||||||
|
mov r22, r12
|
||||||
|
add r22, 16
|
||||||
|
|
||||||
|
; check if r1 is between r11 and r21
|
||||||
|
; and if r2 is between r12 and r22
|
||||||
|
cmp r1, r11
|
||||||
|
iflt jmp handle_widget_click_button_no_click
|
||||||
|
cmp r1, r21
|
||||||
|
ifgt jmp handle_widget_click_button_no_click
|
||||||
|
cmp r2, r12
|
||||||
|
iflt jmp handle_widget_click_button_no_click
|
||||||
|
cmp r2, r22
|
||||||
|
ifgt jmp handle_widget_click_button_no_click
|
||||||
|
|
||||||
|
; if we reach this point then the button was clicked!!
|
||||||
|
pop r22
|
||||||
|
pop r21
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r0
|
||||||
|
|
||||||
|
; add a button click event to the window
|
||||||
|
sub r0, 4
|
||||||
|
mov r1, [r0] ; parameter 0: widget ID
|
||||||
|
mov r2, 0
|
||||||
|
mov r3, 0
|
||||||
|
mov r4, 0
|
||||||
|
mov r5, 0
|
||||||
|
mov r6, 0
|
||||||
|
mov r7, 0
|
||||||
|
mov r8, r30
|
||||||
|
mov r0, EVENT_TYPE_BUTTON_CLICK
|
||||||
|
call new_window_event
|
||||||
|
|
||||||
|
jmp handle_widget_click_done
|
||||||
|
handle_widget_click_button_no_click:
|
||||||
|
pop r22
|
||||||
|
pop r21
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r0
|
||||||
|
|
||||||
|
; get pointer to next widget
|
||||||
|
sub r0, 8
|
||||||
|
mov r0, [r0]
|
||||||
|
|
||||||
|
; if this is the last widget, then exit
|
||||||
|
cmp r0, 0
|
||||||
|
ifz jmp handle_widget_click_done
|
||||||
|
|
||||||
|
; retry
|
||||||
|
jmp handle_widget_click_check_type
|
||||||
|
|
||||||
|
; include widget types
|
||||||
|
#include "widget/button.asm"
|
|
@ -1,5 +1,8 @@
|
||||||
; window event routines
|
; window event routines
|
||||||
|
|
||||||
|
; event types
|
||||||
|
const EVENT_TYPE_BUTTON_CLICK: 0x80000000
|
||||||
|
|
||||||
const WINDOW_EVENT_SIZE: 32
|
const WINDOW_EVENT_SIZE: 32
|
||||||
|
|
||||||
; get the next window event and remove it from the event queue
|
; get the next window event and remove it from the event queue
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
; data.8 reserved_1
|
; data.8 reserved_1
|
||||||
; data.16 reserved_2
|
; data.16 reserved_2
|
||||||
; data.32 menu_bar_ptr - pointer to this window's menu bar root struct, or 0 for none
|
; data.32 menu_bar_ptr - pointer to this window's menu bar root struct, or 0 for none
|
||||||
|
; data.32 first_widget_ptr - pointer to this window's first widget
|
||||||
|
|
||||||
const WINDOW_STRUCT_SIZE: 32 ; 8 words = 32 bytes
|
const WINDOW_STRUCT_SIZE: 36 ; 9 words = 36 bytes
|
||||||
const TITLE_BAR_HEIGHT: 16
|
const TITLE_BAR_HEIGHT: 16
|
||||||
|
|
||||||
; create a new window and allocate memory as required
|
; create a new window and allocate memory as required
|
||||||
|
@ -26,6 +27,7 @@ const TITLE_BAR_HEIGHT: 16
|
||||||
; r4: initial X coordinate (top left corner of title bar)
|
; r4: initial X coordinate (top left corner of title bar)
|
||||||
; r5: initial Y coordinate (top left corner of title bar)
|
; r5: initial Y coordinate (top left corner of title bar)
|
||||||
; r6: pointer to menu bar root struct, or 0x00000000 for no menu bar
|
; r6: pointer to menu bar root struct, or 0x00000000 for no menu bar
|
||||||
|
; r7: pointer to first widget, or 0x00000000 for no widgets
|
||||||
; outputs:
|
; outputs:
|
||||||
; none
|
; none
|
||||||
new_window:
|
new_window:
|
||||||
|
@ -57,6 +59,9 @@ new_window:
|
||||||
; menu bar root struct pointer
|
; menu bar root struct pointer
|
||||||
add r10, 6
|
add r10, 6
|
||||||
mov [r10], r6
|
mov [r10], r6
|
||||||
|
; first widget pointer
|
||||||
|
add r10, 4
|
||||||
|
mov [r10], r7
|
||||||
|
|
||||||
; then, allocate memory for the framebuffer
|
; then, allocate memory for the framebuffer
|
||||||
; the space required is width * (height + TITLE_BAR_HEIGHT) * 4
|
; the space required is width * (height + TITLE_BAR_HEIGHT) * 4
|
||||||
|
|
Loading…
Reference in New Issue
Block a user