diff options
author | Marvin Borner | 2020-10-25 13:20:35 +0100 |
---|---|---|
committer | Marvin Borner | 2020-10-25 13:20:35 +0100 |
commit | c9f89174b9ce73ed93bfad14d57b8f1a43db6bf6 (patch) | |
tree | 8a9fc5d2b7ac66b42b15521c421573db520d7d6b /libgui | |
parent | f83d5e4b8e315f2b17f0c8bf390bf967f02f5837 (diff) |
Added gui event loop and onclick listener
Diffstat (limited to 'libgui')
-rw-r--r-- | libgui/gui.c | 61 | ||||
-rw-r--r-- | libgui/inc/gfx.h | 12 | ||||
-rw-r--r-- | libgui/inc/gui.h | 22 |
3 files changed, 78 insertions, 17 deletions
diff --git a/libgui/gui.c b/libgui/gui.c index 7ea341c..aa5c494 100644 --- a/libgui/gui.c +++ b/libgui/gui.c @@ -6,13 +6,15 @@ #include <gui.h> #include <list.h> #include <mem.h> +#include <print.h> +#include <sys.h> #define MAX_WINDOWS 10 u32 window_count = 0; static struct window windows[MAX_WINDOWS] = { 0 }; -struct window *new_window(const char *title, int x, int y, u32 width, u32 height, int flags) +static struct window *new_window(const char *title, int x, int y, u32 width, u32 height, int flags) { if (window_count + 1 >= MAX_WINDOWS) return NULL; @@ -37,9 +39,9 @@ struct window *new_window(const char *title, int x, int y, u32 width, u32 height return win; } -void merge_elements(struct element *container) +static void merge_elements(struct element *container) { - if (!container->childs || !container->childs->head) + if (!container || !container->childs || !container->childs->head) return; struct node *iterator = container->childs->head; @@ -52,8 +54,26 @@ void merge_elements(struct element *container) } } -struct element *gui_add_button(struct element *container, int x, int y, u32 width, u32 height, - const char *text, u32 color) +static struct element *element_at(struct element *container, int x, int y) +{ + if (!container || !container->childs || !container->childs->head) + return NULL; + + struct element *ret = NULL; + struct node *iterator = container->childs->head; + while (iterator != NULL) { + struct context *ctx = ((struct element *)iterator->data)->ctx; + if (ctx != container->ctx && ctx->flags & WF_RELATIVE && x >= ctx->x && + x <= ctx->x + (int)ctx->width && y >= ctx->y && y <= ctx->y + (int)ctx->height) + ret = iterator->data; + iterator = iterator->next; + } + + return ret; +} + +struct element_button *gui_add_button(struct element *container, int x, int y, u32 width, + u32 height, const char *text, u32 color) { if (!container || !container->childs) return NULL; @@ -76,7 +96,36 @@ struct element *gui_add_button(struct element *container, int x, int y, u32 widt list_add(container->childs, button); merge_elements(container); - return button; + return button->data; +} + +void gui_event_loop(struct element *container) +{ + if (!container) + return; + + struct message *msg; + while (1) { + if (!(msg = msg_receive())) { + yield(); + continue; + } + + switch (msg->type) { + case GUI_MOUSE: { + struct gui_event_mouse *event = msg->data; + struct element *elem = element_at(container, event->x, event->y); + if (!elem) + continue; + + if (elem->type == GUI_TYPE_BUTTON) { + struct element_button *button = elem->data; + if (event->but1 && button->on_click) + button->on_click(); + } + } + } + } } struct element *gui_init(const char *title, u32 width, u32 height) diff --git a/libgui/inc/gfx.h b/libgui/inc/gfx.h index fe48ac2..2ce588c 100644 --- a/libgui/inc/gfx.h +++ b/libgui/inc/gfx.h @@ -39,7 +39,7 @@ #define WF_NO_RESIZE (1 << 2) #define WF_RELATIVE (1 << 3) -enum message_type { WM_NEW_CONTEXT = EVENT_MAX + 1, WM_REDRAW, WM_KEYBOARD }; +enum message_type { GFX_NEW_CONTEXT = EVENT_MAX + 1, GFX_REDRAW }; // Generalized font struct struct font { @@ -61,12 +61,6 @@ struct context { int flags; }; -struct msg_keyboard { - char ch; - int press; - int scancode; -}; - void gfx_write_char(struct context *ctx, int x, int y, u32 c, char ch); void gfx_write(struct context *ctx, int x, int y, u32 c, char *text); void gfx_load_image(struct context *ctx, char *path, int x, int y); @@ -86,7 +80,7 @@ int gfx_font_width(); */ #define gfx_new_ctx(ctx) \ - (msg_send(2, WM_NEW_CONTEXT, (ctx)), (struct context *)msg_receive_loop()->data) -#define gfx_redraw() (msg_send(2, WM_REDRAW, NULL)) // TODO: Partial redraw (optimization) + (msg_send(2, GFX_NEW_CONTEXT, (ctx)), (struct context *)msg_receive_loop()->data) +#define gfx_redraw() (msg_send(2, GFX_REDRAW, NULL)) // TODO: Partial redraw (optimization) #endif diff --git a/libgui/inc/gui.h b/libgui/inc/gui.h index ea1e40e..e7573f8 100644 --- a/libgui/inc/gui.h +++ b/libgui/inc/gui.h @@ -10,11 +10,14 @@ #define MAX_CHILDS 100 +// TODO: Improve event types (maybe as struct header) +enum window_event_type { GUI_KEYBOARD = 10, GUI_MOUSE, GUI_MAX }; enum element_type { GUI_TYPE_CONTAINER, GUI_TYPE_BUTTON, GUI_TYPE_TEXTBOX }; struct element_button { const char *text; u32 color; + void (*on_click)(); }; struct element_textbox { @@ -37,8 +40,23 @@ struct window { struct context *ctx; }; +struct gui_event_keyboard { + char ch; + int press; + int scancode; +}; + +struct gui_event_mouse { + int x; + int y; + int but1; + int but2; + int but3; +}; + struct element *gui_init(const char *title, u32 width, u32 height); -struct element *gui_add_button(struct element *container, int x, int y, u32 width, u32 height, - const char *text, u32 color); +void gui_event_loop(struct element *container); +struct element_button *gui_add_button(struct element *container, int x, int y, u32 width, + u32 height, const char *text, u32 color); #endif |