ui_tree_table
This commit is contained in:
119
src/ui/ui.c
119
src/ui/ui.c
@@ -109,6 +109,17 @@ fn ui_id_t ui_idf(char *str, ...) {
|
||||
|
||||
fn void ui_push_id_string(s8_t string) { ui_push_id(ui_id(string)); }
|
||||
|
||||
#define ui_set_top_ex(x) defer_block(ui_push_top_ex(x), ui_pop_top_ex())
|
||||
fn void ui_push_top_ex(ui_box_t *box) {
|
||||
assert(ui->top == ui->top);
|
||||
ui->top = box;
|
||||
}
|
||||
fn ui_box_t *ui_pop_top_ex(void) {
|
||||
ui_box_t *result = ui->top;
|
||||
ui->top = ui->top->parent;
|
||||
return result;
|
||||
}
|
||||
|
||||
#define ui_set_top(x) defer_block(ui_push_top(x), ui_pop_top())
|
||||
fn void ui_push_top(ui_box_t *new_top) {
|
||||
assert(new_top->parent == ui->top);
|
||||
@@ -116,10 +127,12 @@ fn void ui_push_top(ui_box_t *new_top) {
|
||||
ui_push_id(new_top->id);
|
||||
ui_push_rect(new_top->rect);
|
||||
}
|
||||
fn void ui_pop_top(void) {
|
||||
fn ui_box_t *ui_pop_top(void) {
|
||||
ui_box_t *result = ui->top;
|
||||
ui->top = ui->top->parent;
|
||||
ui_pop_id();
|
||||
ui_pop_rect();
|
||||
return result;
|
||||
}
|
||||
|
||||
fn r2f32_t *ui_top_rectp(void) {
|
||||
@@ -132,15 +145,27 @@ fn void ui_set_children_sums(ui_box_t *box) {
|
||||
}
|
||||
|
||||
if (box->flags.children_sum_x) {
|
||||
f32 min = MIN(box->first->rect.min.x, box->last->rect.min.x);
|
||||
f32 max = MAX(box->first->rect.max.x, box->last->rect.max.x);
|
||||
f32 min = box->rect.min.x;
|
||||
f32 max = box->rect.max.x;
|
||||
if (box->first) {
|
||||
f32 min_child = MIN(box->first->rect.min.x, box->last->rect.min.x);
|
||||
f32 max_child = MAX(box->first->rect.max.x, box->last->rect.max.x);
|
||||
min = MIN(box->rect.min.x, min_child);
|
||||
max = MAX(box->rect.max.x, max_child);
|
||||
}
|
||||
box->rect.min.x = min;
|
||||
box->rect.max.x = max;
|
||||
}
|
||||
|
||||
if (box->flags.children_sum_y) {
|
||||
f32 min = MIN(box->first->rect.min.y, box->last->rect.min.y);
|
||||
f32 max = MAX(box->first->rect.max.y, box->last->rect.max.y);
|
||||
f32 min = box->rect.min.y;
|
||||
f32 max = box->rect.max.y;
|
||||
if (box->first) {
|
||||
f32 min_child = MIN(box->first->rect.min.y, box->last->rect.min.y);
|
||||
f32 max_child = MAX(box->first->rect.max.y, box->last->rect.max.y);
|
||||
min = MIN(box->rect.min.y, min_child);
|
||||
max = MAX(box->rect.max.y, max_child);
|
||||
}
|
||||
box->rect.min.y = min;
|
||||
box->rect.max.y = max;
|
||||
}
|
||||
@@ -239,6 +264,19 @@ fn ui_box_t *ui_build_box_from_id(ui_code_loc_t loc, ui_box_flags_t flags, ui_id
|
||||
box->text_align = ui_top_text_align();
|
||||
box->border_thickness = ui_top_border_thickness();
|
||||
box->string_pos_offset = ui_top_string_pos_offset();
|
||||
|
||||
// :ui_box_flags_t
|
||||
ui_box_flags_t top_flags = ui_top_flags();
|
||||
{
|
||||
if(top_flags.draw_rect) box->flags.draw_rect = true;
|
||||
if(top_flags.draw_border) box->flags.draw_border = true;
|
||||
if(top_flags.draw_text) box->flags.draw_text = true;
|
||||
if(top_flags.clip_rect) box->flags.clip_rect = true;
|
||||
if(top_flags.children_sum_x) box->flags.children_sum_x = true;
|
||||
if(top_flags.children_sum_y) box->flags.children_sum_y = true;
|
||||
if(top_flags.keyboard_nav) box->flags.keyboard_nav = true;
|
||||
}
|
||||
|
||||
ui_box_fill_with_colors(box);
|
||||
ui_push_box(ui->top, box);
|
||||
return box;
|
||||
@@ -272,10 +310,12 @@ fn ui_box_t *ui__make_box(ui_box_params_t params) {
|
||||
ui_id_t id = params.id;
|
||||
if (ui_id_is_null(id) && params.null_id == false) {
|
||||
if (params.string.len != 0) {
|
||||
id = ui_id(params.string);
|
||||
id = ui_id(ui_get_hash_string(params.string));
|
||||
id.value = hash_mix(id.value, ui_hash_from_stack());
|
||||
}
|
||||
if (ui_id_is_null(id)) {
|
||||
id = ui_id_from_loc(params.loc);
|
||||
id.value = hash_mix(id.value, ui_hash_from_stack());
|
||||
}
|
||||
}
|
||||
ui_box_t *box = ui_build_box_from_id(params.loc, params.flags, id);
|
||||
@@ -576,28 +616,44 @@ fn ui_box_t *ui__label(ui_code_loc_t loc, char *str, ...) {
|
||||
return box;
|
||||
}
|
||||
|
||||
#define ui_expander(...) defer_if (ui_begin_expander(__VA_ARGS__).clicked, ui_end_expander())
|
||||
#define ui_begin_expander(...) ui__begin_expander(UILOC, __VA_ARGS__)
|
||||
fn ui_signal_t ui__begin_expander(ui_code_loc_t loc, char *str, ...) {
|
||||
S8_FMT(tcx->temp, str, string);
|
||||
ui_box_t *box = ui_box(.loc = loc, .string = string, .flags = { .draw_text = true, .keyboard_nav = true });
|
||||
if (box->created_new) box->expanded = true;
|
||||
ui_signal_t signal = ui_signal_from_box(box);
|
||||
if (signal.clicked) box->expanded = !box->expanded;
|
||||
signal.clicked = box->expanded;
|
||||
if ( box->expanded) box->string = s8_printf(tcx->temp, "* %S", box->string);
|
||||
if (!box->expanded) box->string = s8_printf(tcx->temp, "> %S", box->string);
|
||||
if (box->expanded) {
|
||||
ui_push_string_pos_offset(ui_top_string_pos_offset() + ui_em(0.5f));
|
||||
ui_push_id(box->id);
|
||||
}
|
||||
return signal;
|
||||
#define ui_tree_table() defer_block(ui_tree_table_begin(UILOC), ui_tree_table_end())
|
||||
fn void ui_tree_table_begin(ui_code_loc_t loc) {
|
||||
ui_box_t *box = ui_box(.loc = loc, .rect = ui_next_rect(ui_top_lop(), ui_top_rectp(), v2f32_null), .flags = { .draw_border = true, .children_sum_y = true });
|
||||
ui_push_top(box);
|
||||
}
|
||||
|
||||
fn void ui_end_expander(void) {
|
||||
ui_pop_string_pos_offset();
|
||||
fn void ui_tree_table_end(void) {
|
||||
ui_box_t *box = ui_pop_top();
|
||||
ui_set_children_sums(box);
|
||||
ui_next_rect(ui_top_lop(), ui_top_rectp(), r2f32_get_size(box->rect));
|
||||
}
|
||||
|
||||
#define ui_tree_table_expandable(...) defer_if (ui_tree_table_push_expandable(UILOC, __VA_ARGS__).clicked, ui_tree_table_pop_expandable())
|
||||
fn void ui_tree_table_pop_expandable(void) {
|
||||
r2f32_add_left(ui_top_rectp(), ui_dm(1));
|
||||
ui_tree_table_end();
|
||||
ui_pop_id();
|
||||
}
|
||||
fn ui_signal_t ui_tree_table_push_expandable(ui_code_loc_t loc, char *str, ...) {
|
||||
S8_FMT(tcx->temp, str, string);
|
||||
ui_id_t id = ui_id(ui_get_hash_string(string));
|
||||
ui_push_id(id);
|
||||
ui_tree_table_begin(loc);
|
||||
ui_box_t *box = ui_box(.loc = loc, .string = string, .flags = { .draw_rect = true, .draw_text = true, .keyboard_nav = true});
|
||||
ui_signal_t button = ui_signal_from_box(box);
|
||||
if (button.box->created_new) button.box->expanded = true;
|
||||
if (button.clicked) button.box->expanded = !button.box->expanded;
|
||||
button.clicked = button.box->expanded;
|
||||
|
||||
r2f32_cut_left(ui_top_rectp(), ui_dm(1));
|
||||
|
||||
if (button.clicked == false) {
|
||||
ui_tree_table_pop_expandable();
|
||||
}
|
||||
if ( button.box->expanded) button.box->string = s8_printf(tcx->temp, "* %S", button.box->string);
|
||||
if (!button.box->expanded) button.box->string = s8_printf(tcx->temp, "> %S", button.box->string);
|
||||
return button;
|
||||
}
|
||||
|
||||
fn ui_box_t *ui_get_prev_box(ui_box_t *box, b32 (*match)(ui_box_t *)) {
|
||||
for (ui_box_t *it = box; it;) {
|
||||
@@ -917,7 +973,7 @@ fn void ui_serial_subtype(void *p, type_t *type, s8_t name) {
|
||||
}
|
||||
|
||||
if (type->kind == type_kind_array) {
|
||||
ui_expander("%S:", name) {
|
||||
ui_tree_table_expandable("%S:", name) {
|
||||
for (i32 i = 0; i < type->count; i += 1) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
s8_t index_name = s8_printf(scratch.arena, "[%d]", i);
|
||||
@@ -930,7 +986,7 @@ fn void ui_serial_subtype(void *p, type_t *type, s8_t name) {
|
||||
}
|
||||
|
||||
if (type->kind == type_kind_struct) {
|
||||
ui_expander("%S:", name) {
|
||||
ui_tree_table_expandable("%S:", name) {
|
||||
for (i32 i = 0; i < type->count; i += 1) {
|
||||
type_member_t *tm = type->members + i;
|
||||
void *tmp = ti_extract_member(p, tm);
|
||||
@@ -943,8 +999,8 @@ fn void ui_serial_subtype(void *p, type_t *type, s8_t name) {
|
||||
}
|
||||
}
|
||||
|
||||
fn void ui_serial_type(void *p, type_t *type) {
|
||||
ui_serial_subtype(p, type, type->name);
|
||||
fn void ui_serial_type(ui_code_loc_t loc, void *p, type_t *type) {
|
||||
ui_set_id(ui_id_from_loc(loc)) ui_serial_subtype(p, type, type->name);
|
||||
}
|
||||
|
||||
fn void ui_reload(void) {
|
||||
@@ -1064,10 +1120,8 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
||||
} else_is_invalid;
|
||||
}
|
||||
ui_label("allocated boxes: %d", ui->allocated_boxes);
|
||||
ui_serial_type(&ui_test_event, type(app_event_t));
|
||||
ui_set_id(ui_id_from_loc(UILOC)) {
|
||||
ui_serial_type(&ui_test_event, type(app_event_t));
|
||||
}
|
||||
ui_serial_type(UILOC, &ui_test_event, type(app_event_t));
|
||||
ui_serial_type(UILOC, &ui_test_event, type(app_event_t));
|
||||
}
|
||||
|
||||
locl f32 scroller_value;
|
||||
@@ -1419,7 +1473,6 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
||||
ui_label_button("a");
|
||||
ui_label_button("memes");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -78,6 +78,10 @@ fn void ui_push_rect(r2f32_t v) { ui_r2f32_node_t *n = ma_push_type(tcx->temp, u
|
||||
fn void ui_pop_rect(void) { SLLS_POP(ui->rect_stack); }
|
||||
fn r2f32_t ui_top_rect(void) { return ui->rect_stack->value; }
|
||||
#define ui_set_rect(x) defer_block(ui_push_rect(x), ui_pop_rect())
|
||||
fn void ui_push_flags(ui_box_flags_t v) { ui_box_flags_node_t *n = ma_push_type(tcx->temp, ui_box_flags_node_t); n->value = v; SLLS_PUSH(ui->flags_stack, n); }
|
||||
fn void ui_pop_flags(void) { SLLS_POP(ui->flags_stack); }
|
||||
fn ui_box_flags_t ui_top_flags(void) { return ui->flags_stack->value; }
|
||||
#define ui_set_flags(x) defer_block(ui_push_flags(x), ui_pop_flags())
|
||||
fn void ui_push_background_color(v4f32_t v) { ui_v4f32_node_t *n = ma_push_type(tcx->temp, ui_v4f32_node_t); n->value = v; SLLS_PUSH(ui->background_color_stack, n); }
|
||||
fn void ui_pop_background_color(void) { SLLS_POP(ui->background_color_stack); }
|
||||
fn v4f32_t ui_top_background_color(void) { return ui->background_color_stack->value; }
|
||||
@@ -116,6 +120,7 @@ assert(ui->required_size_stack == NULL);
|
||||
assert(ui->padding_stack == NULL);
|
||||
assert(ui->string_pos_offset_stack == NULL);
|
||||
assert(ui->rect_stack == NULL);
|
||||
assert(ui->flags_stack == NULL);
|
||||
assert(ui->background_color_stack == NULL);
|
||||
assert(ui->bg_hot_color_stack == NULL);
|
||||
assert(ui->bg_active_color_stack == NULL);
|
||||
@@ -131,6 +136,7 @@ ui_push_border_thickness(1.0f);
|
||||
ui_push_text_align(ui_text_align_left);
|
||||
ui_push_string_pos_offset(0);
|
||||
ui_push_rect(window_rect_from_frame(ui->frame));
|
||||
ui_push_flags((ui_box_flags_t){0});
|
||||
ui_push_background_color(ui_color_table[ui_color_rect]);
|
||||
ui_push_bg_hot_color(ui_color_table[ui_color_rect_hot]);
|
||||
ui_push_bg_active_color(ui_color_table[ui_color_rect_active]);
|
||||
@@ -146,6 +152,7 @@ ui_pop_border_thickness();
|
||||
ui_pop_text_align();
|
||||
ui_pop_string_pos_offset();
|
||||
ui_pop_rect();
|
||||
ui_pop_flags();
|
||||
ui_pop_background_color();
|
||||
ui_pop_bg_hot_color();
|
||||
ui_pop_bg_active_color();
|
||||
|
||||
@@ -20,6 +20,7 @@ typedef struct ui_lop_node_t ui_lop_node_t; struct ui_lop_node_t { ui_lop_t valu
|
||||
typedef struct ui_f32_node_t ui_f32_node_t; struct ui_f32_node_t { f32 value; ui_f32_node_t *next; };
|
||||
typedef struct ui_text_align_node_t ui_text_align_node_t; struct ui_text_align_node_t { ui_text_align_t value; ui_text_align_node_t *next; };
|
||||
typedef struct ui_r2f32_node_t ui_r2f32_node_t; struct ui_r2f32_node_t { r2f32_t value; ui_r2f32_node_t *next; };
|
||||
typedef struct ui_box_flags_node_t ui_box_flags_node_t; struct ui_box_flags_node_t { ui_box_flags_t value; ui_box_flags_node_t *next; };
|
||||
typedef struct ui_v4f32_node_t ui_v4f32_node_t; struct ui_v4f32_node_t { v4f32_t value; ui_v4f32_node_t *next; };
|
||||
#define UI_DECL_BOX_MEMBERS \
|
||||
f32 border_thickness;\
|
||||
@@ -28,6 +29,7 @@ f32 required_size;\
|
||||
f32 padding;\
|
||||
f32 string_pos_offset;\
|
||||
r2f32_t rect;\
|
||||
ui_box_flags_t flags;\
|
||||
v4f32_t background_color;\
|
||||
v4f32_t bg_hot_color;\
|
||||
v4f32_t bg_active_color;\
|
||||
@@ -45,6 +47,7 @@ ui_f32_node_t *required_size_stack;\
|
||||
ui_f32_node_t *padding_stack;\
|
||||
ui_f32_node_t *string_pos_offset_stack;\
|
||||
ui_r2f32_node_t *rect_stack;\
|
||||
ui_box_flags_node_t *flags_stack;\
|
||||
ui_v4f32_node_t *background_color_stack;\
|
||||
ui_v4f32_node_t *bg_hot_color_stack;\
|
||||
ui_v4f32_node_t *bg_active_color_stack;\
|
||||
|
||||
@@ -12,6 +12,7 @@ struct ui_id_t {
|
||||
|
||||
typedef struct ui_box_flags_t ui_box_flags_t;
|
||||
struct ui_box_flags_t {
|
||||
// :ui_box_flags_t - change those places when modifying this
|
||||
b8 draw_rect: 1;
|
||||
b8 draw_border: 1;
|
||||
b8 draw_text: 1;
|
||||
@@ -79,7 +80,6 @@ struct ui_box_t {
|
||||
s8_t string;
|
||||
v2f32_t string_size;
|
||||
|
||||
ui_box_flags_t flags;
|
||||
b8 created_new;
|
||||
ui_custom_draw_t *custom_draw;
|
||||
ui_lop_t lop;
|
||||
@@ -160,6 +160,7 @@ fn b32 ui_is_focused_box(ui_box_t *box) { return !ui_is_null_box(box) && box->id
|
||||
|
||||
#define UILOC (ui_code_loc_t){.file = __FILE__, .line = __LINE__, .counter = __COUNTER__}
|
||||
#define ui_em(x) ((x) * rn->main_font->size)
|
||||
#define ui_dm(V) ((V) * rn->main_font->computed_xchar_size)
|
||||
#define ui_max 200000000.f
|
||||
#define ui_children_sum 0
|
||||
#define ui_box_flags(...) (ui_box_flag_t){__VA_ARGS__}
|
||||
|
||||
@@ -42,6 +42,7 @@ fn void mt_ui_stacks(ma_arena_t *arena, sb8_t *c, sb8_t *h) {
|
||||
{ f32 padding 0 x }
|
||||
{ f32 string_pos_offset 0 0 }
|
||||
{ r2f32_t rect 0 `window_rect_from_frame(ui->frame)` }
|
||||
{ ui_box_flags_t flags 0 `(ui_box_flags_t){0}` }
|
||||
{ v4f32_t background_color 0 `ui_color_table[ui_color_rect]` }
|
||||
{ v4f32_t bg_hot_color 0 `ui_color_table[ui_color_rect_hot]` }
|
||||
{ v4f32_t bg_active_color 0 `ui_color_table[ui_color_rect_active]` }
|
||||
|
||||
Reference in New Issue
Block a user