horiscroller
This commit is contained in:
209
src/ui/ui.c
209
src/ui/ui.c
@@ -194,6 +194,7 @@ fn ui_box_t *ui_build_box_from_id(ui_code_loc_t loc, ui_box_flags_t flags, ui_id
|
|||||||
|
|
||||||
fn void ui_box_auto_rect(ui_box_t *box) {
|
fn void ui_box_auto_rect(ui_box_t *box) {
|
||||||
v2f32_t string_size = rn_measure_string(rn->main_font, box->string);
|
v2f32_t string_size = rn_measure_string(rn->main_font, box->string);
|
||||||
|
box->string_size = string_size;
|
||||||
ui_axis2_t axis = ui_axis_from_lop(ui_top_lop());
|
ui_axis2_t axis = ui_axis_from_lop(ui_top_lop());
|
||||||
if (ui->required_size_stack && (axis == ui_axis2_x || axis == ui_axis2_y)) {
|
if (ui->required_size_stack && (axis == ui_axis2_x || axis == ui_axis2_y)) {
|
||||||
string_size.e[axis] = ui_top_required_size();
|
string_size.e[axis] = ui_top_required_size();
|
||||||
@@ -201,19 +202,9 @@ fn void ui_box_auto_rect(ui_box_t *box) {
|
|||||||
if (ui->padding_stack && (axis == ui_axis2_x || axis == ui_axis2_y)) {
|
if (ui->padding_stack && (axis == ui_axis2_x || axis == ui_axis2_y)) {
|
||||||
string_size.e[axis] += ui_top_padding();
|
string_size.e[axis] += ui_top_padding();
|
||||||
}
|
}
|
||||||
if (box->flags.dont_compute_rect == false) {
|
|
||||||
r2f32_t rect = ui_next_rect(ui_top_lop(), &ui->top->rect, string_size);
|
r2f32_t rect = ui_next_rect(ui_top_lop(), &ui->top->rect, string_size);
|
||||||
ui_set_rect(box, rect);
|
ui_set_rect(box, rect);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn ui_box_t *ui_build_box_from_string(ui_code_loc_t loc, ui_box_flags_t flags, s8_t string) {
|
|
||||||
ui_id_t id = ui_id(string);
|
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, flags, id);
|
|
||||||
box->string = ui_get_display_string(string);
|
|
||||||
ui_box_auto_rect(box);
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct ui_box_params_t ui_box_params_t;
|
typedef struct ui_box_params_t ui_box_params_t;
|
||||||
struct ui_box_params_t {
|
struct ui_box_params_t {
|
||||||
@@ -308,8 +299,7 @@ fn void ui_set_to_be_determined(ui_box_t *box, ui_axis2_t axis) {
|
|||||||
} else_is_invalid;
|
} else_is_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn v2f32_t ui_aligned_text_pos(f32 offset, ui_text_align_t text_align, r2f32_t rect, s8_t string) {
|
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 string_size = rn_measure_string(rn->main_font, string);
|
|
||||||
v2f32_t rect_size = r2f32_get_size(rect);
|
v2f32_t rect_size = r2f32_get_size(rect);
|
||||||
v2f32_t rect_string_diff = v2f32_sub(rect_size, string_size);
|
v2f32_t rect_string_diff = v2f32_sub(rect_size, string_size);
|
||||||
v2f32_t center_pos = v2f32_divs(rect_string_diff, 2);
|
v2f32_t center_pos = v2f32_divs(rect_string_diff, 2);
|
||||||
@@ -375,7 +365,7 @@ fn void ui_text_input_draw(ui_box_t *box) {
|
|||||||
|
|
||||||
ui_text_input_t *ti = box->text_input;
|
ui_text_input_t *ti = box->text_input;
|
||||||
s8_t string = s8(ti->str, ti->len);
|
s8_t string = s8(ti->str, ti->len);
|
||||||
v2f32_t pos = ui_aligned_text_pos(box->string_pos_offset, box->text_align, co.rect, string);
|
v2f32_t pos = ui_aligned_text_pos(box->string_pos_offset, box->text_align, co.rect, string, rn_measure_string(rn->main_font, string));
|
||||||
rn_draw_string(rn->main_font, pos, co.text_color, string);
|
rn_draw_string(rn->main_font, pos, co.text_color, string);
|
||||||
|
|
||||||
ti->caret = ui_caret_clamp(ti->caret, 0, (i32)ti->len);
|
ti->caret = ui_caret_clamp(ti->caret, 0, (i32)ti->len);
|
||||||
@@ -406,7 +396,7 @@ fn void ui_default_draw_box(ui_box_t *box) {
|
|||||||
rn_draw_rect_border(co.rect, co.border_color, box->border_thickness);
|
rn_draw_rect_border(co.rect, co.border_color, box->border_thickness);
|
||||||
}
|
}
|
||||||
if (box->flags.draw_text) {
|
if (box->flags.draw_text) {
|
||||||
v2f32_t text_pos = ui_aligned_text_pos(box->string_pos_offset, box->text_align, co.rect, box->string);
|
v2f32_t text_pos = ui_aligned_text_pos(box->string_pos_offset, box->text_align, co.rect, box->string, box->string_size);
|
||||||
rn_draw_string(rn->main_font, text_pos, co.text_color, box->string);
|
rn_draw_string(rn->main_font, text_pos, co.text_color, box->string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -526,7 +516,6 @@ fn ui_signal_t ui__radio_button(ui_code_loc_t loc, i32 *value, i32 value_clicked
|
|||||||
ui_box_t *box = ui_box(.loc = loc, .string = string, .flags = { .draw_border = true, .draw_rect = true, .draw_text = true, .keyboard_nav = true });
|
ui_box_t *box = ui_box(.loc = loc, .string = string, .flags = { .draw_border = true, .draw_rect = true, .draw_text = true, .keyboard_nav = true });
|
||||||
ui_signal_t signal = ui_signal_from_box(box);
|
ui_signal_t signal = ui_signal_from_box(box);
|
||||||
if (signal.clicked) *value = value_clicked;
|
if (signal.clicked) *value = value_clicked;
|
||||||
// @todo?
|
|
||||||
if (*value == value_clicked) box->background_color = ui_color_table[ui_color_rect_turned_on];
|
if (*value == value_clicked) box->background_color = ui_color_table[ui_color_rect_turned_on];
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
@@ -569,26 +558,6 @@ fn void ui_end_expander(void) {
|
|||||||
ui_pop_id();
|
ui_pop_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void ui_begin_build(ui_code_loc_t loc, app_event_t *ev, r2f32_t window_rect) {
|
|
||||||
ui->event = ev;
|
|
||||||
|
|
||||||
for (ui_box_t *box = ui->hash_first, *next = NULL; box; box = next) {
|
|
||||||
next = box->hash_next;
|
|
||||||
if (box->id.value == 0) {
|
|
||||||
DLLQ_REMOVE_EX(ui->hash_first, ui->hash_last, box, hash_next, hash_prev);
|
|
||||||
zero_struct(box);
|
|
||||||
SLLS_PUSH(ui->free_first, box);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ui_box_t *ui_get_prev_box(ui_box_t *box, b32 (*match)(ui_box_t *)) {
|
fn ui_box_t *ui_get_prev_box(ui_box_t *box, b32 (*match)(ui_box_t *)) {
|
||||||
for (ui_box_t *it = box; it;) {
|
for (ui_box_t *it = box; it;) {
|
||||||
if (it->last) {
|
if (it->last) {
|
||||||
@@ -627,24 +596,30 @@ fn ui_box_t *ui_get_next_box(ui_box_t *box, b32 (*match)(ui_box_t *)) {
|
|||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn b32 ui_match_axis(ui_box_t *box, ui_axis2_t axis) {
|
|
||||||
ui_axis2_t box_axis = ui_axis_from_lop(box->lop);
|
|
||||||
b32 result = box_axis == axis;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn b32 ui_match_keynav(ui_box_t *box) {
|
fn b32 ui_match_keynav(ui_box_t *box) {
|
||||||
b32 result = box->flags.keyboard_nav;
|
b32 result = box->flags.keyboard_nav;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn b32 ui_match_keynav_xaxis(ui_box_t *box) {
|
fn void ui_begin_build(ui_code_loc_t loc, app_event_t *ev, r2f32_t window_rect) {
|
||||||
b32 result = box->flags.keyboard_nav && ui_match_axis(box, ui_axis2_x);
|
ui->event = ev;
|
||||||
return result;
|
|
||||||
|
for (ui_box_t *box = ui->hash_first, *next = NULL; box; box = next) {
|
||||||
|
next = box->hash_next;
|
||||||
|
if (box->id.value == 0) {
|
||||||
|
DLLQ_REMOVE_EX(ui->hash_first, ui->hash_last, box, hash_next, hash_prev);
|
||||||
|
zero_struct(box);
|
||||||
|
SLLS_PUSH(ui->free_first, box);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_box_t *ui_get_right_box(ui_box_t *box) { return ui_get_next_box(box, ui_match_keynav_xaxis); }
|
ui_push_init_values();
|
||||||
fn ui_box_t *ui_get_left_box(ui_box_t *box) { return ui_get_prev_box(box, ui_match_keynav_xaxis); }
|
|
||||||
|
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) {
|
fn void ui_end_build(void) {
|
||||||
{
|
{
|
||||||
@@ -980,7 +955,7 @@ fn void ui_end_reversal(void) {
|
|||||||
|
|
||||||
|
|
||||||
gb app_event_t ui_test_event;
|
gb app_event_t ui_test_event;
|
||||||
gb i32 ui_g_panel = 3;
|
gb i32 ui_g_panel = 2;
|
||||||
fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_count) {
|
fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_count) {
|
||||||
ui_begin_frame(frame);
|
ui_begin_frame(frame);
|
||||||
rn_begin_frame(frame);
|
rn_begin_frame(frame);
|
||||||
@@ -1008,12 +983,14 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
ui->top->rect = r2f32_shrinks(ui->top->rect, ui_em(1));
|
ui->top->rect = r2f32_shrinks(ui->top->rect, ui_em(1));
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// First list panel
|
// Data panel
|
||||||
if (ui_g_panel == 1) {
|
if (ui_g_panel == 1) {
|
||||||
ui_box_t *scroller_box = ui_box(r2f32_cut_right(&ui->top->rect, 10 * frame->dpr), {.draw_rect = true, .clip_rect = true});
|
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});
|
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));
|
item_box->rect = r2f32_shrinks(item_box->rect, ui_em(1));
|
||||||
|
|
||||||
|
|
||||||
ui_set_text_align(ui_text_align_left)
|
ui_set_text_align(ui_text_align_left)
|
||||||
ui_set_top(item_box) {
|
ui_set_top(item_box) {
|
||||||
locl char buff[128];
|
locl char buff[128];
|
||||||
@@ -1040,8 +1017,7 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
ui_signal_t signal = ui_label_button("%S: %f##slider%S", tweak->name, *n, tweak->name);
|
ui_signal_t signal = ui_label_button("%S: %f##slider%S", tweak->name, *n, tweak->name);
|
||||||
if (signal.dragging) {
|
if (signal.dragging) {
|
||||||
f32 size = tweak->max - tweak->min;
|
f32 size = tweak->max - tweak->min;
|
||||||
v2f32_t string_size = rn_measure_string(rn->main_font, signal.box->string);
|
f32 delta = (signal.drag.x / signal.box->string_size.x) * size;
|
||||||
f32 delta = (signal.drag.x / string_size.x) * size;
|
|
||||||
*n = CLAMP(*n + delta, tweak->min, tweak->max);
|
*n = CLAMP(*n + delta, tweak->min, tweak->max);
|
||||||
}
|
}
|
||||||
} else_is_invalid;
|
} else_is_invalid;
|
||||||
@@ -1054,7 +1030,7 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
}
|
}
|
||||||
|
|
||||||
locl f32 scroller_value;
|
locl f32 scroller_value;
|
||||||
defer_block(ui_push_top(scroller_box), ui_pop_top()) {
|
ui_set_top(scroller_box) {
|
||||||
f32 item_count = (f32)item_box->node_count;
|
f32 item_count = (f32)item_box->node_count;
|
||||||
f32 one_item_y_size = ui_em(1);
|
f32 one_item_y_size = ui_em(1);
|
||||||
f32 all_items_size = item_count * one_item_y_size;
|
f32 all_items_size = item_count * one_item_y_size;
|
||||||
@@ -1088,10 +1064,50 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
scroller_value -= ev->mouse_wheel_delta.y;
|
scroller_value -= ev->mouse_wheel_delta.y;
|
||||||
}
|
}
|
||||||
scroller_value = CLAMP(scroller_value, 0, all_items_size);
|
scroller_value = CLAMP(scroller_value, 0, all_items_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
locl f32 bottom_scroller_value;
|
||||||
|
ui_set_top(bottom_scroller) {
|
||||||
|
f32 max_size = 0;
|
||||||
|
for (ui_box_t *it = item_box->first; it; it = it->next) {
|
||||||
|
max_size = MAX(max_size, it->string_size.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 scroller_rect_pixels = r2f32_get_size(bottom_scroller->full_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});
|
||||||
|
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];
|
||||||
|
ui_signal_t left_box_sig = ui_signal_from_box(left_box);
|
||||||
|
ui_signal_t signal = ui_signal_from_box(slider_box);
|
||||||
|
ui_signal_t right_box_sig = ui_signal_from_box(down_box);
|
||||||
|
|
||||||
|
f32 coef = (max_size / scroller_rect_pixels) / scrollable_space;
|
||||||
|
|
||||||
|
if (signal.dragging) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (ev->kind == app_event_kind_mouse_wheel) {
|
||||||
|
bottom_scroller_value -= ev->mouse_wheel_delta.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bottom_scroller_value = CLAMP(bottom_scroller_value, 0, max_size);
|
||||||
|
}
|
||||||
|
|
||||||
for (ui_box_t *it = item_box->first; it; it = it->next) {
|
for (ui_box_t *it = item_box->first; it; it = it->next) {
|
||||||
ui_offset_box(it, v2f32(0, scroller_value));
|
ui_offset_box(it, v2f32(bottom_scroller_value, scroller_value));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,16 +1247,17 @@ 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, .clip_rect = true});
|
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 *item_box = ui_box(.rect = r2f32_cut_left(&ui->top->rect, ui_max), .flags = {.draw_rect = true, .clip_rect = true});
|
||||||
|
|
||||||
locl f32 scroller_value;
|
locl f32 right_scroller_value;
|
||||||
|
|
||||||
f32 one_item_y_size = ui_em(1);
|
f32 one_item_y_size = ui_em(1);
|
||||||
f32 all_items_size = item_count * one_item_y_size;
|
f32 all_items_size = item_count * one_item_y_size;
|
||||||
f32 item_box_size = r2f32_get_size(item_box->full_rect).y;
|
f32 item_box_pixels = r2f32_get_size(item_box->full_rect).y;
|
||||||
f32 visible_item_count = f32_ceil(item_box_size / one_item_y_size);
|
f32 visible_item_count = f32_ceil(item_box_pixels / one_item_y_size);
|
||||||
f32 render_start_count = f32_floor(scroller_value / one_item_y_size);
|
f32 render_start_count = f32_floor(right_scroller_value / one_item_y_size);
|
||||||
|
|
||||||
i32 istart = (i32)render_start_count;
|
i32 istart = (i32)render_start_count;
|
||||||
i32 iend = (i32)render_start_count + (i32)visible_item_count;
|
i32 iend = (i32)render_start_count + (i32)visible_item_count;
|
||||||
@@ -1255,15 +1272,15 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defer_block(ui_push_top(right_scroller), ui_pop_top()) {
|
ui_set_top(right_scroller) {
|
||||||
f32 right_scroller_size = r2f32_get_size(right_scroller->full_rect).y;
|
f32 scroller_rect_pixels = r2f32_get_size(right_scroller->full_rect).y;
|
||||||
f32 scroller_size = CLAMP(item_box_size / (all_items_size + frame->window_size.y), 0, 1.0f);
|
f32 scroller_size = f32_clamp01(item_box_pixels / (all_items_size + frame->window_size.y));
|
||||||
f32 scrollable_space = (1 - scroller_size);
|
f32 scrollable_space = (1 - scroller_size);
|
||||||
f32 scroller_norm = scroller_value / (all_items_size);
|
f32 scroller_value_norm = right_scroller_value / (all_items_size);
|
||||||
f32 scroller_percent = scroller_norm * scrollable_space;
|
f32 scroller_value_n = scroller_value_norm * scrollable_space;
|
||||||
|
|
||||||
ui_box_t *upper_box = ui_box(r2f32_cut_top(&ui->top->rect, scroller_percent * right_scroller_size), {.draw_rect = true});
|
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 * right_scroller_size), {.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 *down_box = ui_box(r2f32_cut_top(&ui->top->rect, ui_max), {.draw_rect = true});
|
||||||
slider_box->background_color = ui_color_table[ui_color_scroller];
|
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_hot_color = ui_color_table[ui_color_scroller_hot];
|
||||||
@@ -1272,25 +1289,67 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
ui_signal_t upper_box_signal = ui_signal_from_box(upper_box);
|
ui_signal_t upper_box_signal = ui_signal_from_box(upper_box);
|
||||||
ui_signal_t down_box_signal = ui_signal_from_box(down_box);
|
ui_signal_t down_box_signal = ui_signal_from_box(down_box);
|
||||||
f32 drag = ev->mouse_delta.y;
|
f32 drag = ev->mouse_delta.y;
|
||||||
f32 coef = (all_items_size / item_box_size) / scrollable_space;
|
f32 coef = (all_items_size / item_box_pixels) / scrollable_space;
|
||||||
if (signal.dragging) {
|
if (signal.dragging) {
|
||||||
scroller_value += drag * coef;
|
right_scroller_value += drag * coef;
|
||||||
}
|
}
|
||||||
if (upper_box_signal.dragging || down_box_signal.dragging) {
|
if (upper_box_signal.dragging || down_box_signal.dragging) {
|
||||||
scroller_value = (ev->mouse_pos.y - upper_box->full_rect.min.y) * coef;
|
right_scroller_value = (ev->mouse_pos.y - upper_box->full_rect.min.y) * coef;
|
||||||
scroller_value -= (r2f32_get_size(slider_box->full_rect).y / 2) * coef;
|
right_scroller_value -= (r2f32_get_size(slider_box->full_rect).y / 2) * coef;
|
||||||
}
|
}
|
||||||
if (ev->kind == app_event_kind_mouse_wheel) {
|
if (ev->kind == app_event_kind_mouse_wheel) {
|
||||||
scroller_value -= ev->mouse_wheel_delta.y;
|
right_scroller_value -= ev->mouse_wheel_delta.y;
|
||||||
|
}
|
||||||
|
right_scroller_value = CLAMP(right_scroller_value, 0, all_items_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
locl f32 bottom_scroller_value;
|
||||||
|
ui_set_top(bottom_scroller) {
|
||||||
|
f32 max_size = 0;
|
||||||
|
for (ui_box_t *it = item_box->first; it; it = it->next) {
|
||||||
|
max_size = MAX(max_size, it->string_size.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 scroller_rect_pixels = r2f32_get_size(bottom_scroller->full_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});
|
||||||
|
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];
|
||||||
|
ui_signal_t left_box_sig = ui_signal_from_box(left_box);
|
||||||
|
ui_signal_t signal = ui_signal_from_box(slider_box);
|
||||||
|
ui_signal_t right_box_sig = ui_signal_from_box(down_box);
|
||||||
|
|
||||||
|
f32 coef = (max_size / scroller_rect_pixels) / scrollable_space;
|
||||||
|
|
||||||
|
if (signal.dragging) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (ev->kind == app_event_kind_mouse_wheel) {
|
||||||
|
bottom_scroller_value -= ev->mouse_wheel_delta.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
bottom_scroller_value = CLAMP(bottom_scroller_value, 0, max_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
scroller_value = CLAMP(scroller_value, 0, all_items_size);
|
|
||||||
|
|
||||||
for (ui_box_t *it = item_box->first; it; it = it->next) {
|
for (ui_box_t *it = item_box->first; it; it = it->next) {
|
||||||
ui_offset_box(it, v2f32(0, scroller_value));
|
ui_offset_box(it, v2f32(bottom_scroller_value, right_scroller_value));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// Menus panel
|
||||||
if (ui_g_panel == 3) {
|
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->rect, ui_max), .flags = {.draw_rect = true, .clip_rect = true});
|
||||||
ui_set_top(item_box) {
|
ui_set_top(item_box) {
|
||||||
@@ -1334,6 +1393,8 @@ fn void ui_demo_update(app_frame_t *frame, mt_tweak_t *tweak_table, i32 tweak_co
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// Everything lister
|
||||||
ui_id_t lister_id = ui_id_from_loc(UILOC);
|
ui_id_t lister_id = ui_id_from_loc(UILOC);
|
||||||
locl b32 lister_open;
|
locl b32 lister_open;
|
||||||
b32 lister_just_opened = false;
|
b32 lister_just_opened = false;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ struct ui_box_flags_t {
|
|||||||
b8 draw_text: 1;
|
b8 draw_text: 1;
|
||||||
b8 clip_rect: 1;
|
b8 clip_rect: 1;
|
||||||
|
|
||||||
b8 dont_compute_rect: 1;
|
|
||||||
b8 keyboard_nav: 1;
|
b8 keyboard_nav: 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,6 +75,7 @@ struct ui_box_t {
|
|||||||
|
|
||||||
ui_code_loc_t loc;
|
ui_code_loc_t loc;
|
||||||
s8_t string;
|
s8_t string;
|
||||||
|
v2f32_t string_size;
|
||||||
|
|
||||||
ui_box_flags_t flags;
|
ui_box_flags_t flags;
|
||||||
b8 created_new;
|
b8 created_new;
|
||||||
@@ -170,4 +170,3 @@ fn void ui_set_rect(ui_box_t *box, r2f32_t rect) { box->rect = box->full_rect =
|
|||||||
|
|
||||||
fn ui_id_t ui_id(s8_t string);
|
fn ui_id_t ui_id(s8_t string);
|
||||||
fn ui_id_t ui_idf(char *str, ...);
|
fn ui_id_t ui_idf(char *str, ...);
|
||||||
fn v2f32_t ui_aligned_text_pos(f32 string_pos_offset, ui_text_align_t text_align, r2f32_t rect, s8_t string);
|
|
||||||
8
todo.txt
8
todo.txt
@@ -24,8 +24,16 @@
|
|||||||
[ ] ui
|
[ ] ui
|
||||||
[ ] table
|
[ ] table
|
||||||
[ ] vertical scroll
|
[ ] vertical scroll
|
||||||
|
[x] working
|
||||||
|
[ ] we depend on ui_boxes existing to calculate max_size which doesn't play well with efficient horiscroll, canm this be fixed?
|
||||||
|
[x] horizontal scroll
|
||||||
|
[x] efficient, on fixed size
|
||||||
|
[x] non-efficient
|
||||||
[ ] context menu
|
[ ] context menu
|
||||||
|
[x] working
|
||||||
|
[ ] maybe a separate root for context menu?
|
||||||
[ ] hover tooltips
|
[ ] hover tooltips
|
||||||
|
[ ] separate root which gets drawn on top of all ui
|
||||||
[ ] upper left menu dynamics
|
[ ] upper left menu dynamics
|
||||||
[x] debug console, lines
|
[x] debug console, lines
|
||||||
[x] fix elements getting offset when font large and they are on the edge
|
[x] fix elements getting offset when font large and they are on the edge
|
||||||
|
|||||||
Reference in New Issue
Block a user