diff options
-rw-r--r-- | apps/chess/main.c | 6 | ||||
-rw-r--r-- | apps/paint/main.c | 12 | ||||
-rw-r--r-- | libs/libc/sys.c | 8 | ||||
-rw-r--r-- | libs/libgui/Makefile | 3 | ||||
-rw-r--r-- | libs/libgui/gfx.c | 10 | ||||
-rw-r--r-- | libs/libgui/gfx.h | 3 | ||||
-rw-r--r-- | libs/libgui/gui.c | 27 | ||||
-rw-r--r-- | libs/libgui/gui.h | 17 | ||||
-rw-r--r-- | libs/libgui/widgets.c | 29 | ||||
-rw-r--r-- | libs/libgui/widgets.h | 14 |
10 files changed, 94 insertions, 35 deletions
diff --git a/apps/chess/main.c b/apps/chess/main.c index 64911dc..fbb00e8 100644 --- a/apps/chess/main.c +++ b/apps/chess/main.c @@ -214,7 +214,7 @@ static void draw_board(void) { for (u8 x = 0; x < 8; x++) { for (u8 y = 0; y < 8; y++) { - u32 widget = gui_new_widget(win, GUI_MAIN, vec2(TILE * x, TILE * y), + u32 widget = gui_widget(win, GUI_MAIN, vec2(TILE * x, TILE * y), vec2(TILE, TILE)); assert((signed)widget > 0); @@ -225,7 +225,7 @@ static void draw_board(void) gui_fill(win, widget, GUI_LAYER_BG, colored ? DARK_COLOR : LIGHT_COLOR); struct piece *tile = &tiles[x][y]; - gui_listen_widget(win, widget, GUI_LISTEN_MOUSECLICK, (u32)mouseclick); + gui_widget_listen(win, widget, GUI_LISTEN_MOUSECLICK, (u32)mouseclick); tile->widget = widget; @@ -239,7 +239,7 @@ static void draw_board(void) int main(void) { - win = gui_new_custom_window(APPNAME, vec2(0, 0), vec2(TILE * 8, TILE * 8)); + win = gui_custom_window(APPNAME, vec2(0, 0), vec2(TILE * 8, TILE * 8)); fen_parse(START_FEN); draw_board(); diff --git a/apps/paint/main.c b/apps/paint/main.c index aed784c..0e90ee8 100644 --- a/apps/paint/main.c +++ b/apps/paint/main.c @@ -34,29 +34,29 @@ static void color_click(struct gui_event_mouse *event) // TODO: Fix and improve paint without KVM int main(void) { - u32 win = gui_new_window(APPNAME); + u32 win = gui_window(APPNAME); vec2 win_size = gui_window_size(win); - u32 toolbar = gui_new_widget(win, GUI_MAIN, vec2(0, 0), + u32 toolbar = gui_widget(win, GUI_MAIN, vec2(0, 0), vec2(win_size.x, COLOR_SIZE + 2 * TOOLBAR_MARGIN)); gui_fill(win, toolbar, GUI_LAYER_BG, COLOR_WHITE); u32 color_count = COUNT(colors); for (u32 i = 0; i < color_count; i++) { - u32 color = gui_new_widget(win, toolbar, + u32 color = gui_widget(win, toolbar, vec2(TOOLBAR_MARGIN + i * (COLOR_SIZE + TOOLBAR_MARGIN), TOOLBAR_MARGIN), vec2(COLOR_SIZE, COLOR_SIZE)); gui_fill(win, color, GUI_LAYER_FG, colors[i]); gui_draw_border(win, color, GUI_LAYER_FG, 2, COLOR_BLACK); - gui_listen_widget(win, color, GUI_LISTEN_MOUSECLICK, (u32)color_click); + gui_widget_listen(win, color, GUI_LISTEN_MOUSECLICK, (u32)color_click); } u32 canvas = - gui_new_widget(win, GUI_MAIN, vec2(0, COLOR_SIZE + 2 * TOOLBAR_MARGIN), + gui_widget(win, GUI_MAIN, vec2(0, COLOR_SIZE + 2 * TOOLBAR_MARGIN), vec2(win_size.x, win_size.y - (COLOR_SIZE + 2 * TOOLBAR_MARGIN))); gui_fill(win, canvas, GUI_LAYER_BG, COLOR_WHITE); - gui_listen_widget(win, canvas, GUI_LISTEN_MOUSEMOVE, (u32)mousemove); + gui_widget_listen(win, canvas, GUI_LISTEN_MOUSEMOVE, (u32)mousemove); gui_redraw_window(win); gui_loop(); diff --git a/libs/libc/sys.c b/libs/libc/sys.c index b00bd32..c6b7fa3 100644 --- a/libs/libc/sys.c +++ b/libs/libc/sys.c @@ -189,12 +189,20 @@ static void atexit_trigger(void) if (!slot) return; + static u8 cnt = 0; + if (cnt++ != 0) { + log("Couldn't execute all atexit routines\n"); + return; + } + while (slot-- > 0) { if (funcs[slot]) { funcs[slot](); funcs[slot] = NULL; } } + + cnt = 0; } void atexit(void (*func)(void)) diff --git a/libs/libgui/Makefile b/libs/libgui/Makefile index a8f3a62..3aa441a 100644 --- a/libs/libgui/Makefile +++ b/libs/libgui/Makefile @@ -4,7 +4,8 @@ COBJS = psf.o \ png.o \ gfx.o \ gui.o \ - msg.o + msg.o \ + widgets.o CFLAGS = $(CFLAGS_DEFAULT) -I$(LIBS) -I$(LIBS)/libc/inc/ -pie -fPIE -fPIC -DUSER diff --git a/libs/libgui/gfx.c b/libs/libgui/gfx.c index f16b8dd..913fe59 100644 --- a/libs/libgui/gfx.c +++ b/libs/libgui/gfx.c @@ -457,14 +457,8 @@ void gfx_fill(struct gfx_context *ctx, u32 c) gfx_draw_rectangle(ctx, vec2(0, 0), vec2(ctx->size.x, ctx->size.y), c); } -int gfx_font_height(enum font_type font_type) +vec2 gfx_font_size(enum font_type font_type) { struct gfx_font *font = gfx_resolve_font(font_type); - return font->size.y; -} - -int gfx_font_width(enum font_type font_type) -{ - struct gfx_font *font = gfx_resolve_font(font_type); - return font->size.x; + return font->size; } diff --git a/libs/libgui/gfx.h b/libs/libgui/gfx.h index cb89ff5..899bf4d 100644 --- a/libs/libgui/gfx.h +++ b/libs/libgui/gfx.h @@ -103,8 +103,7 @@ void gfx_write_char(struct gfx_context *ctx, vec2 pos, enum font_type font_type, void gfx_write(struct gfx_context *ctx, vec2 pos, enum font_type font_type, u32 c, const char *text) NONNULL; -int gfx_font_height(enum font_type); -int gfx_font_width(enum font_type); +vec2 gfx_font_size(enum font_type font_type); /** * Image loading diff --git a/libs/libgui/gui.c b/libs/libgui/gui.c index 1496239..d5538aa 100644 --- a/libs/libgui/gui.c +++ b/libs/libgui/gui.c @@ -15,6 +15,9 @@ struct gui_widget { struct gfx_context bg; struct list *children; + u32 margin; // Between sub-widgets + enum gui_layout layout; + struct { void (*mousemove)(struct gui_event_mouse *event); void (*mouseclick)(struct gui_event_mouse *event); @@ -388,7 +391,7 @@ static vec2 gui_offset_widget(struct gui_widget *parent, struct gui_widget *chil return offset; } -static struct gui_widget *gui_new_plain_widget(vec2 pos, vec2 size, u8 bpp) +static struct gui_widget *gui_new_plain_widget(vec2 pos, vec2 size, enum gui_layout layout, u8 bpp) { struct gui_widget *widget = zalloc(sizeof(*widget)); struct gfx_context bg; @@ -400,17 +403,19 @@ static struct gui_widget *gui_new_plain_widget(vec2 pos, vec2 size, u8 bpp) widget->bg = *gfx_new_ctx(&bg, size, bpp); widget->fg = *gfx_new_ctx(&fg, size, bpp); widget->children = list_new(); + widget->margin = 4; + widget->layout = layout; return widget; } -u32 gui_new_widget(u32 win_id, u32 widget_id, vec2 pos, vec2 size) +u32 gui_widget(u32 win_id, u32 widget_id, vec2 pos, vec2 size) { struct gui_widget *parent = gui_widget_by_id(win_id, widget_id); if (!parent) gui_error(ENOENT); - struct gui_widget *child = gui_new_plain_widget(pos, size, parent->bg.bpp); + struct gui_widget *child = gui_new_plain_widget(pos, size, GUI_HLAYOUT, parent->bg.bpp); list_add(parent->children, child); return child->id; @@ -451,7 +456,7 @@ static void gui_destroy_widgets(u32 win_id) list_destroy(win->widgets); } -void gui_listen_widget(u32 win_id, u32 widget_id, enum gui_listener listener, u32 func) +void gui_widget_listen(u32 win_id, u32 widget_id, enum gui_listener listener, u32 func) { if (!func) gui_error(EFAULT); @@ -489,11 +494,11 @@ void gui_popup(const char *text) { vec2 pos = vec2(200, 200); - u32 popup = gui_new_custom_window("Popup", pos, vec2(POPUP_WIDTH, POPUP_HEIGHT)); + u32 popup = gui_custom_window("Popup", pos, vec2(POPUP_WIDTH, POPUP_HEIGHT)); struct gui_window *win = gui_window_by_id(popup); gui_fill(popup, gui_main_widget_id(win), GUI_LAYER_BG, COLOR_WHITE); - u32 widget = gui_new_widget(popup, GUI_MAIN, vec2(0, 0), vec2(POPUP_WIDTH, 32)); + u32 widget = gui_widget(popup, GUI_MAIN, vec2(0, 0), vec2(POPUP_WIDTH, 32)); gui_fill(popup, widget, GUI_LAYER_BG, COLOR_WHITE); gui_write(popup, widget, GUI_LAYER_FG, vec2(0, 0), FONT_32, COLOR_BLACK, text); @@ -516,7 +521,7 @@ vec2 gui_window_size(u32 win_id) * Window manager interfaces */ -u32 gui_new_custom_window(const char *name, vec2 pos, vec2 size) +u32 gui_custom_window(const char *name, vec2 pos, vec2 size) { if (!windows) windows = list_new(); @@ -554,8 +559,8 @@ u32 gui_new_custom_window(const char *name, vec2 pos, vec2 size) win->widgets = list_new(); // Initialize GUI_MAIN widget - list_add(win->widgets, - gui_new_plain_widget(vec2(0, 0), win->ctx.size, win->ctx.bpp)); + list_add(win->widgets, gui_new_plain_widget(vec2(0, 0), win->ctx.size, GUI_HLAYOUT, + win->ctx.bpp)); return win->id; } @@ -563,9 +568,9 @@ u32 gui_new_custom_window(const char *name, vec2 pos, vec2 size) gui_error(EINVAL); } -u32 gui_new_window(const char *name) +u32 gui_window(const char *name) { - return gui_new_custom_window(name, vec2(0, 0), vec2(0, 0)); + return gui_custom_window(name, vec2(0, 0), vec2(0, 0)); } void gui_redraw_window_only(u32 id) diff --git a/libs/libgui/gui.h b/libs/libgui/gui.h index e148c45..37626cf 100644 --- a/libs/libgui/gui.h +++ b/libs/libgui/gui.h @@ -20,6 +20,12 @@ enum gui_layer { GUI_LAYER_FG, }; +enum gui_layout { + GUI_NO_LAYOUT, + GUI_VLAYOUT, // New widgets get positioned under previous widget + GUI_HLAYOUT, // New widgets get positioned right of previous widget +}; + struct gui_event_mouse { u32 win; u32 widget; @@ -32,12 +38,15 @@ struct gui_event_mouse { } but; }; +// Down here because of codependency stuff +#include <libgui/widgets.h> + /** * Window operations */ -u32 gui_new_custom_window(const char *name, vec2 pos, vec2 size); -u32 gui_new_window(const char *name); +u32 gui_custom_window(const char *name, vec2 pos, vec2 size); +u32 gui_window(const char *name); void gui_redraw_window(u32 id); void gui_redraw_window_only(u32 id); // Without widgets @@ -63,8 +72,8 @@ void gui_draw_line(u32 win_id, u32 widget_id, enum gui_layer layer, vec2 pos1, v * Widget operations */ -u32 gui_new_widget(u32 win_id, u32 widget_id, vec2 pos, vec2 size); -void gui_listen_widget(u32 win_id, u32 widget_id, enum gui_listener listener, u32 func); +u32 gui_widget(u32 win_id, u32 widget_id, vec2 pos, vec2 size); +void gui_widget_listen(u32 win_id, u32 widget_id, enum gui_listener listener, u32 func); void gui_redraw_widget(u32 win_id, u32 widget_id); void gui_popup(const char *text); diff --git a/libs/libgui/widgets.c b/libs/libgui/widgets.c new file mode 100644 index 0000000..d6e82cd --- /dev/null +++ b/libs/libgui/widgets.c @@ -0,0 +1,29 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#include <def.h> +#include <libgui/gui.h> +#include <libgui/widgets.h> + +#define TEXT_PAD 2 + +/** + * Button + */ + +void gui_button_custom(u32 window, u32 widget, vec2 pos, enum font_type font_type, u32 bg, u32 fg, + void (*click)(struct gui_event_mouse *event), const char *text) +{ + vec2 font_size = gfx_font_size(font_type); + vec2 size = vec2(font_size.x * strlen(text) + TEXT_PAD * 2, font_size.y + TEXT_PAD * 2); + u32 button = gui_widget(window, widget, pos, size); + gui_fill(window, button, GUI_LAYER_BG, bg); + gui_write(window, button, GUI_LAYER_FG, vec2(TEXT_PAD, TEXT_PAD), font_type, fg, text); + gui_widget_listen(window, button, GUI_LISTEN_MOUSECLICK, (u32)click); +} + +void gui_button(u32 window, u32 widget, void (*click)(struct gui_event_mouse *event), + const char *text) +{ + gui_button_custom(window, widget, vec2(0, 0), FONT_16, COLOR_WHITE, COLOR_BLACK, click, + text); +} diff --git a/libs/libgui/widgets.h b/libs/libgui/widgets.h new file mode 100644 index 0000000..64862f0 --- /dev/null +++ b/libs/libgui/widgets.h @@ -0,0 +1,14 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#ifndef WIDGETS_H +#define WIDGETS_H + +#include <libgui/gfx.h> +#include <libgui/gui.h> + +void gui_button_custom(u32 window, u32 widget, vec2 pos, enum font_type font_type, u32 bg, u32 fg, + void (*click)(struct gui_event_mouse *event), const char *text); +void gui_button(u32 window, u32 widget, void (*click)(struct gui_event_mouse *event), + const char *text); + +#endif |