app_frame, ui layout, draw the list

This commit is contained in:
Krzosa Karol
2025-01-09 10:38:08 +01:00
parent bd5ce59791
commit 74a60e812d
9 changed files with 234 additions and 217 deletions

View File

@@ -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"

View File

@@ -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,
};

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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()) {
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("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()) {
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");
defer_block(ui_push_expander("inner_pos: v2f64_t"), ui_pop_parent()) {
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();
}
}
}
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_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;
}

View File

@@ -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

View File

@@ -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