rect_top and children sum

This commit is contained in:
Krzosa Karol
2025-01-28 23:26:46 +01:00
parent 5fe358f480
commit 491f60b59e
6 changed files with 113 additions and 71 deletions

View File

@@ -108,9 +108,50 @@ fn ui_id_t ui_idf(char *str, ...) {
}
fn void ui_push_id_string(s8_t string) { ui_push_id(ui_id(string)); }
fn void ui_push_top(ui_box_t *new_top) { assert(new_top->parent == ui->top); ui->top = new_top; ui_push_id(new_top->id); }
fn void ui_pop_top(void) { ui->top = ui->top->parent; ui_pop_id(); }
#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);
ui->top = new_top;
ui_push_id(new_top->id);
ui_push_rect(new_top->rect);
}
fn void ui_pop_top(void) {
ui->top = ui->top->parent;
ui_pop_id();
ui_pop_rect();
}
fn r2f32_t *ui_top_rectp(void) {
return &ui->rect_stack->value;
}
fn void ui_set_children_sums(ui_box_t *box) {
for (ui_box_t *it = box->first; it; it = it->next) {
ui_set_children_sums(it);
}
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);
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);
box->rect.min.y = min;
box->rect.max.y = max;
}
}
fn void ui_clear_appear_t(ui_box_t *box) {
box->appear_t = 0;
for (ui_box_t *it = box->first; it; it = it->next) {
ui_clear_appear_t(it);
}
}
fn ui_box_t *ui_alloc_box(void) {
ui_box_t *box = NULL;
@@ -164,7 +205,6 @@ fn r2f32_t ui_next_rect(ui_lop_t op, r2f32_t *rect, v2f32_t required_size) {
}
fn void ui_offset_one_box(ui_box_t *box, v2f32_t offset) {
box->full_rect = r2f32_sub_v2f32(box->full_rect, offset);
box->rect = r2f32_sub_v2f32(box->rect, offset);
}
@@ -214,8 +254,7 @@ fn void ui_box_auto_rect(ui_box_t *box) {
if (ui->padding_stack && (axis == ui_axis2_x || axis == ui_axis2_y)) {
string_size.e[axis] += ui_top_padding();
}
r2f32_t rect = ui_next_rect(ui_top_lop(), &ui->top->rect, string_size);
ui_set_rect(box, rect);
box->rect = ui_next_rect(ui_top_lop(), ui_top_rectp(), string_size);
}
typedef struct ui_box_params_t ui_box_params_t;
@@ -244,7 +283,7 @@ fn ui_box_t *ui__make_box(ui_box_params_t params) {
if (r2f32_is_null(params.rect)) {
ui_box_auto_rect(box);
} else {
ui_set_rect(box, params.rect);
box->rect = params.rect;
}
return box;
@@ -301,16 +340,6 @@ fn ui_signal_t ui_signal_from_box(ui_box_t *box) {
return result;
}
fn void ui_set_to_be_determined(ui_box_t *box, ui_axis2_t axis) {
if (axis == ui_axis2_x) {
box->full_rect.min.x = box->rect.max.x;
box->full_rect.max.x = box->rect.min.x;
} else if (axis == ui_axis2_y) {
box->full_rect.min.y = box->rect.max.y;
box->full_rect.max.y = box->rect.min.y;
} else_is_invalid;
}
fn v2f32_t ui_aligned_text_pos(f32 offset, ui_text_align_t text_align, r2f32_t rect, s8_t string, v2f32_t string_size) {
v2f32_t rect_size = r2f32_get_size(rect);
v2f32_t rect_string_diff = v2f32_sub(rect_size, string_size);
@@ -335,7 +364,7 @@ struct ui_draw_compute_t {
fn ui_draw_compute_t ui_draw_compute(ui_box_t *box) {
ui_draw_compute_t co = {0};
co.rect = box->full_rect;
co.rect = box->rect;
f32 appear_t = f32_ease_out_n(f32_clamp01(box->appear_t * 2), 10);
if (!ui_id_is_null(box->id)) {
v2f32_t size = v2f32_muls(r2f32_get_size(co.rect), 0.15f);
@@ -628,12 +657,13 @@ fn void ui_begin_build(ui_code_loc_t loc, app_event_t *ev, r2f32_t window_rect)
ui_push_init_values();
zero_struct(&ui->root);
ui->root.full_rect = ui->root.rect = window_rect;
ui->top = &ui->root;
ui->root.loc = loc;
}
fn void ui_end_build(void) {
ui_set_children_sums(&ui->root);
{
app_event_t *ev = ui->event;
ui_box_t *focus_box = ui_find_box(ui->focus);
@@ -664,7 +694,7 @@ fn void ui_end_build(void) {
}
fn void ui__draw_box(app_frame_t *frame, ui_box_t *box) {
box->final_rect = r2f32_intersect(box->full_rect, ui->clip_rect);
box->final_rect = r2f32_intersect(box->rect, ui->clip_rect);
if (box->custom_draw) {
box->custom_draw(box);
} else {
@@ -673,7 +703,7 @@ fn void ui__draw_box(app_frame_t *frame, ui_box_t *box) {
r2f32_t prev_clip_rect = ui->clip_rect;
if (box->flags.clip_rect) {
ui->clip_rect = box->full_rect;
ui->clip_rect = box->rect;
rn_set_clip(ui->clip_rect);
}
for (ui_box_t *it = box->first; it; it = it->next) {
@@ -965,7 +995,6 @@ fn void ui_end_reversal(void) {
}
}
gb app_event_t ui_test_event;
gb i32 ui_g_panel = 2;
fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_count) {
@@ -982,7 +1011,7 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
ui_g_panel = 3;
}
ui_box_t *top_box = ui_box(.null_id = true, .rect = r2f32_cut_top(&ui->top->rect, ui_em(1.5f)), .flags = {.draw_rect = true, .clip_rect = true});
ui_box_t *top_box = ui_box(.null_id = true, .rect = r2f32_cut_top(ui_top_rectp(), ui_em(1.5f)), .flags = {.draw_rect = true, .clip_rect = true});
ui_set_padding(ui_em(3))
ui_set_text_align(ui_text_align_center)
ui_set_lop(ui_lop_cut_left)
@@ -992,19 +1021,19 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
ui_radio_button(&ui_g_panel, 3, "menus");
}
ui->top->rect = r2f32_shrinks(ui->top->rect, ui_em(1));
ui_top_rectp()[0] = r2f32_shrinks(ui_top_rect(), ui_em(1));
///////////////////////////////
// Data panel
if (ui_g_panel == 1) {
ui_box_t *scroller_box = ui_box(r2f32_cut_right(&ui->top->rect, 10 * frame->dpr), {.draw_rect = true});
ui_box_t *bottom_scroller = ui_box(r2f32_cut_bottom(&ui->top->rect, 10 * frame->dpr), {.draw_rect = true});
ui_box_t *item_box = ui_box(r2f32_cut_left(&ui->top->rect, ui_max), {.draw_rect = true, .clip_rect = true});
item_box->rect = r2f32_shrinks(item_box->rect, ui_em(1));
ui_box_t *scroller_box = ui_box(r2f32_cut_right(ui_top_rectp(), 10 * frame->dpr), {.draw_rect = true});
ui_box_t *bottom_scroller = ui_box(r2f32_cut_bottom(ui_top_rectp(), 10 * frame->dpr), {.draw_rect = true});
ui_box_t *item_box = ui_box(r2f32_cut_left(ui_top_rectp(), ui_max), {.draw_rect = true, .clip_rect = true});
ui_set_text_align(ui_text_align_left)
ui_set_top(item_box) {
ui_top_rectp()[0] = r2f32_shrinks(ui_top_rect(), ui_em(1));
locl char buff[128];
locl ui_text_input_t text_input;
if (text_input.str == NULL) {
@@ -1046,17 +1075,17 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
f32 item_count = (f32)item_box->node_count;
f32 one_item_y_size = ui_em(1);
f32 all_items_size = item_count * one_item_y_size;
f32 item_box_size = r2f32_get_size(item_box->full_rect).y;
f32 scroller_box_size = r2f32_get_size(scroller_box->full_rect).y;
f32 item_box_size = r2f32_get_size(item_box->rect).y;
f32 scroller_box_size = r2f32_get_size(scroller_box->rect).y;
f32 scroller_size = CLAMP(item_box_size / (all_items_size + frame->window_size.y), 0, 1.0f);
f32 scrollable_space = (1 - scroller_size);
f32 scroller_norm = scroller_value / (all_items_size);
f32 scroller_percent = scroller_norm * scrollable_space;
f32 slider_box_size = scroller_size * scroller_box_size;
ui_box_t *upper_box = ui_box(r2f32_cut_top(&ui->top->rect, scroller_percent * scroller_box_size), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_top(&ui->top->rect, slider_box_size), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_top(&ui->top->rect, ui_max), {.draw_rect = true});
ui_box_t *upper_box = ui_box(r2f32_cut_top(ui_top_rectp(), scroller_percent * scroller_box_size), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_top(ui_top_rectp(), slider_box_size), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_top(ui_top_rectp(), ui_max), {.draw_rect = true});
slider_box->background_color = ui_color_table[ui_color_scroller];
slider_box->bg_hot_color = ui_color_table[ui_color_scroller_hot];
slider_box->bg_active_color = ui_color_table[ui_color_scroller_active];
@@ -1087,15 +1116,15 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
max_size = MAX(max_size, it->string_size.x);
}
f32 scroller_rect_pixels = r2f32_get_size(bottom_scroller->full_rect).x;
f32 scroller_rect_pixels = r2f32_get_size(bottom_scroller->rect).x;
f32 scroller_button_size_norm = f32_clamp01(scroller_rect_pixels / max_size);
f32 scrollable_space = (1.f - scroller_button_size_norm);
f32 scroller_value_norm = bottom_scroller_value / max_size;
f32 scroller_value_n = scroller_value_norm * scrollable_space;
ui_box_t *left_box = ui_box(r2f32_cut_left(&ui->top->rect, scroller_value_n * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_left(&ui->top->rect, scroller_button_size_norm * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_left(&ui->top->rect, ui_max), {.draw_rect = true});
ui_box_t *left_box = ui_box(r2f32_cut_left(ui_top_rectp(), scroller_value_n * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_left(ui_top_rectp(), scroller_button_size_norm * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_left(ui_top_rectp(), ui_max), {.draw_rect = true});
slider_box->background_color = ui_color_table[ui_color_scroller];
slider_box->bg_hot_color = ui_color_table[ui_color_scroller_hot];
slider_box->bg_active_color = ui_color_table[ui_color_scroller_active];
@@ -1109,8 +1138,8 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
bottom_scroller_value += ev->mouse_delta.x * coef;
}
if (left_box_sig.dragging || right_box_sig.dragging) {
bottom_scroller_value = (ev->mouse_pos.x - left_box->full_rect.min.x) * coef;
bottom_scroller_value -= (r2f32_get_size(slider_box->full_rect).x / 2) * coef;
bottom_scroller_value = (ev->mouse_pos.x - left_box->rect.min.x) * coef;
bottom_scroller_value -= (r2f32_get_size(slider_box->rect).x / 2) * coef;
}
if (ev->kind == app_event_kind_mouse_wheel) {
bottom_scroller_value -= ev->mouse_wheel_delta.x;
@@ -1258,15 +1287,15 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
}
}
ui_box_t *right_scroller = ui_box(.rect = r2f32_cut_right(&ui->top->rect, 10 * frame->dpr), .flags = {.draw_rect = true});
ui_box_t *bottom_scroller = ui_box(.rect = r2f32_cut_bottom(&ui->top->rect, 10 * frame->dpr), .flags = {.draw_rect = true});
ui_box_t *item_box = ui_box(.rect = r2f32_cut_left(&ui->top->rect, ui_max), .flags = {.draw_rect = true, .clip_rect = true});
ui_box_t *right_scroller = ui_box(.rect = r2f32_cut_right(ui_top_rectp(), 10 * frame->dpr), .flags = {.draw_rect = true});
ui_box_t *bottom_scroller = ui_box(.rect = r2f32_cut_bottom(ui_top_rectp(), 10 * frame->dpr), .flags = {.draw_rect = true});
ui_box_t *item_box = ui_box(.rect = r2f32_cut_left(ui_top_rectp(), ui_max), .flags = {.draw_rect = true, .clip_rect = true});
locl f32 right_scroller_value;
f32 one_item_y_size = ui_em(1);
f32 all_items_size = item_count * one_item_y_size;
f32 item_box_pixels = r2f32_get_size(item_box->full_rect).y;
f32 item_box_pixels = r2f32_get_size(item_box->rect).y;
f32 visible_item_count = f32_ceil(item_box_pixels / one_item_y_size);
f32 render_start_count = f32_floor(right_scroller_value / one_item_y_size);
@@ -1275,8 +1304,8 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
istart = CLAMP(istart, 0, (i32)item_count);
iend = CLAMP(iend, 0, (i32)item_count);
r2f32_cut_top_no_squash(&item_box->rect, render_start_count * one_item_y_size);
ui_set_top(item_box) {
r2f32_cut_top_no_squash(ui_top_rectp(), render_start_count * one_item_y_size);
for (i32 i = istart; i <iend ; i += 1) {
char *it = log_lines[i % lengthof(log_lines)];
ui_label("%s##log_line%d", it, i);
@@ -1284,15 +1313,15 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
}
ui_set_top(right_scroller) {
f32 scroller_rect_pixels = r2f32_get_size(right_scroller->full_rect).y;
f32 scroller_rect_pixels = r2f32_get_size(right_scroller->rect).y;
f32 scroller_size = f32_clamp01(item_box_pixels / (all_items_size + frame->window_size.y));
f32 scrollable_space = (1 - scroller_size);
f32 scroller_value_norm = right_scroller_value / (all_items_size);
f32 scroller_value_n = scroller_value_norm * scrollable_space;
ui_box_t *upper_box = ui_box(r2f32_cut_top(&ui->top->rect, scroller_value_n * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_top(&ui->top->rect, scroller_size * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_top(&ui->top->rect, ui_max), {.draw_rect = true});
ui_box_t *upper_box = ui_box(r2f32_cut_top(ui_top_rectp(), scroller_value_n * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_top(ui_top_rectp(), scroller_size * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_top(ui_top_rectp(), ui_max), {.draw_rect = true});
slider_box->background_color = ui_color_table[ui_color_scroller];
slider_box->bg_hot_color = ui_color_table[ui_color_scroller_hot];
slider_box->bg_active_color = ui_color_table[ui_color_scroller_active];
@@ -1305,8 +1334,8 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
right_scroller_value += drag * coef;
}
if (upper_box_signal.dragging || down_box_signal.dragging) {
right_scroller_value = (ev->mouse_pos.y - upper_box->full_rect.min.y) * coef;
right_scroller_value -= (r2f32_get_size(slider_box->full_rect).y / 2) * coef;
right_scroller_value = (ev->mouse_pos.y - upper_box->rect.min.y) * coef;
right_scroller_value -= (r2f32_get_size(slider_box->rect).y / 2) * coef;
}
if (ev->kind == app_event_kind_mouse_wheel) {
right_scroller_value -= ev->mouse_wheel_delta.y;
@@ -1321,15 +1350,15 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
max_size = MAX(max_size, it->string_size.x);
}
f32 scroller_rect_pixels = r2f32_get_size(bottom_scroller->full_rect).x;
f32 scroller_rect_pixels = r2f32_get_size(bottom_scroller->rect).x;
f32 scroller_button_size_norm = f32_clamp01(scroller_rect_pixels / max_size);
f32 scrollable_space = (1.f - scroller_button_size_norm);
f32 scroller_value_norm = bottom_scroller_value / max_size;
f32 scroller_value_n = scroller_value_norm * scrollable_space;
ui_box_t *left_box = ui_box(r2f32_cut_left(&ui->top->rect, scroller_value_n * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_left(&ui->top->rect, scroller_button_size_norm * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_left(&ui->top->rect, ui_max), {.draw_rect = true});
ui_box_t *left_box = ui_box(r2f32_cut_left(ui_top_rectp(), scroller_value_n * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *slider_box = ui_box(r2f32_cut_left(ui_top_rectp(), scroller_button_size_norm * scroller_rect_pixels), {.draw_rect = true});
ui_box_t *down_box = ui_box(r2f32_cut_left(ui_top_rectp(), ui_max), {.draw_rect = true});
slider_box->background_color = ui_color_table[ui_color_scroller];
slider_box->bg_hot_color = ui_color_table[ui_color_scroller_hot];
slider_box->bg_active_color = ui_color_table[ui_color_scroller_active];
@@ -1343,8 +1372,8 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
bottom_scroller_value += ev->mouse_delta.x * coef;
}
if (left_box_sig.dragging || right_box_sig.dragging) {
bottom_scroller_value = (ev->mouse_pos.x - left_box->full_rect.min.x) * coef;
bottom_scroller_value -= (r2f32_get_size(slider_box->full_rect).x / 2) * coef;
bottom_scroller_value = (ev->mouse_pos.x - left_box->rect.min.x) * coef;
bottom_scroller_value -= (r2f32_get_size(slider_box->rect).x / 2) * coef;
}
if (ev->kind == app_event_kind_mouse_wheel) {
bottom_scroller_value -= ev->mouse_wheel_delta.x;
@@ -1360,7 +1389,7 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
///////////////////////////////
// Menus panel
if (ui_g_panel == 3) {
ui_box_t *item_box = ui_box(.rect = r2f32_cut_left(&ui->top->rect, ui_max), .flags = {.draw_rect = true, .clip_rect = true});
ui_box_t *item_box = ui_box(.rect = r2f32_cut_left(ui_top_rectp(), ui_max), .flags = {.draw_rect = true, .clip_rect = true});
ui_set_top(item_box) {
ui_label("right click to bring up the context menu!");
}
@@ -1377,25 +1406,28 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
}
if (context_menu_open) {
ui_box_t *menu = ui_box(.rect = r2f32_min_dim(menu_pos, v2f32(ui_em(10), ui_to_be_determined)), .flags = {.draw_border = true, .draw_rect = true});
ui_box_t *menu = ui_box(.rect = r2f32_min_dim(menu_pos, v2f32(ui_em(10), ui_children_sum)), .flags = {.draw_border = true, .draw_rect = true, .children_sum_y = true});
ui_set_top(menu)
ui_set_text_align(ui_text_align_left)
ui_set_string_pos_offset(ui_em(1))
ui_set_padding(ui_em(0.2f)) {
ui_label_button("file");
ui_label_button("memes");
r2f32_cut_left(ui_top_rectp(), ui_em(1));
ui_box_t *a = ui_box(.flags = {.draw_border = true, .draw_rect = true, .children_sum_y = true});
ui_set_top(a) {
ui_label_button("a");
ui_label_button("memes");
}
}
ui_set_to_be_determined(menu, ui_axis2_y);
if (ev_left_down(ev) && !r2f32_contains(menu->full_rect, ev->mouse_pos)) {
if (ev_left_down(ev) && !r2f32_contains(menu->final_rect, ev->mouse_pos)) {
context_menu_open = 0;
}
if (ev_right_down(ev)) {
menu->appear_t = 0;
for (ui_box_t *it = menu->first; it; it = it->next) {
it->appear_t = 0;
}
ui_clear_appear_t(menu);
}
}
}