From 205f7d49530e6c32ec0a09045d9cb45dcf9b1752 Mon Sep 17 00:00:00 2001 From: quou Date: Wed, 31 Jul 2024 22:12:48 +1000 Subject: GUI + map editor beginnings --- gui.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 gui.c (limited to 'gui.c') diff --git a/gui.c b/gui.c new file mode 100644 index 0000000..0fe1f69 --- /dev/null +++ b/gui.c @@ -0,0 +1,198 @@ +#include "gui.h" +#include "memory.h" +#include "plat.h" +#include "render.h" +#include "standard.h" + +void* gui_alloc(GUI* g, int size) { + GUI_El* e = arena_alloc(g->a, size); + if (g->prev) + g->prev->next = e; + if (!g->first) + g->first = e; + g->prev = e; + e->next = 0; + return e; +} + +void gui_begin(GUI* g, const App* app, Arena* a) { + g->a = a; + g->app = app; + g->pad = 2; + g->first = 0; + g->cursor[0] = 10; + g->cursor[1] = 10; +} + +void gui_get_layout(GUI* g, Rect* r) { + r->x = g->cursor[0]; + r->y = g->cursor[1]; + g->cursor[1] += r->h; +} + +int gui_text_width(const char* text, int len) { + (void)text; + return len * 10; +} + +int gui_text_height(void) { + return 10; +} + +int mouse_over(const App* app, const Rect* r) { + return + app->mx > r->x && + app->my > r->y && + app->mx < r->x + r->w && + app->my < r->y + r->h; +} + +Rect gui_viewport(GUI* g) { + Rect r = { 0 }; + r.w = g->app->w; + r.h = g->app->h; + return r; +} + +Rect gui_cut_left(Rect* a, int v) { + Rect r = * a; + a->x += v; + a->w -= v; + r.w -= a->w; + return r; +} + +Rect gui_cut_right(Rect* a, int v) { + Rect r = *a; + a->w -= v; + r.x += v; + r.w -= v; + return r; +} + +Rect gui_cut_down(Rect* a, int v) { + Rect r = *a; + a->h -= v; + r.y += v; + r.h -= v; + return r; +} + +Rect gui_cut_up(Rect* a, int v) { + Rect r = * a; + a->y += v; + a->h -= v; + r.h -= a->h; + return r; +} + +int gui_btn(GUI* g, Rect r, const char* text) { + int len = string_len(text); + GUI_Btn* e = gui_alloc(g, sizeof *e); + e->el.type = gui_el_type_btn; + e->el.r = r; + e->text = arena_alloc_aligned(g->a, len + 1, 1); + string_copy(e->text, text); + e->hover = mouse_over(g->app, &e->el.r); + e->active = e->hover && + g->app->mbtn_states[mbtn_left] & key_state_pressed; + return e->hover && + g->app->mbtn_states[mbtn_left] & key_state_just_released; +} + +void gui_scrollable( + GUI* g, + Rect r, + GUI_Scroll_State* state, + GUI_Scrollable_Draw_Fn fn +) { + GUI_Scrollable* e = gui_alloc(g, sizeof *e); + e->el.type = gui_el_type_scrollable; + e->el.r = r; + e->ss = state; + e->draw = fn; +} + +void rect_cfit(Rect* r) { + r->x++; + r->y++; + r->w -= 2; + r->h -= 2; +} + +void draw_container(Renderer* r, const Rect* rect, int active) { + const Colour bg = make_colour(0xc3c3c3, 0xff); + Colour out1 = make_colour(0xffffff, 0xff); + Colour out2 = make_colour(0x000000, 0xff); + Rect t = *rect; + if (active) { + Colour t = out1; + out1 = out2; + out2 = t; + } + ren_rect(r, bg, rect); + t.h = 1; + ren_rect(r, out1, &t); + t.w = 1; + t.h = rect->h; + ren_rect(r, out1, &t); + t.h--; + t.x += rect->w - 1; + t.y++; + ren_rect(r, out2, &t); + t.y = rect->y + rect->h - 1; + t.x = rect->x + 1; + t.w = rect->w - 1; + t.h = 1; + ren_rect(r, out2, &t); +} + +void draw_btn(GUI* g, Renderer* r, const GUI_Btn* btn) { + const Colour txt = make_colour(0x000000, 0xff); + int tp[2]; + Rect rect = btn->el.r; + (void)g; + tp[0] = + rect.x + rect.w / 2 - + gui_text_width(btn->text, string_len(btn->text)) / 2; + tp[1] = + rect.y + rect.h / 2 - + gui_text_height() / 2; + if (btn->active) { + tp[0]++; + tp[1]++; + } + draw_container(r, &rect, btn->active); + rect_cfit(&rect); + ren_clip(r, &rect); + ren_text(r, txt, tp[0], tp[1], btn->text); + ren_clipr(r); +} + +void draw_scrollable( + GUI* g, + Renderer* r, + const GUI_Scrollable* s +) { + Rect rect = s->el.r; + draw_container(r, &s->el.r, 0); + rect_cfit(&rect); + ren_clip(r, &rect); + s->draw(g, r, &rect, s->ss); + ren_clipr(r); +} + +void gui_end(GUI* g, Renderer* r) { + GUI_El* el = g->first; + while (el) { + switch (el->type) { + case gui_el_type_btn: + draw_btn(g, r, (GUI_Btn*)el); + break; + case gui_el_type_scrollable: + draw_scrollable(g, r, (GUI_Scrollable*)el); + break; + } + el = el->next; + } +} -- cgit v1.2.3-54-g00ecf