aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/window.c10
-rw-r--r--libgui/gui.c111
-rw-r--r--libgui/inc/gfx.h2
-rw-r--r--libgui/inc/gui.h36
4 files changed, 139 insertions, 20 deletions
diff --git a/apps/window.c b/apps/window.c
index a69b6db..9342009 100644
--- a/apps/window.c
+++ b/apps/window.c
@@ -19,11 +19,13 @@ int main()
struct element *root = gui_init("test", 600, 400);
struct element *container =
- gui_add_container(root, 100, 0, root->ctx->width / 2, root->ctx->height, COLOR_RED);
- struct element_button *button =
- gui_add_button(container, 10, 10, FONT_24, "Baum!", COLOR_WHITE, COLOR_BLACK)->data;
+ gui_add_container(root, 0, 0, root->ctx->width / 2, root->ctx->height, COLOR_RED);
+ struct element *button =
+ gui_add_button(container, 10, 10, FONT_24, "Button", COLOR_WHITE, COLOR_BLACK);
+ struct element *text_input =
+ gui_add_text_input(container, 10, 50, 200, FONT_24, COLOR_WHITE, COLOR_BLACK);
- button->on_click = on_click;
+ button->event.on_click = on_click;
gui_event_loop(root);
diff --git a/libgui/gui.c b/libgui/gui.c
index dcf8b1f..72de970 100644
--- a/libgui/gui.c
+++ b/libgui/gui.c
@@ -1,5 +1,6 @@
// MIT License, Copyright (c) 2020 Marvin Borner
// Mostly GFX function wrappers
+// TODO: Reduce code duplication
#include <def.h>
#include <gfx.h>
@@ -105,6 +106,20 @@ void gui_sync_button(struct element *elem)
gfx_write(elem->ctx, 0, 0, button->font_type, button->color_fg, button->text);
}
+void gui_sync_label(struct element *elem)
+{
+ struct element_label *label = elem->data;
+ gfx_fill(elem->ctx, label->color_bg);
+ gfx_write(elem->ctx, 0, 0, label->font_type, label->color_fg, label->text);
+}
+
+void gui_sync_text_input(struct element *elem)
+{
+ struct element_text_input *text_input = elem->data;
+ gfx_fill(elem->ctx, text_input->color_bg);
+ gfx_write(elem->ctx, 0, 0, text_input->font_type, text_input->color_fg, text_input->text);
+}
+
void gui_sync_container(struct element *elem)
{
struct element_container *container = elem->data;
@@ -115,11 +130,9 @@ void gui_sync_container(struct element *elem)
struct element *gui_add_button(struct element *container, int x, int y, enum font_type font_type,
char *text, u32 color_bg, u32 color_fg)
{
- if (!container || !container->childs)
+ if (!container || !container->childs || !gfx_resolve_font(font_type))
return NULL;
- gfx_resolve_font(font_type);
-
struct element *button = malloc(sizeof(*button));
button->type = GUI_TYPE_BUTTON;
button->window_id = container->window_id;
@@ -144,6 +157,65 @@ struct element *gui_add_button(struct element *container, int x, int y, enum fon
return button;
}
+struct element *gui_add_label(struct element *container, int x, int y, enum font_type font_type,
+ char *text, u32 color_bg, u32 color_fg)
+{
+ if (!container || !container->childs || !gfx_resolve_font(font_type))
+ return NULL;
+
+ struct element *label = malloc(sizeof(*label));
+ label->type = GUI_TYPE_LABEL;
+ label->window_id = container->window_id;
+ label->ctx = malloc(sizeof(*label->ctx));
+ label->ctx->x = x;
+ label->ctx->y = y;
+ label->ctx->width = strlen(text) * gfx_font_width(font_type);
+ label->ctx->height = gfx_font_height(font_type);
+ label->ctx->flags = WF_RELATIVE;
+ label->childs = list_new();
+ label->data = malloc(sizeof(struct element_label));
+ ((struct element_label *)label->data)->text = text;
+ ((struct element_label *)label->data)->color_fg = color_fg;
+ ((struct element_label *)label->data)->color_bg = color_bg;
+ ((struct element_label *)label->data)->font_type = font_type;
+
+ gfx_new_ctx(label->ctx);
+ list_add(container->childs, label);
+ gui_sync_label(label);
+ merge_elements(get_root(container->window_id));
+
+ return label;
+}
+
+struct element *gui_add_text_input(struct element *container, int x, int y, u32 width,
+ enum font_type font_type, u32 color_bg, u32 color_fg)
+{
+ if (!container || !container->childs || !gfx_resolve_font(font_type))
+ return NULL;
+
+ struct element *text_input = malloc(sizeof(*text_input));
+ text_input->type = GUI_TYPE_TEXT_INPUT;
+ text_input->window_id = container->window_id;
+ text_input->ctx = malloc(sizeof(*text_input->ctx));
+ text_input->ctx->x = x;
+ text_input->ctx->y = y;
+ text_input->ctx->width = width;
+ text_input->ctx->height = gfx_font_height(font_type);
+ text_input->ctx->flags = WF_RELATIVE;
+ text_input->childs = list_new();
+ text_input->data = malloc(sizeof(struct element_text_input));
+ ((struct element_text_input *)text_input->data)->color_fg = color_fg;
+ ((struct element_text_input *)text_input->data)->color_bg = color_bg;
+ ((struct element_text_input *)text_input->data)->font_type = font_type;
+
+ gfx_new_ctx(text_input->ctx);
+ list_add(container->childs, text_input);
+ gui_sync_text_input(text_input);
+ merge_elements(get_root(container->window_id));
+
+ return text_input;
+}
+
struct element *gui_add_container(struct element *container, int x, int y, u32 width, u32 height,
u32 color_bg)
{
@@ -172,12 +244,14 @@ struct element *gui_add_container(struct element *container, int x, int y, u32 w
return new_container;
}
+// TODO: Split into small functions
void gui_event_loop(struct element *container)
{
if (!container)
return;
struct message *msg;
+ struct element *focused = NULL;
while (1) {
if (!(msg = msg_receive())) {
yield();
@@ -187,15 +261,30 @@ void gui_event_loop(struct element *container)
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();
+ focused = element_at(container, event->x, event->y);
+ if (focused && focused->event.on_click && event->but1)
+ focused->event.on_click(event);
+ break;
+ }
+ case GUI_KEYBOARD: {
+ struct gui_event_keyboard *event = msg->data;
+
+ if (focused && focused->type == GUI_TYPE_TEXT_INPUT && event->press &&
+ event->ch) {
+ char *s = ((struct element_text_input *)focused->data)->text;
+ u32 l = strlen(s);
+ s[l] = event->ch;
+ s[l + 1] = '\0';
+ gui_sync_text_input(focused);
+ merge_elements(get_root(focused->window_id));
+ gfx_redraw();
}
+
+ if (focused && focused->event.on_key && event->ch) {
+ focused->event.on_key(event);
+ }
+
+ break;
}
}
}
diff --git a/libgui/inc/gfx.h b/libgui/inc/gfx.h
index 5010650..c8e5a29 100644
--- a/libgui/inc/gfx.h
+++ b/libgui/inc/gfx.h
@@ -13,6 +13,8 @@
#define GET_GREEN(color) ((color >> 8) & 0x000000FF)
#define GET_BLUE(color) ((color >> 0) & 0X000000FF)
+#define COLOR_TRANSPARENT 0x00000000
+#define COLOR_INVISIBLE 0x00000000
#define COLOR_BLACK 0xff0f0f0f
#define COLOR_RED 0xfff07f7f
#define COLOR_GREEN 0xff7ff088
diff --git a/libgui/inc/gui.h b/libgui/inc/gui.h
index b79db3a..3f74178 100644
--- a/libgui/inc/gui.h
+++ b/libgui/inc/gui.h
@@ -8,14 +8,28 @@
#include <gfx.h>
#include <list.h>
+// TODO: Remove limits
#define MAX_CHILDS 100
+#define MAX_INPUT_LENGTH 100
// TODO: Improve event types (maybe as struct header)
enum window_event_type { GUI_KEYBOARD = GFX_MAX + 1, GUI_MOUSE, GUI_MAX };
-enum element_type { GUI_TYPE_ROOT, GUI_TYPE_CONTAINER, GUI_TYPE_BUTTON, GUI_TYPE_TEXTBOX };
+enum element_type {
+ GUI_TYPE_ROOT,
+ GUI_TYPE_CONTAINER,
+ GUI_TYPE_BUTTON,
+ GUI_TYPE_LABEL,
+ GUI_TYPE_TEXT_INPUT
+};
enum container_flags { SPLIT };
+struct element_event {
+ void (*on_click)();
+ void (*on_key)();
+ void (*on_submit)();
+};
+
struct element_container {
u32 color_bg;
enum container_flags flags;
@@ -26,12 +40,19 @@ struct element_button {
u32 color_fg;
u32 color_bg;
enum font_type font_type;
- void (*on_click)();
};
-struct element_textbox {
- const char *text;
- u32 color;
+struct element_label {
+ char *text;
+ u32 color_fg;
+ u32 color_bg;
+ enum font_type font_type;
+};
+
+struct element_text_input {
+ char text[MAX_INPUT_LENGTH];
+ u32 color_fg;
+ u32 color_bg;
enum font_type font_type;
};
@@ -39,6 +60,7 @@ struct element {
enum element_type type;
u32 window_id;
struct context *ctx; // Coordinates are relative to container
+ struct element_event event;
struct list *childs;
void *data; // Who needs static types anyways :)
};
@@ -68,6 +90,10 @@ struct element *gui_init(const char *title, u32 width, u32 height);
void gui_event_loop(struct element *container);
struct element *gui_add_button(struct element *container, int x, int y, enum font_type font_type,
char *text, u32 color_bg, u32 color_fg);
+struct element *gui_add_label(struct element *container, int x, int y, enum font_type font_type,
+ char *text, u32 color_bg, u32 color_fg);
+struct element *gui_add_text_input(struct element *container, int x, int y, u32 width,
+ enum font_type font_type, u32 color_bg, u32 color_fg);
struct element *gui_add_container(struct element *container, int x, int y, u32 width, u32 height,
u32 color_bg);