diff --git a/src/ui/ui.c b/src/ui/ui.c index 45a0048..835369d 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -996,40 +996,8 @@ struct ui_scroller_t { ui_scroller_params_t p; }; -fn ui_scroller_t ui_begin_scroller(ui_code_loc_t loc, ui_scroller_params_t p) { - ui_scroller_t r = {.p = p}; - - if (p.verti.enabled) { - r.verti.box = ui_box(.loc = loc, .rect = r2f32_cut_right(&p.parent->rect, ui_dm(0.5f)), .flags = {.draw_rect = true}); - r2f32_cut_bottom(&r.verti.box->rect, ui_dm(0.5f)); - r.verti.item_box_pixels = r2f32_get_size(p.parent->rect).y; - - if (p.verti.item_count) { - f32 visible_item_count = f32_ceil(r.verti.item_box_pixels / p.verti.item_pixels); - f32 render_start_count = f32_floor(p.verti.value[0] / p.verti.item_pixels); - - i32 istart = (i32)render_start_count; - i32 iend = (i32)render_start_count + (i32)visible_item_count; - r.verti.istart = CLAMP(istart, 0, (i32)p.verti.item_count); - r.verti.iend = CLAMP(iend, 0, (i32)p.verti.item_count); - r.p.verti.max_size = r.p.verti.item_pixels * r.p.verti.item_count; - } - } - - if (p.hori.enabled) { - loc.counter += 10000; - r.hori.box = ui_box(.loc = loc, .rect = r2f32_cut_bottom(&p.parent->rect, ui_dm(0.5f)), .flags = {.draw_rect = true}); - } - - return r; -} - -fn void ui_cut_top_scroller_offset(ui_scroller_t s) { - r2f32_cut_top_no_squash(ui_top_rectp(), (f32)s.verti.istart * s.p.verti.item_pixels); -} - -fn void ui_end_scroller(ui_scroller_t s) { - if (s.p.verti.enabled) ui_set_top(s.verti.box) { +fn void ui_scroller_calc_vertical(ui_scroller_t s) { + ui_set_top(s.verti.box) { f32 scroller_rect_pixels = r2f32_get_size(s.verti.box->rect).y; f32 all_items_size = s.p.verti.max_size; f32 scroller_size = f32_clamp01(s.verti.item_box_pixels / (all_items_size + s.verti.item_box_pixels)); @@ -1062,41 +1030,81 @@ fn void ui_end_scroller(ui_scroller_t s) { } s.p.verti.value[0] = CLAMP(s.p.verti.value[0], 0, all_items_size); } +} - if (s.p.hori.enabled) ui_set_top(s.hori.box) { - f32 scroller_rect_pixels = r2f32_get_size(s.hori.box->rect).x; - f32 scroller_button_size_norm = f32_clamp01(scroller_rect_pixels / s.p.hori.max_size); - f32 scrollable_space = (1.f - scroller_button_size_norm); +fn ui_scroller_t ui_begin_scroller(ui_code_loc_t loc, ui_scroller_params_t p) { + ui_scroller_t s = {.p = p}; - f32 scroller_value_norm = s.p.hori.value[0] / s.p.hori.max_size; - f32 scroller_value_n = scroller_value_norm * scrollable_space; - 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]; - 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); + if (p.verti.enabled) { + s.verti.box = ui_box(.loc = loc, .rect = r2f32_cut_right(&p.parent->rect, ui_dm(0.5f)), .flags = {.draw_rect = true}); + r2f32_cut_bottom(&s.verti.box->rect, ui_dm(0.5f)); + s.verti.item_box_pixels = r2f32_get_size(p.parent->rect).y; + if (p.verti.item_count) { + s.p.verti.max_size = s.p.verti.item_pixels * s.p.verti.item_count; + ui_scroller_calc_vertical(s); - app_event_t *ev = ui->event; - f32 coef = f32_safe_ratio0((s.p.hori.max_size / scroller_rect_pixels), scrollable_space); + f32 visible_item_count = f32_ceil(s.verti.item_box_pixels / p.verti.item_pixels); + f32 render_start_count = f32_floor(p.verti.value[0] / p.verti.item_pixels); - if (signal.dragging) { - s.p.hori.value[0] += ev->mouse_delta.x * coef; + i32 istart = (i32)render_start_count; + i32 iend = (i32)render_start_count + (i32)visible_item_count; + s.verti.istart = CLAMP(istart, 0, (i32)p.verti.item_count); + s.verti.iend = CLAMP(iend, 0, (i32)p.verti.item_count); } - if (left_box_sig.dragging || right_box_sig.dragging) { - s.p.hori.value[0] = (ev->mouse_pos.x - left_box->rect.min.x) * coef; - s.p.hori.value[0] -= (r2f32_get_size(slider_box->rect).x / 2) * coef; - } - if (ev->kind == app_event_kind_mouse_wheel) { - s.p.hori.value[0] -= ev->mouse_wheel_delta.x; - } - - s.p.hori.value[0] = CLAMP(s.p.hori.value[0], 0, s.p.hori.max_size); } + if (p.hori.enabled) { + loc.counter += 10000; + s.hori.box = ui_box(.loc = loc, .rect = r2f32_cut_bottom(&p.parent->rect, ui_dm(0.5f)), .flags = {.draw_rect = true}); + } + + return s; +} + +fn void ui_cut_top_scroller_offset(ui_scroller_t s) { + r2f32_cut_top_no_squash(ui_top_rectp(), (f32)s.verti.istart * s.p.verti.item_pixels); +} + +fn void ui_end_scroller(ui_scroller_t s) { + if (s.p.verti.enabled && s.p.verti.item_count == 0) { + ui_scroller_calc_vertical(s); + } + + if (s.p.hori.enabled) { + ui_set_top(s.hori.box) { + f32 scroller_rect_pixels = r2f32_get_size(s.hori.box->rect).x; + f32 scroller_button_size_norm = f32_clamp01(scroller_rect_pixels / s.p.hori.max_size); + f32 scrollable_space = (1.f - scroller_button_size_norm); + + f32 scroller_value_norm = s.p.hori.value[0] / s.p.hori.max_size; + f32 scroller_value_n = scroller_value_norm * scrollable_space; + 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]; + 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); + + app_event_t *ev = ui->event; + f32 coef = f32_safe_ratio0((s.p.hori.max_size / scroller_rect_pixels), scrollable_space); + + if (signal.dragging) { + s.p.hori.value[0] += ev->mouse_delta.x * coef; + } + if (left_box_sig.dragging || right_box_sig.dragging) { + s.p.hori.value[0] = (ev->mouse_pos.x - left_box->rect.min.x) * coef; + s.p.hori.value[0] -= (r2f32_get_size(slider_box->rect).x / 2) * coef; + } + if (ev->kind == app_event_kind_mouse_wheel) { + s.p.hori.value[0] -= ev->mouse_wheel_delta.x; + } + + s.p.hori.value[0] = CLAMP(s.p.hori.value[0], 0, s.p.hori.max_size); + } + } ui_offset_children(s.p.parent, v2f32(s.p.hori.value ? s.p.hori.value[0] : 0, s.p.verti.value ? s.p.verti.value[0] : 0)); }