diff --git a/build_file.c b/build_file.c index 02585ab..cea9902 100644 --- a/build_file.c +++ b/build_file.c @@ -1,3 +1,4 @@ +// don't ever include stuff that build_file will generate code for! #include "src/core/core_inc.h" #include "src/core/core_inc.c" diff --git a/src/app/app.gen.c b/src/app/app.gen.c index c20c63b..c49abe3 100644 --- a/src/app/app.gen.c +++ b/src/app/app.gen.c @@ -260,22 +260,25 @@ type_t type__app_event_t = { type_kind_struct, s8_const_lit("app_event_t"), size {.name = s8_const_lit("mouse_button"), .type = &type__app_mouse_button_t, .offset = offsetof(app_event_t, mouse_button), .dont_serialize = 0}, {.name = s8_const_lit("key"), .type = &type__app_key_t, .offset = offsetof(app_event_t, key), .dont_serialize = 0}, {.name = s8_const_lit("text"), .type = &type__s8_t, .offset = offsetof(app_event_t, text), .dont_serialize = 0}, - {.name = s8_const_lit("mouse_wheel_delta"), .type = &type__v3f64_t, .offset = offsetof(app_event_t, mouse_wheel_delta), .dont_serialize = 0}, + {.name = s8_const_lit("mouse_wheel_delta"), .type = &type__v3f32_t, .offset = offsetof(app_event_t, mouse_wheel_delta), .dont_serialize = 0}, + {.name = s8_const_lit("mouse_pos"), .type = &type__v2f32_t, .offset = offsetof(app_event_t, mouse_pos), .dont_serialize = 0}, {.name = s8_const_lit("ctrl"), .type = &type__b8, .offset = offsetof(app_event_t, ctrl), .dont_serialize = 0}, {.name = s8_const_lit("shift"), .type = &type__b8, .offset = offsetof(app_event_t, shift), .dont_serialize = 0}, {.name = s8_const_lit("alt"), .type = &type__b8, .offset = offsetof(app_event_t, alt), .dont_serialize = 0}, - {.name = s8_const_lit("meta"), .type = &type__b8, .offset = offsetof(app_event_t, meta), .dont_serialize = 0}, - {.name = s8_const_lit("dpr"), .type = &type__f64, .offset = offsetof(app_event_t, dpr), .dont_serialize = 0}, - {.name = s8_const_lit("window_size"), .type = &type__v2f64_t, .offset = offsetof(app_event_t, window_size), .dont_serialize = 0}, - {.name = s8_const_lit("mouse_pos"), .type = &type__v2f64_t, .offset = offsetof(app_event_t, mouse_pos), .dont_serialize = 0}, }, - .count = 13, + .count = 10, }; -type_t type__app_event_list_t = { type_kind_struct, s8_const_lit("app_event_list_t"), sizeof(app_event_list_t), +type_t type__app_frame_t = { type_kind_struct, s8_const_lit("app_frame_t"), sizeof(app_frame_t), .members = (type_member_t[]){ - {.name = s8_const_lit("first"), .type = &(type_t){type_kind_pointer, s8_const_lit("app_event_t*"), sizeof(void *), .base = &type__app_event_t}, .offset = offsetof(app_event_list_t, first), .dont_serialize = 1}, - {.name = s8_const_lit("last"), .type = &(type_t){type_kind_pointer, s8_const_lit("app_event_t*"), sizeof(void *), .base = &type__app_event_t}, .offset = offsetof(app_event_list_t, last), .dont_serialize = 0}, - {.name = s8_const_lit("len"), .type = &type__i32, .offset = offsetof(app_event_list_t, len), .dont_serialize = 0}, + {.name = s8_const_lit("next"), .type = &(type_t){type_kind_pointer, s8_const_lit("app_frame_t*"), sizeof(void *), .base = &type__app_frame_t}, .offset = offsetof(app_frame_t, next), .dont_serialize = 0}, + {.name = s8_const_lit("delta"), .type = &type__f64, .offset = offsetof(app_frame_t, delta), .dont_serialize = 0}, + {.name = s8_const_lit("dpr"), .type = &type__f32, .offset = offsetof(app_frame_t, dpr), .dont_serialize = 0}, + {.name = s8_const_lit("window_size"), .type = &type__v2f32_t, .offset = offsetof(app_frame_t, window_size), .dont_serialize = 0}, + {.name = s8_const_lit("mouse_pos"), .type = &type__v2f32_t, .offset = offsetof(app_frame_t, mouse_pos), .dont_serialize = 0}, + {.name = s8_const_lit("event_count"), .type = &type__i32, .offset = offsetof(app_frame_t, event_count), .dont_serialize = 0}, + {.name = s8_const_lit("first_event"), .type = &(type_t){type_kind_pointer, s8_const_lit("app_event_t*"), sizeof(void *), .base = &type__app_event_t}, .offset = offsetof(app_frame_t, first_event), .dont_serialize = 0}, + {.name = s8_const_lit("last_event"), .type = &(type_t){type_kind_pointer, s8_const_lit("app_event_t*"), sizeof(void *), .base = &type__app_event_t}, .offset = offsetof(app_frame_t, last_event), .dont_serialize = 0}, + {.name = s8_const_lit("update"), .type = &type__f64, .offset = offsetof(app_frame_t, update), .dont_serialize = 0}, }, - .count = 3, + .count = 9, }; \ No newline at end of file diff --git a/src/app/app.gen.h b/src/app/app.gen.h index 6920818..9b59de1 100644 --- a/src/app/app.gen.h +++ b/src/app/app.gen.h @@ -98,19 +98,22 @@ struct app_event_t { app_mouse_button_t mouse_button; app_key_t key; s8_t text; - v3f64_t mouse_wheel_delta; + v3f32_t mouse_wheel_delta; + v2f32_t mouse_pos; b8 ctrl; b8 shift; b8 alt; - b8 meta; - f64 dpr; - v2f64_t window_size; - v2f64_t mouse_pos; }; -typedef struct app_event_list_t app_event_list_t; -struct app_event_list_t { - app_event_t* first; - app_event_t* last; - i32 len; +typedef struct app_frame_t app_frame_t; +struct app_frame_t { + app_frame_t* next; + f64 delta; + f32 dpr; + v2f32_t window_size; + v2f32_t mouse_pos; + i32 event_count; + app_event_t* first_event; + app_event_t* last_event; + f64 update; }; \ No newline at end of file diff --git a/src/app/app.meta.c b/src/app/app.meta.c index 68d27cd..fc0e0ee 100644 --- a/src/app/app.meta.c +++ b/src/app/app.meta.c @@ -166,32 +166,28 @@ void meta_app(ma_arena_t *arena) { app_mouse_button_t mouse_button; // @mouse_down @mouse_up app_key_t key; // @key_down @key_up s8_t text; // @text - - // @todo: test why xyz in js???????????? - v3f64_t mouse_wheel_delta; // @mouse_wheel + v3f32_t mouse_wheel_delta; // @mouse_wheel + v2f32_t mouse_pos; // @mouse_move // always present data b8 ctrl; b8 shift; b8 alt; - b8 meta; - - f64 dpr; - v2f64_t window_size; - v2f64_t mouse_pos; }; - struct app_event_list_t { - app_event_t *first; @dont_serialize - app_event_t *last; - i32 len; - }; + struct app_frame_t { + app_frame_t *next; + f64 delta; + f32 dpr; + v2f32_t window_size; + v2f32_t mouse_pos; - // struct app_frame_t { - // f64 delta; - // f64 time; - // app_event_list_t event_list; - // }; + i32 event_count; + app_event_t *first_event; + app_event_t *last_event; + + f64 update; + }; )); sb8_serial_ast_to_code(h, decls); diff --git a/src/app/app_win32.c b/src/app/app_win32.c index 7f3c041..656da10 100644 --- a/src/app/app_win32.c +++ b/src/app/app_win32.c @@ -8,7 +8,7 @@ #pragma comment(lib, "winmm.lib") fn void app_init(void); -fn b32 app_update(app_event_list_t events); +fn b32 app_update(app_frame_t *frame); gb b32 w32_good_scheduling; gb WNDCLASSW w32_wc; @@ -16,27 +16,27 @@ gb HWND w32_window_handle; gb HDC w32_dc; gb b32 w32_quit_app; -fn v2f64_t w32_get_window_size(HWND window) { +fn v2f32_t w32_get_window_size(HWND window) { RECT window_rect; GetClientRect(window, &window_rect); - f64 x = window_rect.right - window_rect.left; - f64 y = window_rect.bottom - window_rect.top; - return (v2f64_t){x, y}; + f32 x = (f32)(window_rect.right - window_rect.left); + f32 y = (f32)(window_rect.bottom - window_rect.top); + return (v2f32_t){x, y}; } -fn v2f64_t w32_get_mouse_pos(HWND window) { +fn v2f32_t w32_get_mouse_pos(HWND window) { POINT p; GetCursorPos(&p); ScreenToClient(window, &p); - return (v2f64_t){p.x, p.y}; + return (v2f32_t){(f32)p.x, (f32)p.y}; } -fn f64 w32_get_dpr(HWND window_handle) { +fn f32 w32_get_dpr(HWND window_handle) { UINT dpi = GetDpiForWindow(window_handle); if (dpi == 0) { return 1.0; } - f64 result = (f64)dpi / 96.0; + f32 result = (f32)dpi / 96.0f; return result; } @@ -57,22 +57,19 @@ fn f64 w32_seconds_now(void) { /////////////////////////////// // event processing -gb app_event_list_t w32_event_list; +gb app_frame_t *w32_frame; gb ma_arena_t *w32_event_arena; -fn void w32_push_event(app_event_t event) { +fn void w32_push_event(app_frame_t *frame, app_event_t event) { app_event_t *ev = ma_push_type(w32_event_arena, app_event_t); *ev = event; if (GetKeyState(VK_CONTROL) & 0x8000) ev->ctrl = true; if (GetKeyState(VK_SHIFT) & 0x8000) ev->shift = true; if (GetKeyState(VK_MENU) & 0x8000) ev->alt = true; - ev->window_size = w32_get_window_size(w32_window_handle); - ev->mouse_pos = w32_get_mouse_pos(w32_window_handle); - ev->dpr = w32_get_dpr(w32_window_handle); - SLLQ_APPEND(w32_event_list.first, w32_event_list.last, ev); - w32_event_list.len += 1; + SLLQ_APPEND(frame->first_event, frame->last_event, ev); + frame->event_count += 1; } fn void w32_push_wm_char_event(WPARAM wparam) { @@ -88,7 +85,7 @@ fn void w32_push_wm_char_event(WPARAM wparam) { } } - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_text, .text = string, }); @@ -101,13 +98,13 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp } break; case WM_KEYDOWN: { - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_key_down, .key = w32_map_wparam_to_app_key(wparam) }); } break; case WM_KEYUP: { - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_key_up, .key = w32_map_wparam_to_app_key(wparam) }); @@ -116,14 +113,14 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp case WM_LBUTTONDOWN: { SetCapture(wnd); - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_down, .mouse_button = app_mouse_button_left, }); } break; case WM_LBUTTONUP: { ReleaseCapture(); - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_up, .mouse_button = app_mouse_button_left, }); @@ -131,13 +128,13 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp case WM_RBUTTONDOWN: { - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_down, .mouse_button = app_mouse_button_right, }); } break; case WM_RBUTTONUP: { - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_up, .mouse_button = app_mouse_button_right, }); @@ -146,14 +143,14 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp case WM_MBUTTONDOWN: { SetCapture(wnd); - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_down, .mouse_button = app_mouse_button_middle, }); } break; case WM_MBUTTONUP: { ReleaseCapture(); - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_up, .mouse_button = app_mouse_button_middle, }); @@ -161,9 +158,9 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp case WM_MOUSEWHEEL: { int zDelta = GET_WHEEL_DELTA_WPARAM(wparam); - w32_push_event((app_event_t){ + w32_push_event(w32_frame, (app_event_t){ .kind = app_event_kind_mouse_wheel, - .mouse_wheel_delta = (v3f64_t){0, zDelta}, + .mouse_wheel_delta = (v3f32_t){0, (f32)zDelta}, }); } break; @@ -179,15 +176,15 @@ fn LRESULT CALLBACK w32_window_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lp return 0; } -app_event_list_t w32_get_events(ma_arena_t *arena, b32 wait, b32 *waited) { +b32 w32_get_events(ma_arena_t *arena, app_frame_t *frame, b32 wait) { w32_event_arena = arena; - zero_struct(&w32_event_list); - *waited = false; + w32_frame = frame; + b32 waited = false; MSG msg; if (wait) { if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE) == 0) { - *waited = true; + waited = true; } GetMessageW(&msg, NULL, 0, 0); @@ -200,7 +197,7 @@ app_event_list_t w32_get_events(ma_arena_t *arena, b32 wait, b32 *waited) { DispatchMessageW(&msg); } - return w32_event_list; + return waited; } /////////////////////////////// @@ -212,11 +209,11 @@ struct w32_canvas_t { HWND window_handle; HBITMAP dib; HDC dib_dc; - v2f64_t window_size; + v2f32_t window_size; }; w32_canvas_t w32_create_canvas(HWND window_handle) { - v2f64_t window_size = w32_get_window_size(window_handle); + v2f32_t window_size = w32_get_window_size(window_handle); w32_canvas_t result = {.window_handle = window_handle, .window_size = window_size}; HDC window_dc = GetDC(window_handle); BITMAPINFO bminfo = {0}; @@ -252,7 +249,7 @@ void w32_present_canvas(w32_canvas_t *canvas) { } void w32_try_resizing_canvas(w32_canvas_t *canvas, HWND window_handle) { - v2f64_t window_size = w32_get_window_size(window_handle); + v2f32_t window_size = w32_get_window_size(window_handle); if (canvas->window_size.x != window_size.x || canvas->window_size.y != window_size.y) { w32_destroy_canvas(canvas); *canvas = w32_create_canvas(window_handle); @@ -354,32 +351,36 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n f64 time_frame_start = w32_seconds_now(); f64 time_delta = 1.0 / refresh_rate; - f64 time_total = 0.0; f64 time_update = 0.0; b32 wait_for_events = false; u64 consecutive_missed_frames = 0; u64 missed_frames = 0; - u64 frame = 0; + u64 frame_counter = 0; for (;;) { - b32 waited_for_events = false; - app_event_list_t event_list = w32_get_events(tcx.temp, wait_for_events, &waited_for_events); - if (waited_for_events) { - // delta_time = 0.0001 + app_frame_t frame = {0}; + frame.window_size = w32_get_window_size(w32_window_handle); + frame.dpr = w32_get_dpr(w32_window_handle); + frame.mouse_pos = w32_get_mouse_pos(w32_window_handle); + frame.delta = time_delta; + frame.update = time_update; + + b32 waited = w32_get_events(tcx.temp, &frame, wait_for_events); + if (waited) { + frame.delta = 0.00001; } - for (app_event_t *ev = event_list.first; ev; ev = ev->next) { + for (app_event_t *ev = frame.first_event; ev; ev = ev->next) { if (ev->kind == app_event_kind_key_down && ev->key == app_key_escape) { ExitProcess(0); } } - if (event_list.len == 0) { - w32_push_event((app_event_t){.kind = app_event_kind_update}); - event_list = w32_event_list; + if (frame.event_count == 0) { + w32_push_event(&frame, (app_event_t){.kind = app_event_kind_update}); } - b32 animating = app_update(event_list); + b32 animating = app_update(&frame); wait_for_events = !animating; SwapBuffers(w32_dc); @@ -417,13 +418,12 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n consecutive_missed_frames += 1; } - frame += 1; + frame_counter += 1; // @todo: // should this be time_delta or time_update ???? // probably want the locked frame rate and total should reflect that, so choosing // time_delta seems the correct choice but not really sure what is correct. - time_total += time_delta; time_frame_start = w32_seconds_now(); } diff --git a/src/render/render_opengl.c b/src/render/render_opengl.c index 0e21e97..53bb4f7 100644 --- a/src/render/render_opengl.c +++ b/src/render/render_opengl.c @@ -181,12 +181,17 @@ v2f32_t rn_draw_string(rn_font_t *font, v2f32_t pos, v4f32_t color, s8_t string) return rn_base_draw_string(font, string, pos, color, true); } +v2f32_t rn_draw_stringf(rn_font_t *font, v2f32_t pos, v4f32_t color, char *str, ...) { + S8_FMT(tcx.temp, str, result); + return rn_draw_string(font, pos, color, result); +} + v2f32_t rn_measure_string(rn_font_t *font, s8_t string) { return rn_base_draw_string(font, string, v2f32(0,0), v4f32(0,0,0,0), false); } void rn_init(ma_arena_t *perm) { - rn_state.cap = 1024*64; + rn_state.cap = 1024*256; rn_state.vertices = ma_push_array(perm, rn_vertex_t, rn_state.cap); { @@ -194,11 +199,11 @@ void rn_init(ma_arena_t *perm) { s8_t font_data = rn_get_default_font(tcx.temp); rn_atlas_t *atlas = rn_create_atlas(scratch.arena, (v2i32_t){2048, 2048}); - u32 font_size = 100; + u32 font_size = 50; rn_state.main_font = rn_create_font(perm, font_data, atlas, font_size); GLint filter = GL_NEAREST; - // if (StyleFontFilter == 1) filter = GL_LINEAR; + // filter = GL_LINEAR; glCreateTextures(GL_TEXTURE_2D, 1, &atlas->texture_id); glTextureParameteri(atlas->texture_id, GL_TEXTURE_MIN_FILTER, filter); glTextureParameteri(atlas->texture_id, GL_TEXTURE_MAG_FILTER, filter); diff --git a/src/wasm_app/main.c b/src/wasm_app/main.c index 0ebf5cd..f45fbd0 100644 --- a/src/wasm_app/main.c +++ b/src/wasm_app/main.c @@ -9,7 +9,7 @@ #include "render/backup_font.c" #include "render/font.c" #include "render/render_opengl.c" -// #include "gfx2d/gfx2d.c" +// #include "gfx2d/gfx2d.c"dv #include "ui.c" @@ -32,8 +32,6 @@ gb globals_t *globals; fn void app_init(void) { - ui_test_iterators(); - ma_arena_t *perm = &tcx._perm; globals = ma_push_type(perm, globals_t); // globals->gfx = ma_push_type(perm, gfx_t); @@ -41,65 +39,53 @@ fn void app_init(void) { ui_init(perm); } -fn b32 app_update(app_event_list_t events) { +fn b32 app_update(app_frame_t *frame) { ui_begin_frame(); defer_block(ui_begin_build(), ui_end_build()) { - defer_block(ui_push_expander("app_event_t"), ui_pop_parent()) { - defer_block(ui_push_expander("mouse_wheel_delta: v3f64_t"), ui_pop_parent()) { - ui_label("x: f64 = value"); - ui_label("y: f64 = value"); - ui_label("z: f64 = value"); - } - ui_label("kind: app_event_kind_t = value"); - ui_label("ctrl: b8 = value"); - ui_label("shift: b8 = value"); - defer_block(ui_push_expander("pos: v2f64_t"), ui_pop_parent()) { - defer_block(ui_push_expander("inner_pos: v2f64_t"), ui_pop_parent()) { + defer_block(ui_push_list_container(), ui_pop_parent()) { + if (ui_push_expander("app_event_t")) { + if (ui_push_expander("mouse_wheel_delta: v3f64_t")) { ui_label("x: f64 = value"); ui_label("y: f64 = value"); + ui_label("z: f64 = value"); + ui_pop_expander(); } - ui_label("y: f64 = value"); - defer_block(ui_push_expander("inner_pos: v2f64_t"), ui_pop_parent()) { - ui_label("x: f64 = value"); + ui_label("kind: app_event_kind_t = value"); + ui_label("ctrl: b8 = value"); + ui_label("shift: b8 = value"); + if (ui_push_expander("pos: v2f64_t")) { + if (ui_push_expander("inner_pos: v2f64_t")) { + ui_label("x: f64 = value"); + ui_label("y: f64 = value"); + ui_pop_expander(); + } ui_label("y: f64 = value"); + if (ui_push_expander("inner_pos: v2f64_t")) { + ui_label("x: f64 = value"); + ui_label("y: f64 = value"); + ui_pop_expander(); + } + ui_pop_expander(); } + ui_label("alt: b8 = value"); + ui_label("meta: b8 = value"); + ui_pop_expander(); } - ui_label("alt: b8 = value"); - ui_label("meta: b8 = value"); } } - for (app_event_t *ev = events.first; ev; ev = ev->next) { + for (app_event_t *ev = frame->first_event; ev; ev = ev->next) { if (globals->event.kind == app_event_kind_null) { globals->event = *ev; } - - #if 0 - // ui_struct() - type_t *ti = type(app_event_t); - - ui_push_list("▼ %S: struct", ti->name); - for (type_member_t *tm = ti->members; tm < ti->members + ti->count; tm += 1) { - if (tm->kind == type_kind_struct) { - ui_list_struct(tm->type, ti_get_member_offset(tm, p) - } else { - ui_list_item("%-20S: %S = %S", tm->name, ti_serial_type(tcx.temp, tm->type), ti_serial_data(p, type)); - } - } - ui_pop_list(); - - #endif - } - { - app_event_t *ev = events.last; - rn_begin(); - rn_draw_string(&rn_state.main_font, v2f32(0,0), black_color_global, s8_lit("hello world!")); - rn_end(v2f64_to_v2f32(ev->window_size), white_color_global); + rn_begin(); + rn_draw_stringf(&rn_state.main_font, v2f32(0,0), black_color_global, "delta: %f update: %f", frame->delta, frame->update); - } + ui_draw(); + rn_end(frame->window_size, white_color_global); #if 0 // These steps should be totally optional!! @@ -138,5 +124,5 @@ fn b32 app_update(app_event_list_t events) { #endif ui_end_frame(); - return false; + return true; } diff --git a/src/wasm_app/ui.c b/src/wasm_app/ui.c index e993b30..b338055 100644 --- a/src/wasm_app/ui.c +++ b/src/wasm_app/ui.c @@ -20,8 +20,8 @@ typedef enum { typedef struct ui_size_t ui_size_t; struct ui_size_t { ui_size_kind_t kind; - f64 value; - f64 strictness; + f32 value; + f32 strictness; }; typedef struct ui_box_t ui_box_t; @@ -36,11 +36,13 @@ struct ui_box_t { ui_box_t *last; s8_t string; ui_size_t semantic_size[ui_axis2_count]; + b32 grow_axis[ui_axis2_count]; // computed by layout system - f64 computed_rel_pos[ui_axis2_count]; - f64 computed_size[ui_axis2_count]; - r2f64_t rect; + f32 iter_pos[ui_axis2_count]; + f32 computed_rel_pos[ui_axis2_count]; + f32 computed_size[ui_axis2_count]; + r2f32_t rect; }; typedef struct ui_t ui_t; @@ -114,17 +116,50 @@ ui_box_t *ui_pop_parent(void) { return top; } -ui_box_t *ui_push_expander(char *fmt, ...) { - S8_FMT(tcx.temp, fmt, string); - ui_id_t id = ui_id_from_string(string); +ui_box_t *ui_spacer(char *spacing_char) { + ui_id_t id = ui_null_id; + ui_box_t *box = ui_alloc_box(id); + ui_push_box(box); + v2f32_t spacing = rn_measure_string(&rn_state.main_font, s8_from_char(spacing_char)); + box->semantic_size[0] = (ui_size_t){ui_size_kind_pixels, spacing.x, 0.5}; + box->semantic_size[1] = (ui_size_t){ui_size_kind_pixels, 10, 0.5}; + return box; +} + +ui_box_t *ui_push_list_container(void) { + ui_id_t id = ui_null_id; ui_box_t *box = ui_alloc_box(id); ui_push_parent(box); + box->semantic_size[0] = (ui_size_t){ui_size_kind_children_sum, 0, 0.5}; + box->semantic_size[1] = (ui_size_t){ui_size_kind_children_sum, 0, 0.5}; + box->grow_axis[1] = true; + return box; +} + +ui_box_t *ui_push_expander(char *str, ...) { + S8_FMT(tcx.temp, str, string); + ui_id_t id = ui_id_from_string(string); + ui_box_t *box = ui_alloc_box(id); + ui_push_box(box); box->string = string; box->semantic_size[0] = (ui_size_t){ui_size_kind_text_content, 0, 0.5}; - box->semantic_size[1] = (ui_size_t){ui_size_kind_pixels, 40, 0.5}; + box->semantic_size[1] = (ui_size_t){ui_size_kind_text_content, 0, 0.5}; + { + ui_box_t *container = ui_push_list_container(); + container->grow_axis[0] = 1; + container->grow_axis[1] = 0; + ui_spacer("-"); + ui_box_t *c = ui_push_list_container(); + } + return box; } +void ui_pop_expander() { + ui_pop_parent(); + ui_pop_parent(); +} + ui_box_t *ui_label(char *fmt, ...) { S8_FMT(tcx.temp, fmt, string); ui_id_t id = ui_id_from_string(string); @@ -132,7 +167,7 @@ ui_box_t *ui_label(char *fmt, ...) { ui_push_box(box); box->string = string; box->semantic_size[0] = (ui_size_t){ui_size_kind_text_content, 0, 0.5}; - box->semantic_size[1] = (ui_size_t){ui_size_kind_pixels, 40, 0.5}; + box->semantic_size[1] = (ui_size_t){ui_size_kind_text_content, 0, 0.5}; return box; } @@ -209,66 +244,6 @@ void ui_test_stringify_postorder(sb8_t *sb, ui_box_t *box) { sb8_printf(sb, "%S", box->string); } -void ui_test_iterators(void) { - ma_temp_t scratch = ma_begin_scratch(); - ui_init(scratch.arena); - - defer_block(ui_begin_build(), ui_end_build()) { - defer_block(ui_push_expander("app_event_t"), ui_pop_parent()) { - defer_block(ui_push_expander("mouse_wheel_delta: v3f64_t"), ui_pop_parent()) { - ui_label("x: f64 = value"); - ui_label("y: f64 = value"); - ui_label("z: f64 = value"); - } - ui_label("kind: app_event_kind_t = value"); - ui_label("ctrl: b8 = value"); - ui_label("shift: b8 = value"); - defer_block(ui_push_expander("pos: v2f64_t"), ui_pop_parent()) { - defer_block(ui_push_expander("inner_pos: v2f64_t"), ui_pop_parent()) { - ui_label("x: f64 = value"); - ui_label("y: f64 = value"); - } - ui_label("y: f64 = value"); - defer_block(ui_push_expander("inner_pos: v2f64_t"), ui_pop_parent()) { - ui_label("x: f64 = value"); - ui_label("y: f64 = value"); - } - } - ui_label("alt: b8 = value"); - ui_label("meta: b8 = value"); - } - } - - { - sb8_t *sb = sb8_serial_begin(scratch.arena); - ui_test_stringify_preorder(sb, ui->root); - s8_t recursive_string = sb8_serial_end(scratch.arena, sb); - - sb = sb8_serial_begin(scratch.arena); - for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { - sb8_printf(sb, "%S", it.box->string); - } - s8_t iter_string = sb8_serial_end(scratch.arena, sb); - assert(s8_equal(iter_string, recursive_string)); - } - - { - sb8_t *sb = sb8_serial_begin(scratch.arena); - ui_test_stringify_postorder(sb, ui->root); - s8_t recursive_string = sb8_serial_end(scratch.arena, sb); - - sb = sb8_serial_begin(scratch.arena); - for (ui_postorder_iter_t it = ui_iterate_postorder(ui->root); ui_postorder_iter_is_valid(it); ui_iter_advance_postorder(&it)) { - sb8_printf(sb, "%S", it.box->string); - } - s8_t iter_string = sb8_serial_end(scratch.arena, sb); - assert(s8_equal(iter_string, recursive_string)); - } - - ui = NULL; - ma_end_scratch(scratch); -} - void ui_end_frame(void) { for (i32 i = 0; i < ui->allocated_boxes; i += 1) { ui_box_t *it = ui->box_array + i; @@ -277,8 +252,9 @@ void ui_end_frame(void) { } } -#if 0 -void ui_draw(gfx_t *gfx) { +void ui_draw(void) { + rn_font_t *font = &rn_state.main_font; + // compute standalone sizes: (pixels, text_content) for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { ui_box_t *box = it.box; @@ -287,29 +263,75 @@ void ui_draw(gfx_t *gfx) { if (sem.kind == ui_size_kind_pixels) { box->computed_size[i] = sem.value; } else if (sem.kind == ui_size_kind_text_content) { - box->computed_size[i] = measure_text_ex(box->string); + box->computed_size[i] = rn_measure_string(font, box->string).e[i]; } } } // compute: (percent_of_parent) - // for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { - // ui_box_t *box = it.box; - // for (i32 i = 0; i < ui_axis2_count; i += 1) { - // ui_size_t sem = box->semantic_size[i]; - // if (sem.kind == ui_size_kind_percent_of_parent) { - // } - // } - // } + for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { + ui_box_t *box = it.box; + ui_box_t *parent = box->parent; + for (i32 i = 0; i < ui_axis2_count; i += 1) { + ui_size_t sem = box->semantic_size[i]; + if (sem.kind == ui_size_kind_percent_of_parent) { + assert(sem.value >= 0 && sem.value <= 1.0); + assert(parent->semantic_size[i].kind == ui_size_kind_pixels || parent->semantic_size[i].kind == ui_size_kind_text_content); + box->computed_size[i] = sem.value * parent->computed_size[i]; + } + } + } // compute: (children_sum) + for (ui_postorder_iter_t it = ui_iterate_postorder(ui->root); ui_postorder_iter_is_valid(it); ui_iter_advance_postorder(&it)) { + ui_box_t *box = it.box; + for (i32 i = 0; i < ui_axis2_count; i += 1) { + ui_size_t sem = box->semantic_size[i]; + if (sem.kind != ui_size_kind_children_sum) continue; + + b32 grow_axis = box->grow_axis[i]; + for (ui_box_t *child = box->first; child; child = child->next) { + assert(child->computed_size[i] != 0.f); + if (grow_axis) { + box->computed_size[i] += child->computed_size[i]; + } else { + box->computed_size[i] = MAX(box->computed_size[i], child->computed_size[i]); + } + } + } + } // solve violations // compute relative positions + + + v2f32_t pos = {0,0}; + for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { + ui_box_t *box = it.box; + ui_box_t *parent = box->parent; + if (box == ui->root) continue; + + for (i32 i = 0; i < ui_axis2_count; i += 1) { + f32 *pos = &box->computed_rel_pos[i]; + f32 size = box->computed_size[i]; + + f32 parent_pos = parent->computed_rel_pos[i]; + f32 *iter_pos = &parent->iter_pos[i]; + + *pos = parent_pos + *iter_pos; + if (parent->grow_axis[i]) *iter_pos += size; + } + + v2f32_t pos = v2f32(box->computed_rel_pos[0], box->computed_rel_pos[1]); + v2f32_t size = v2f32(box->computed_size[0], box->computed_size[1]); + box->rect = r2f32_mindim(pos, size); + } + for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { ui_box_t *box = it.box; + rn_draw_rect(box->rect, primary_color_global); + rn_draw_string(font, box->rect.min, black_color_global, box->string); } } -#endif \ No newline at end of file diff --git a/todo.txt b/todo.txt index e95926c..e1fdd23 100644 --- a/todo.txt +++ b/todo.txt @@ -7,6 +7,7 @@ [ ] sleep [ ] hot reload / plugins [ ] tests using yield + [ ] touchpad gestures: https://learn.microsoft.com/en-us/windows/win32/wintouch/windows-touch-gestures-overview [ ] linux [ ] wasm [ ] drag and drop