improving scroller
This commit is contained in:
@@ -45,16 +45,61 @@ fn b32 app_update(app_frame_t *frame) {
|
|||||||
assert(frame->first_event);
|
assert(frame->first_event);
|
||||||
|
|
||||||
for (app_event_t *ev = frame->first_event; ev; ev = ev->next) {
|
for (app_event_t *ev = frame->first_event; ev; ev = ev->next) {
|
||||||
static f32 scroller_percent;
|
static f32 scroller_value;
|
||||||
defer_block(ui_begin_build(UI_CODE_LOC, ev), ui_end_build()) {
|
defer_block(ui_begin_build(UI_CODE_LOC, ev), ui_end_build()) {
|
||||||
defer_block(ui_push_xcontainer(UI_CODE_LOC, ui_em(25), ui_em(30)), ui_pop_parent()) {
|
defer_block(ui_push_xcontainer(UI_CODE_LOC, ui_em(25), ui_em(30)), ui_pop_parent()) {
|
||||||
|
|
||||||
ui_box_t *container = ui_push_container(UI_CODE_LOC, ui_percent(0.97f), ui_percent(1));
|
|
||||||
set_flag1(container->flags, ui_box_flag_scroll);
|
|
||||||
container->view_offset.y = scroller_percent * frame->window_size.y;//r2f32_get_size(container->rect).y;
|
|
||||||
defer_block(container, ui_pop_parent()) {
|
|
||||||
|
|
||||||
// ui_offset_all_entries_by(scroller_percent);
|
ui_box_t *item_box = ui_build_box_from_string(UI_CODE_LOC, flag3(ui_box_flag_scroll, ui_box_flag_draw_rect, ui_box_flag_draw_border), s8_lit("scrolled item_box"));
|
||||||
|
ui_set_semantic_size(item_box, ui_percent(0.97f), ui_percent(1));
|
||||||
|
item_box->grow_axis = ui_axis2_y;
|
||||||
|
defer_block(ui_push_parent(item_box), ui_pop_parent()) {
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "app_event_t").clicked, ui_pop_exp()) {
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "mouse_wheel_delta: v3f64_t").clicked, ui_pop_exp()) {
|
||||||
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "z: f64 = value");
|
||||||
|
}
|
||||||
|
ui_label(UI_CODE_LOC, "kind: app_event_kind_t = value");
|
||||||
|
ui_label(UI_CODE_LOC, "ctrl: b8 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "shift: b8 = value");
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "pos: v2f64_t").clicked, ui_pop_exp()) {
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "inner_pos: v2f64_t##asd").clicked, ui_pop_exp()) {
|
||||||
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
}
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "inner_pos: v2f64_t##qwe").clicked, ui_pop_exp()) {
|
||||||
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
}
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
}
|
||||||
|
ui_label(UI_CODE_LOC, "alt: b8 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "meta: b8 = value");
|
||||||
|
}
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "app_event_t").clicked, ui_pop_exp()) {
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "mouse_wheel_delta: v3f64_t").clicked, ui_pop_exp()) {
|
||||||
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "z: f64 = value");
|
||||||
|
}
|
||||||
|
ui_label(UI_CODE_LOC, "kind: app_event_kind_t = value");
|
||||||
|
ui_label(UI_CODE_LOC, "ctrl: b8 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "shift: b8 = value");
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "pos: v2f64_t").clicked, ui_pop_exp()) {
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "inner_pos: v2f64_t##asd").clicked, ui_pop_exp()) {
|
||||||
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
}
|
||||||
|
defer_if (ui_push_exp(UI_CODE_LOC, "inner_pos: v2f64_t##qwe").clicked, ui_pop_exp()) {
|
||||||
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
}
|
||||||
|
ui_label(UI_CODE_LOC, "y: f64 = value");
|
||||||
|
}
|
||||||
|
ui_label(UI_CODE_LOC, "alt: b8 = value");
|
||||||
|
ui_label(UI_CODE_LOC, "meta: b8 = value");
|
||||||
|
}
|
||||||
defer_if (ui_push_exp(UI_CODE_LOC, "app_event_t").clicked, ui_pop_exp()) {
|
defer_if (ui_push_exp(UI_CODE_LOC, "app_event_t").clicked, ui_pop_exp()) {
|
||||||
defer_if (ui_push_exp(UI_CODE_LOC, "mouse_wheel_delta: v3f64_t").clicked, ui_pop_exp()) {
|
defer_if (ui_push_exp(UI_CODE_LOC, "mouse_wheel_delta: v3f64_t").clicked, ui_pop_exp()) {
|
||||||
ui_label(UI_CODE_LOC, "x: f64 = value");
|
ui_label(UI_CODE_LOC, "x: f64 = value");
|
||||||
@@ -78,24 +123,31 @@ fn b32 app_update(app_frame_t *frame) {
|
|||||||
ui_label(UI_CODE_LOC, "alt: b8 = value");
|
ui_label(UI_CODE_LOC, "alt: b8 = value");
|
||||||
ui_label(UI_CODE_LOC, "meta: b8 = value");
|
ui_label(UI_CODE_LOC, "meta: b8 = value");
|
||||||
}
|
}
|
||||||
// pop ui_offset_all_entries_by(scroller_percent);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroller
|
// scroller
|
||||||
{
|
{
|
||||||
ui_push_container(UI_CODE_LOC, ui_percent(0.03f), ui_percent(1));
|
|
||||||
f32 scroller_size = 0.1f;
|
|
||||||
f32 scroller_second = (1 - scroller_size) - scroller_percent;
|
|
||||||
|
|
||||||
|
f32 all_items_size = (f32)item_box->node_count * get_font_size();
|
||||||
|
f32 item_box_size = r2f32_get_size(item_box->rect).y;
|
||||||
|
|
||||||
|
f32 scroller_size = CLAMP(item_box_size / all_items_size, 0, 1.0f);
|
||||||
|
f32 scrollable_space = (1 - scroller_size);
|
||||||
|
f32 scroller_percent = scroller_value * scrollable_space;
|
||||||
|
f32 inV_scroller_percent = 1.f / scroller_percent;
|
||||||
|
f32 scroller_second = scrollable_space - scroller_percent;
|
||||||
|
|
||||||
|
ui_push_container(UI_CODE_LOC, ui_percent(0.03f), ui_percent(1));
|
||||||
ui_spacer(UI_CODE_LOC, ui_percent(1), ui_percent(scroller_percent));
|
ui_spacer(UI_CODE_LOC, ui_percent(1), ui_percent(scroller_percent));
|
||||||
ui_signal_t sig = ui_scroller_button(UI_CODE_LOC, ui_percent(1), ui_percent(scroller_size));
|
ui_signal_t sig = ui_scroller_button(UI_CODE_LOC, ui_percent(1), ui_percent(scroller_size));
|
||||||
if (sig.dragging) {
|
if (sig.dragging) {
|
||||||
scroller_percent += (ev->mouse_delta.y / frame->window_size.y);
|
scroller_value += (ev->mouse_delta.y / item_box_size * 2);
|
||||||
scroller_percent = CLAMP(scroller_percent, 0, 0.9f);
|
|
||||||
}
|
}
|
||||||
|
scroller_value = CLAMP(scroller_value, 0, 1.0f);
|
||||||
ui_spacer(UI_CODE_LOC, ui_percent(1), ui_percent(scroller_second));
|
ui_spacer(UI_CODE_LOC, ui_percent(1), ui_percent(scroller_second));
|
||||||
ui_pop_parent();
|
ui_pop_parent();
|
||||||
|
|
||||||
|
item_box->view_offset.y = scroller_value * (all_items_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,9 +48,10 @@ fn ui_box_t *ui_alloc_box(void) {
|
|||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void ui_push_box(ui_box_t *box) {
|
fn void ui_push(ui_box_t *parent, ui_box_t *box) {
|
||||||
box->parent = ui->top;
|
box->parent = parent;
|
||||||
DLLQ_APPEND(ui->top->first, ui->top->last, box);
|
DLLQ_APPEND(parent->first, parent->last, box);
|
||||||
|
parent->node_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void ui_set_semantic_size(ui_box_t *box, ui_size_t x, ui_size_t y) {
|
fn void ui_set_semantic_size(ui_box_t *box, ui_size_t x, ui_size_t y) {
|
||||||
@@ -62,7 +63,7 @@ fn s8_t ui_tprint_loc(ui_code_loc_t loc) {
|
|||||||
return s8_printf(tcx.temp, "%s(%d)", loc.file, loc.line);
|
return s8_printf(tcx.temp, "%s(%d)", loc.file, loc.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_box_t *ui_build_box_from_id(ui_code_loc_t loc, ui_id_t id, ui_box_flag_t flags) {
|
fn ui_box_t *ui_build_box_from_id(ui_code_loc_t loc, ui_box_flag_t flags, ui_id_t id) {
|
||||||
ui_box_t *box = ui_find_box(id);
|
ui_box_t *box = ui_find_box(id);
|
||||||
if (box) {
|
if (box) {
|
||||||
expect (box->last_touched_event_id != ui->event->id) {
|
expect (box->last_touched_event_id != ui->event->id) {
|
||||||
@@ -78,7 +79,7 @@ fn ui_box_t *ui_build_box_from_id(ui_code_loc_t loc, ui_id_t id, ui_box_flag_t f
|
|||||||
box->last_touched_event_id = ui->event->id;
|
box->last_touched_event_id = ui->event->id;
|
||||||
box->id = id;
|
box->id = id;
|
||||||
box->flags = flags;
|
box->flags = flags;
|
||||||
ui_push_box(box);
|
ui_push(ui->top, box);
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +106,9 @@ fn ui_id_t ui_gen_id(ui_id_strategy_t strat, ui_code_loc_t loc, s8_t string) {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_box_t *ui_build_box_from_string(ui_code_loc_t loc, s8_t string, ui_box_flag_t flags) {
|
fn ui_box_t *ui_build_box_from_string(ui_code_loc_t loc, ui_box_flag_t flags, s8_t string) {
|
||||||
ui_id_t id = ui_gen_id(ui->id_strategy, loc, ui_get_hash_string(string));
|
ui_id_t id = ui_gen_id(ui->id_strategy, loc, ui_get_hash_string(string));
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, id, flags);
|
ui_box_t *box = ui_build_box_from_id(loc, flags, id);
|
||||||
box->string = ui_get_display_string(string);
|
box->string = ui_get_display_string(string);
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
@@ -188,7 +189,7 @@ fn void ui_begin_frame(app_frame_t *frame) {
|
|||||||
ui->frame = frame;
|
ui->frame = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void ui_push_top(ui_box_t *box) {
|
fn void ui_push_parent(ui_box_t *box) {
|
||||||
ui->top = box;
|
ui->top = box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,22 +200,22 @@ fn ui_box_t *ui_pop_parent(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ui_box_t *ui_spacer(ui_code_loc_t loc, ui_size_t x, ui_size_t y) {
|
fn ui_box_t *ui_spacer(ui_code_loc_t loc, ui_size_t x, ui_size_t y) {
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, ui_null_id, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_border));
|
ui_box_t *box = ui_build_box_from_id(loc, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_border), ui_null_id);
|
||||||
ui_set_semantic_size(box, x, y);
|
ui_set_semantic_size(box, x, y);
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_signal_t ui_scroller_button(ui_code_loc_t loc, ui_size_t x, ui_size_t y) {
|
fn ui_signal_t ui_scroller_button(ui_code_loc_t loc, ui_size_t x, ui_size_t y) {
|
||||||
ui_id_t id = ui_gen_id(flag2(ui_id_strategy_use_code_loc, ui_id_strategy_use_string), loc, s8_lit("spacer"));
|
ui_id_t id = ui_gen_id(flag2(ui_id_strategy_use_code_loc, ui_id_strategy_use_string), loc, s8_lit("spacer"));
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, id, flag3(ui_box_flag_draw_scroller, ui_box_flag_draw_rect, ui_box_flag_draw_border));
|
ui_box_t *box = ui_build_box_from_id(loc, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_border), id);
|
||||||
ui_set_semantic_size(box, x, y);
|
ui_set_semantic_size(box, x, y);
|
||||||
ui_signal_t signal = ui_signal_from_box(box);
|
ui_signal_t signal = ui_signal_from_box(box);
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui_box_t *ui_push_container(ui_code_loc_t loc, ui_size_t x, ui_size_t y) {
|
fn ui_box_t *ui_push_container(ui_code_loc_t loc, ui_size_t x, ui_size_t y) {
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, ui_null_id, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_border));
|
ui_box_t *box = ui_build_box_from_id(loc, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_border), ui_null_id);
|
||||||
ui_push_top(box);
|
ui_push_parent(box);
|
||||||
ui_set_semantic_size(box, x, y);
|
ui_set_semantic_size(box, x, y);
|
||||||
box->grow_axis = ui_axis2_y;
|
box->grow_axis = ui_axis2_y;
|
||||||
return box;
|
return box;
|
||||||
@@ -234,7 +235,7 @@ fn void ui_set_indented_string(ui_box_t *box, s8_t string) { box->string = s8_pr
|
|||||||
|
|
||||||
fn ui_signal_t ui_push_exp(ui_code_loc_t loc, char *str, ...) {
|
fn ui_signal_t ui_push_exp(ui_code_loc_t loc, char *str, ...) {
|
||||||
S8_FMT(tcx.temp, str, string);
|
S8_FMT(tcx.temp, str, string);
|
||||||
ui_box_t *box = ui_build_box_from_string(loc, string, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_text));
|
ui_box_t *box = ui_build_box_from_string(loc, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_text), string);
|
||||||
ui_set_semantic_size(box, ui_percent(1), ui_text());
|
ui_set_semantic_size(box, ui_percent(1), ui_text());
|
||||||
|
|
||||||
if (box->created_new) box->expanded = true;
|
if (box->created_new) box->expanded = true;
|
||||||
@@ -261,7 +262,7 @@ fn void ui_pop_exp(void) {
|
|||||||
|
|
||||||
fn ui_box_t *ui_label(ui_code_loc_t loc, char *fmt, ...) {
|
fn ui_box_t *ui_label(ui_code_loc_t loc, char *fmt, ...) {
|
||||||
S8_FMT(tcx.temp, fmt, string);
|
S8_FMT(tcx.temp, fmt, string);
|
||||||
ui_box_t *box = ui_build_box_from_id(loc, ui_null_id, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_text));
|
ui_box_t *box = ui_build_box_from_id(loc, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_text), ui_null_id);
|
||||||
ui_set_indented_string(box, string);
|
ui_set_indented_string(box, string);
|
||||||
ui_set_semantic_size(box, ui_text(), ui_text());
|
ui_set_semantic_size(box, ui_text(), ui_text());
|
||||||
return box;
|
return box;
|
||||||
@@ -300,7 +301,6 @@ fn void ui_layout(void) {
|
|||||||
for (ui_axis2_t axis = 0; axis < ui_axis2_count; axis += 1) {
|
for (ui_axis2_t axis = 0; axis < ui_axis2_count; axis += 1) {
|
||||||
ui_size_t sem = box->semantic_size[axis];
|
ui_size_t sem = box->semantic_size[axis];
|
||||||
if (sem.kind == ui_size_kind_percent_of_parent) {
|
if (sem.kind == ui_size_kind_percent_of_parent) {
|
||||||
assert(sem.value >= 0 && sem.value <= 1.0);
|
|
||||||
assert(parent->semantic_size[axis].kind == ui_size_kind_pixels ||
|
assert(parent->semantic_size[axis].kind == ui_size_kind_pixels ||
|
||||||
parent->semantic_size[axis].kind == ui_size_kind_text_content ||
|
parent->semantic_size[axis].kind == ui_size_kind_text_content ||
|
||||||
parent->semantic_size[axis].kind == ui_size_kind_percent_of_parent);
|
parent->semantic_size[axis].kind == ui_size_kind_percent_of_parent);
|
||||||
@@ -382,8 +382,5 @@ fn void ui_draw(void) {
|
|||||||
if (is_flag_set(box->flags, ui_box_flag_draw_text)) {
|
if (is_flag_set(box->flags, ui_box_flag_draw_text)) {
|
||||||
rn_draw_string(font, box->rect.min, black_color_global, box->string);
|
rn_draw_string(font, box->rect.min, black_color_global, box->string);
|
||||||
}
|
}
|
||||||
if (is_flag_set(box->flags, ui_box_flag_draw_scroller)) {
|
|
||||||
rn_draw_string(font, box->rect.min, black_color_global, s8_lit("s"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ enum {
|
|||||||
ui_box_flag_draw_border,
|
ui_box_flag_draw_border,
|
||||||
ui_box_flag_draw_text,
|
ui_box_flag_draw_text,
|
||||||
ui_box_flag_draw_rect,
|
ui_box_flag_draw_rect,
|
||||||
ui_box_flag_draw_scroller,
|
|
||||||
|
|
||||||
ui_box_flag_scroll,
|
ui_box_flag_scroll,
|
||||||
};
|
};
|
||||||
@@ -71,6 +70,8 @@ struct ui_box_t {
|
|||||||
ui_box_t *parent;
|
ui_box_t *parent;
|
||||||
ui_box_t *first;
|
ui_box_t *first;
|
||||||
ui_box_t *last;
|
ui_box_t *last;
|
||||||
|
i32 node_count;
|
||||||
|
|
||||||
ui_box_flag_t flags;
|
ui_box_flag_t flags;
|
||||||
s8_t string;
|
s8_t string;
|
||||||
ui_size_t semantic_size[ui_axis2_count];
|
ui_size_t semantic_size[ui_axis2_count];
|
||||||
@@ -78,14 +79,16 @@ struct ui_box_t {
|
|||||||
ui_code_loc_t loc;
|
ui_code_loc_t loc;
|
||||||
b32 created_new;
|
b32 created_new;
|
||||||
|
|
||||||
|
// layout
|
||||||
|
f32 iter_pos[ui_axis2_count];
|
||||||
|
|
||||||
// preserving state
|
// preserving state
|
||||||
ui_id_t id; // important position!: offset(id) used for partial zeroing
|
ui_id_t id; // important position!: offset(id) used for partial zeroing
|
||||||
u64 last_touched_event_id;
|
u64 last_touched_event_id;
|
||||||
ui_box_t *hash_next;
|
ui_box_t *hash_next;
|
||||||
ui_box_t *hash_prev;
|
ui_box_t *hash_prev;
|
||||||
|
|
||||||
// computed by layout system every frame
|
// layout
|
||||||
f32 iter_pos[ui_axis2_count];
|
|
||||||
f32 computed_rel_pos[ui_axis2_count];
|
f32 computed_rel_pos[ui_axis2_count];
|
||||||
f32 computed_size[ui_axis2_count];
|
f32 computed_size[ui_axis2_count];
|
||||||
r2f32_t rect;
|
r2f32_t rect;
|
||||||
|
|||||||
Reference in New Issue
Block a user