diff --git a/.gitignore b/.gitignore index 53d0468..3350265 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ backup -s.bat +subl.bat multimedia.c multimedia.h diff --git a/build_file.c b/build_file.c index 27310c1..f39cf27 100644 --- a/build_file.c +++ b/build_file.c @@ -28,8 +28,8 @@ int main(int argc, char **argv) { bool run_server = false; bool core_test_target = false; - bool win32_target = false; - bool wasm_target = true; + bool win32_target = true; + bool wasm_target = false; if (execute_python_snippets) { sb8_t *sb = sb8_serial_begin(arena); diff --git a/src/wasm_app/main.c b/src/wasm_app/main.c index 6f53595..786b7e4 100644 --- a/src/wasm_app/main.c +++ b/src/wasm_app/main.c @@ -35,7 +35,52 @@ fn void app_init(void) { } +#if 0 +ui_begin_expander("app_event_t"); +{ + ui_edit_enum("kind: app_event_kind_t = %S"); + + ui_begin_expander("mouse_wheel_delta: v3f64_t"); + { + ui_edit_f64(&x, "x: %f", x); + ui_edit_f64(&y, "y: %f", y); + ui_edit_f64(&z, "z: %f", z); + } + ui_end_expander(); +} +ui_end_expander(); +#endif + + fn b32 app_update(app_event_list_t events) { + 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()) { + 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"); + } + } + + for (app_event_t *ev = events.first; ev; ev = ev->next) { if (globals->event.kind == app_event_kind_null) { globals->event = *ev; @@ -70,7 +115,8 @@ fn b32 app_update(app_event_list_t events) { // render gfx_begin(globals->gfx, ev); gfx_clear(globals->gfx, white_color_global); - gfx_textf(globals->gfx, (v2f64_t){0,ev->window_size.y - font_height}, black_color_global, "delta: %f, time: %f", delta, time); + gfx_textf(globals->gfx, (v2f64_t){0,ev->window_size.y - font_height}, black_color_global, + "delta: %f, time: %f widget_count: %d", delta, time, (i32)ui->allocated_boxes); // ► @@ -88,8 +134,10 @@ fn b32 app_update(app_event_list_t events) { p.y += font_height + 5; } + ui_draw(globals->gfx); gfx_end(globals->gfx); } + ui_end_frame(); return false; } diff --git a/src/wasm_app/ui.c b/src/wasm_app/ui.c index 2a8af22..ee28ec8 100644 --- a/src/wasm_app/ui.c +++ b/src/wasm_app/ui.c @@ -3,27 +3,52 @@ struct ui_id_t { u64 value; }; +typedef enum { + ui_axis2_x, + ui_axis2_y, + ui_axis2_count, +} ui_axis2_t; + +typedef enum { + ui_size_kind_null, + ui_size_kind_pixels, + ui_size_kind_text_content, + ui_size_kind_percent_of_parent, + ui_size_kind_children_sum, +} ui_size_kind_t; + +typedef struct ui_size_t ui_size_t; +struct ui_size_t { + ui_size_kind_t kind; + f64 value; + f64 strictness; +}; + typedef struct ui_box_t ui_box_t; struct ui_box_t { ui_id_t id; + // recreated every frame in building code ui_box_t *next; ui_box_t *prev; ui_box_t *parent; ui_box_t *first; ui_box_t *last; - - ui_box_t *iter_next; // for iterator - s8_t string; - b32 expanded; + ui_size_t semantic_size[ui_axis2_count]; + + // computed by layout system + f64 computed_rel_pos[ui_axis2_count]; + f64 computed_size[ui_axis2_count]; + r2f64_t rect; }; typedef struct ui_t ui_t; struct ui_t { - ma_arena_t *arena; + ma_arena_t *box_arena; // required to be only used for boxes - i32 active_box_count; + i32 allocated_boxes; + ui_box_t *box_array; // first item on arena ui_box_t *root; ui_box_t *top; @@ -33,42 +58,38 @@ struct ui_t { ui_t *ui = NULL; ui_id_t ui_null_id; -#if 0 -ui_begin_expander("app_event_t"); -{ - ui_edit_enum("kind: app_event_kind_t = %S"); - - ui_begin_expander("mouse_wheel_delta: v3f64_t"); - { - ui_edit_f64(&x, "x: %f", x); - ui_edit_f64(&y, "y: %f", y); - ui_edit_f64(&z, "z: %f", z); - } - ui_end_expander(); -} -ui_end_expander(); -#endif - -void ui_init(ma_arena_t *arena) { - ui = ma_push_type(arena, ui_t); - ui->arena = arena; -} - ui_box_t *ui_alloc_box(ui_id_t id) { - ui_box_t *result = ui->first_free; - if (!result) result = ma_push_type(ui->arena, ui_box_t); + ui_box_t *result = NULL; + if (ui->first_free) { + SLLS_POP_AND_STORE(ui->first_free, result); + } else { + result = ma_push_type(ui->box_arena, ui_box_t); + ui->allocated_boxes += 1; + } result->id = id; - ui->active_box_count += 1; return result; } + +void ui_init(ma_arena_t *arena) { + assert(ui->box_arena != tcx.temp); + + ui = ma_push_type(arena, ui_t); + ui->box_arena = arena; + + ui->box_array = ui_alloc_box(ui_null_id); + SLLS_PUSH(ui->first_free, ui->box_array); +} + void ui_begin_build(void) { - ui->root = ui_alloc_box(ui_null_id); - ui->top = ui->root; + ui->top = ui->root = ui_alloc_box(ui_null_id); } void ui_end_build(void) { + assert(ui->top == ui->root); +} +void ui_begin_frame(void) { } ui_id_t ui_id_from_string(s8_t string) { @@ -93,22 +114,25 @@ ui_box_t *ui_pop_parent(void) { return top; } -ui_box_t *ui_push_expander(char *cstring) { - s8_t string = s8_from_char(cstring); +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 *box = ui_alloc_box(id); ui_push_parent(box); box->string = string; - box->expanded = true; + 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}; return box; } -ui_box_t *ui_label(char *cstring) { - s8_t string = s8_from_char(cstring); +ui_box_t *ui_label(char *fmt, ...) { + S8_FMT(tcx.temp, fmt, string); ui_id_t id = ui_id_from_string(string); ui_box_t *box = ui_alloc_box(id); - box->string = string; 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}; return box; } @@ -200,7 +224,10 @@ void ui_test_iterators(void) { ui_label("ctrl: b8 = value"); ui_label("shift: b8 = value"); defer_block(ui_push_expander("pos: v2f64_t"), ui_pop_parent()) { - ui_label("x: 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("y: f64 = value"); defer_block(ui_push_expander("inner_pos: v2f64_t"), ui_pop_parent()) { ui_label("x: f64 = value"); @@ -209,7 +236,6 @@ void ui_test_iterators(void) { } ui_label("alt: b8 = value"); ui_label("meta: b8 = value"); - } } @@ -243,8 +269,45 @@ void ui_test_iterators(void) { 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; + zero_struct(it); + SLLS_PUSH(ui->first_free, it); + } +} -// void ui_end_build(ui_t *ui) { +void ui_draw(gfx_t *gfx) { + // 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; + for (i32 i = 0; i < ui_axis2_count; i += 1) { + ui_size_t sem = box->semantic_size[i]; + 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); + } + } + } -// } + // 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) { + // } + // } + // } + // compute: (children_sum) + + // solve violations + + // compute relative positions + 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; + + } +} \ No newline at end of file