aboutsummaryrefslogtreecommitdiff
path: root/libgui
diff options
context:
space:
mode:
authorMarvin Borner2020-10-25 13:20:35 +0100
committerMarvin Borner2020-10-25 13:20:35 +0100
commitc9f89174b9ce73ed93bfad14d57b8f1a43db6bf6 (patch)
tree8a9fc5d2b7ac66b42b15521c421573db520d7d6b /libgui
parentf83d5e4b8e315f2b17f0c8bf390bf967f02f5837 (diff)
Added gui event loop and onclick listener
Diffstat (limited to 'libgui')
-rw-r--r--libgui/gui.c61
-rw-r--r--libgui/inc/gfx.h12
-rw-r--r--libgui/inc/gui.h22
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