fix fixed size scroller lag

This commit is contained in:
Krzosa Karol
2025-02-05 08:53:16 +01:00
parent 22685cbbd3
commit 99317440b3

View File

@@ -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));
}