diff options
author | quou <quou@disroot.org> | 2024-12-31 23:38:11 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-12-31 23:38:11 +1100 |
commit | 96b27fe9841e537614962e273ef9f0802365ea6d (patch) | |
tree | d1373862f700a83dd476555913b50c969159a836 | |
parent | ae7824be86ecc53752a3bee1038c0677ac203cf7 (diff) |
ui stuf and things hmm m mmm m シ
-rw-r--r-- | app.cpp | 4 | ||||
-rw-r--r-- | app.hpp | 3 | ||||
-rw-r--r-- | c2.cpp | 9 | ||||
-rw-r--r-- | debugger.cpp | 34 | ||||
-rw-r--r-- | qstd/Makefile | 2 | ||||
-rw-r--r-- | qstd/plat.c | 40 | ||||
-rw-r--r-- | qstd/plat.h | 5 | ||||
-rw-r--r-- | ui.cpp | 97 | ||||
-rw-r--r-- | ui.hpp | 5 |
9 files changed, 166 insertions, 33 deletions
@@ -515,6 +515,7 @@ int WinMain( #endif void App::init(const char* name) { + dt = 0.0f; internal = (App_Internal*)arena_alloc( arena, sizeof *internal @@ -536,6 +537,7 @@ void App::destroy() { void App::begin() { int j; + begin_t = get_time(); for (j = 0; j < key_count; j++) key_states[j] &= ~( key_state_just_pressed | key_state_just_released @@ -548,6 +550,8 @@ void App::begin() { } void App::end() { + end_t = get_time(); + dt = (float)((double)(end_t - begin_t) / 1000000000.0); internal->end(this); } @@ -4,6 +4,7 @@ #define app_memory_size (1024 * 1024 * 32) #include <new> +#include <stdint.h> struct Arena; @@ -102,11 +103,13 @@ struct App_Internal; struct App { Arena* arena; + float dt; int running, w, h; int mx, my; int scrollx, scrolly; unsigned char key_states[key_count]; unsigned char mbtn_states[mbtn_count]; + uint64_t begin_t, end_t; App_Internal* internal; template <typename T> @@ -9,6 +9,7 @@ extern "C" { } #include <string.h> #include <math.h> +#include <stdio.h> #define video_arena_size (1024 * 1024 * 16) #define asset_arena_size (1024 * 1024 * 4) @@ -138,6 +139,7 @@ extern "C" int entrypoint() { ui->layout(app->w, app->h); auto toolbar = ui->create_element<UI::Toolbar>(ui->root); register_debuggers(ui, toolbar); + auto fps_label = ui->create_element<UI::Label>(ui->root, ""); while (app->running) { Arena frame_arena; init_arena(&frame_arena, per_frame, per_frame_memory_size); @@ -145,6 +147,11 @@ extern "C" int entrypoint() { app->begin(); dev->begin_frame(); + if (frame % 10 == 0) { + char buf[32]; + sprintf(buf, "FPS: %g", 1.0f / app->dt); + fps_label->set_text(buf); + } ui->update(&frame_arena); { @@ -246,7 +253,7 @@ extern "C" int entrypoint() { ctx.debug_pop(); r += 10; - rot += 0.05f; + rot += 5.0f * app->dt; frame++; dev->present(); app->end(); diff --git a/debugger.cpp b/debugger.cpp index 6a71e15..6cda856 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -11,6 +11,14 @@ struct Vram_Debugger : UI::Modal { } }; +struct Device_Debugger : UI::Modal { + UI::Element* enable_btn; + + Device_Debugger(UI* ui, UI::Element* parent): + UI::Modal(ui, parent, "Device debugger") { + } +}; + void create_vram_debugger( UI* ui, UI::Element* parent, @@ -28,6 +36,23 @@ void create_vram_debugger( ui->create_element<UI::Label>(window->contents, "Hello, I'm the VRAM debugger!"); } +void create_device_debugger( + UI* ui, + UI::Element* parent, + UI::Element* button +) { + auto window = ui->create_element<Device_Debugger>(parent); + window->enable_btn = button; + window->handler = [](UI::Element* e, const UI::Message& m) { + if (m.type == UI::Message::Type::destroy) { + auto window = (Device_Debugger*)e; + window->enable_btn->enable(); + } + return 0; + }; + ui->create_element<UI::Label>(window->contents, "Hello, I'm the device debugger!"); +} + void register_debuggers(UI* ui, UI::Toolbar* toolbar) { auto btnvram = ui->create_element<UI::Button>(toolbar, "VRAM Debugger"); btnvram->handler = [](UI::Element* e, const UI::Message& m) { @@ -37,4 +62,13 @@ void register_debuggers(UI* ui, UI::Toolbar* toolbar) { } return 0; }; + auto btndevice = ui->create_element<UI::Button>(toolbar, "Device Debugger"); + btndevice->handler = [](UI::Element* e, const UI::Message& m) { + if (m.type == UI::Message::Type::click) { + e->disable(); + create_device_debugger(e->ui, e->ui->root, e); + } + return 0; + }; } + diff --git a/qstd/Makefile b/qstd/Makefile index c4b088b..7e3f0f1 100644 --- a/qstd/Makefile +++ b/qstd/Makefile @@ -2,7 +2,7 @@ target = libqstd.a includes = -I../qstd defines = -Dplat_x86 -Dplat_posix -Dallocation_default_alignment=8 -cflags = -std=c90 -pedantic -Wall -Wextra $(DEBUG_COMPILE_FLAG) $(includes) $(defines) +cflags = -std=gnu90 -pedantic -Wall -Wextra $(DEBUG_COMPILE_FLAG) $(includes) $(defines) lflags = $(DEBUG_LINK_FLAG) objects = plat.o memory.o str.o pack.o diff --git a/qstd/plat.c b/qstd/plat.c index 7f07b96..15e0265 100644 --- a/qstd/plat.c +++ b/qstd/plat.c @@ -1,15 +1,21 @@ #include "plat.h" #ifdef plat_posix +#ifndef _POSIX_SOURCE #define _POSIX_SOURCE +#endif +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif +#include <aio.h> #include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <sys/time.h> +#include <sys/types.h> #include <time.h> -#include <stdarg.h> -#include <stdio.h> extern int isatty(int); extern int fileno(FILE*); @@ -83,6 +89,34 @@ void pbreak(int code) { #endif } +static clockid_t global_clock; +static unsigned long global_freq; +static int time_init = 0; + +void init_timer(void) { + struct timespec ts; + global_clock = CLOCK_REALTIME; + global_freq = 1000000000; + time_init = 1; +#if defined(_POSIX_MONOTONIC_CLOCK) + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + global_clock = CLOCK_MONOTONIC; + } +#else + (void)ts; +#endif +} + +uint64_t get_time(void) { + struct timespec ts; + if (!time_init) + init_timer(); + clock_gettime(global_clock, &ts); + return + (uint64_t)ts.tv_sec * global_freq + + (uint64_t)ts.tv_nsec; +} + #endif #ifdef plat_win @@ -153,4 +187,4 @@ void pbreak(int code) { } -#endif
\ No newline at end of file +#endif diff --git a/qstd/plat.h b/qstd/plat.h index 27521fa..b3715a3 100644 --- a/qstd/plat.h +++ b/qstd/plat.h @@ -1,6 +1,8 @@ #ifndef plat_h #define plat_h +#include <stdint.h> + #ifdef assert #undef assert #endif @@ -29,4 +31,7 @@ void print_err(const char* fmt, ...); void print_war(const char* fmt, ...); void pbreak(int code); +uint64_t get_time(void); + + #endif @@ -644,7 +644,7 @@ UI::Element* UI::alloc_element(size_t size) { UI::Element::Element(UI* ui, Element* parent): ui(ui), - parent(parent), + parent(0), children(0), next(0), handler(0), @@ -723,6 +723,8 @@ void UI::Element::enable() { } void UI::Element::add_child(Element* ch) { + assert(ch->parent == 0); + assert(ch->next == 0); if (!children) children = ch; else { @@ -730,6 +732,7 @@ void UI::Element::add_child(Element* ch) { for (; child && child->next; child = child->next); child->next = ch; } + ch->parent = this; ui->layout_dirty = true; } @@ -743,6 +746,8 @@ void UI::Element::remove_child(Element* ch) { prev->next = ch->next; else children = ch->next; + ch->next = 0; + ch->parent = 0; } void UI::Element::message(const Message& msg) { @@ -760,8 +765,6 @@ UI::Rect UI::Container::layout(const Rect& avail) { Rect used = avail; used.w = used.h = 0; bound = avail; - clip = avail; - clip.clip(ui->area); for (child = children; child; child = child->next) { int h; Rect r = child->layout(area); @@ -772,7 +775,17 @@ UI::Rect UI::Container::layout(const Rect& avail) { used.h += h; } bound = used; - return used; + bound.clip(avail); + clip = bound; + clip.clip(ui->area); + if (clip.x == 0 && clip.y == 0 && clip.w == 300 && clip.h == 80) { + return bound; + } + return bound; +} + +void UI::Container::on_render() { + ui->mesh.set_clip(clip); } UI::Toolbar::Toolbar(UI* ui, Element* parent): @@ -801,12 +814,8 @@ UI::Rect UI::Toolbar::layout(const Rect& avail) { void UI::Toolbar::on_render() { ui->mesh.set_clip(clip); - ui->mesh.add_rect( - ui, - bound.x, - bound.y, - bound.w, - bound.h, + ui->draw_container( + bound, 0xa7a7a7 ); } @@ -837,19 +846,20 @@ UI::Rect UI::Button::layout(const Rect& avail) { void UI::Button::on_render() { Colour tc = 0x000000; + int toff[] = { 0, 0 }; if (flags & Flags::disabled) tc = 0x4f4f4f; - if (this == ui->hovered) - ui->draw_container(bound, 0xf0f8ff); - else if (this == ui->hot) + if (this == ui->hot) { + toff[0] = 1; + toff[1] = 1; ui->draw_containeri(bound, 0xffffff); - else + } else ui->draw_container(bound, 0xffffff); ui->mesh.set_clip(clip); ui->mesh.add_text( ui, - bound.x + ui_padding, - bound.y + ui_padding, + bound.x + ui_padding + toff[0], + bound.y + ui_padding + toff[1], text, tc ); @@ -890,30 +900,43 @@ void UI::Label::on_render() { ); } -static int drag_handler(UI::Modal* modal, const UI::Message& msg) { - if (msg.type == UI::Message::Type::activate) { - const App& app = *modal->ui->app; - const UI::Rect& tb = modal->title_bar->bound; - modal->dragging = true; - modal->drag_offset[0] = app.mx - tb.x; - modal->drag_offset[1] = app.my - tb.y; +void UI::Label::set_text(const char* s) { + heap_free(ui->heap, text); + text = dup_stringh(ui->heap, s); + ui->layout_dirty = 1; +} + +static int title_handler(UI::Modal* modal, const UI::Message& msg) { + switch (msg.type) { + case UI::Message::Type::activate: { + const App& app = *modal->ui->app; + const UI::Rect& tb = modal->title_bar->bound; + modal->dragging = true; + modal->drag_offset[0] = app.mx - tb.x; + modal->drag_offset[1] = app.my - tb.y; + modal->bring_to_front(); + } break; + case UI::Message::Type::deactivate: + modal->dragging = false; + break; + default: return 0; } - if (msg.type == UI::Message::Type::deactivate) - modal->dragging = false; return 0; }; UI::Modal::Modal(UI* ui, Element* parent, const char* text): Element(ui, parent), dragging(false) { + pos[0] = 0; + pos[1] = 0; contents = ui->create_element<Container>(this); title_bar = ui->create_element<Toolbar>(contents); title_bar->handler = [](Element* e, const Message& m) { - return drag_handler((Modal*)e->parent->parent, m); + return title_handler((Modal*)e->parent->parent, m); }; close = ui->create_element<Button>(title_bar, "x"); title = ui->create_element<Label>(title_bar, text); title->handler = [](Element* e, const Message& m) { - return drag_handler((Modal*)e->parent->parent->parent, m); + return title_handler((Modal*)e->parent->parent->parent, m); }; close->handler = [](Element* e, const Message& m) { if (m.type == Message::Type::click) @@ -923,15 +946,25 @@ UI::Modal::Modal(UI* ui, Element* parent, const char* text): } UI::Rect UI::Modal::layout(const Rect& avail) { - UI::Rect content_size = contents->layout(avail); + Rect r = avail; + if (pos[0] && pos[1]) { + r.x = pos[0]; + r.y = pos[1]; + } + UI::Rect content_size = contents->layout(r); title_bar->layout(content_size); bound = content_size; clip = content_size; clip.clip(ui->area); + if (!pos[0] && !pos[1]) { + pos[0] = bound.x; + pos[1] = bound.y; + } return content_size; } void UI::Modal::on_render() { + ui->mesh.set_clip(clip); ui->draw_container( contents->bound, Colour(0xffffff, 0x80) @@ -944,6 +977,14 @@ void UI::Modal::on_update() { Rect avail = bound; avail.x = app.mx - drag_offset[0]; avail.y = app.my - drag_offset[1]; + pos[0] = avail.x; + pos[1] = avail.y; layout(avail); } } + +void UI::Modal::bring_to_front() { + Element* p = parent; + p->remove_child(this); + p->add_child(this); +} @@ -194,6 +194,7 @@ struct UI { Container(UI* ui, Element* parent); Rect layout(const Rect& avail) override; + void on_render() override; }; struct Toolbar : Element { @@ -217,6 +218,8 @@ struct UI { ~Label(); Rect layout(const Rect& avail) override; void on_render() override; + + void set_text(const char* s); }; struct Modal : Element { @@ -225,11 +228,13 @@ struct UI { Label* title; Button* close; int drag_offset[2]; + int pos[2]; bool dragging; Modal(UI* ui, Element* parent, const char* title); Rect layout(const Rect& avail) override; void on_render() override; void on_update() override; + void bring_to_front(); }; }; |