ui delta mouse, dragging scroller

This commit is contained in:
Krzosa Karol
2025-01-13 11:11:10 +01:00
parent b4d3f20cad
commit 8c25a7f39c
7 changed files with 60 additions and 16 deletions

View File

@@ -266,8 +266,9 @@ type_t type__app_event_t = { type_kind_struct, s8_const_lit("app_event_t"), size
{.name = s8_const_lit("shift"), .type = &type__b8, .offset = offsetof(app_event_t, shift), .dont_serialize = 0}, {.name = s8_const_lit("shift"), .type = &type__b8, .offset = offsetof(app_event_t, shift), .dont_serialize = 0},
{.name = s8_const_lit("alt"), .type = &type__b8, .offset = offsetof(app_event_t, alt), .dont_serialize = 0}, {.name = s8_const_lit("alt"), .type = &type__b8, .offset = offsetof(app_event_t, alt), .dont_serialize = 0},
{.name = s8_const_lit("mouse_pos"), .type = &type__v2f32_t, .offset = offsetof(app_event_t, mouse_pos), .dont_serialize = 0}, {.name = s8_const_lit("mouse_pos"), .type = &type__v2f32_t, .offset = offsetof(app_event_t, mouse_pos), .dont_serialize = 0},
{.name = s8_const_lit("mouse_delta"), .type = &type__v2f32_t, .offset = offsetof(app_event_t, mouse_delta), .dont_serialize = 0},
}, },
.count = 11, .count = 12,
}; };
type_t type__app_frame_t = { type_kind_struct, s8_const_lit("app_frame_t"), sizeof(app_frame_t), type_t type__app_frame_t = { type_kind_struct, s8_const_lit("app_frame_t"), sizeof(app_frame_t),
.members = (type_member_t[]){ .members = (type_member_t[]){

View File

@@ -104,6 +104,7 @@ struct app_event_t {
b8 shift; b8 shift;
b8 alt; b8 alt;
v2f32_t mouse_pos; v2f32_t mouse_pos;
v2f32_t mouse_delta;
}; };
typedef struct app_frame_t app_frame_t; typedef struct app_frame_t app_frame_t;

View File

@@ -175,6 +175,7 @@ void meta_app(ma_arena_t *arena) {
b8 shift; b8 shift;
b8 alt; b8 alt;
v2f32_t mouse_pos; v2f32_t mouse_pos;
v2f32_t mouse_delta;
}; };
typedef struct app_frame_t app_frame_t; typedef struct app_frame_t app_frame_t;

View File

@@ -60,12 +60,17 @@ fn f64 w32_seconds_now(void) {
gb app_frame_t *w32_frame; gb app_frame_t *w32_frame;
gb ma_arena_t *w32_event_arena; gb ma_arena_t *w32_event_arena;
gb u64 w32_event_id; gb u64 w32_event_id;
gb v2f32_t w32_last_mouse;
fn void w32_push_event(app_frame_t *frame, app_event_t event) { fn void w32_push_event(app_frame_t *frame, app_event_t event) {
app_event_t *ev = ma_push_type(w32_event_arena, app_event_t); app_event_t *ev = ma_push_type(w32_event_arena, app_event_t);
*ev = event; *ev = event;
ev->id = ++w32_event_id; ev->id = ++w32_event_id;
ev->mouse_pos = w32_get_mouse_pos(w32_window_handle); {
v2f32_t new_pos = w32_get_mouse_pos(w32_window_handle);
ev->mouse_delta = v2f32_sub(new_pos, w32_last_mouse);
ev->mouse_pos = w32_last_mouse = new_pos;
}
if (GetKeyState(VK_CONTROL) & 0x8000) ev->ctrl = true; if (GetKeyState(VK_CONTROL) & 0x8000) ev->ctrl = true;
if (GetKeyState(VK_SHIFT) & 0x8000) ev->shift = true; if (GetKeyState(VK_SHIFT) & 0x8000) ev->shift = true;
@@ -367,12 +372,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
u64 frame_counter = 0; u64 frame_counter = 0;
for (;;) { for (;;) {
app_frame_t frame = {0}; app_frame_t frame = {0};
frame.window_size = w32_get_window_size(w32_window_handle);
frame.dpr = w32_get_dpr(w32_window_handle);
frame.mouse_pos = w32_get_mouse_pos(w32_window_handle);
frame.delta = time_delta;
frame.update = time_update;
frame.frame = frame_counter;
b32 waited = w32_get_events(tcx.temp, &frame, wait_for_events); b32 waited = w32_get_events(tcx.temp, &frame, wait_for_events);
if (waited) { if (waited) {
@@ -389,6 +388,13 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
w32_push_event(&frame, (app_event_t){.kind = app_event_kind_update}); w32_push_event(&frame, (app_event_t){.kind = app_event_kind_update});
} }
frame.window_size = w32_get_window_size(w32_window_handle);
frame.dpr = w32_get_dpr(w32_window_handle);
frame.mouse_pos = frame.last_event->mouse_pos;
frame.delta = time_delta;
frame.update = time_update;
frame.frame = frame_counter;
b32 animating = app_update(&frame); b32 animating = app_update(&frame);
wait_for_events = !animating; wait_for_events = !animating;

View File

@@ -87,6 +87,17 @@ fn b32 app_update(app_frame_t *frame) {
// scroller // scroller
{ {
ui_push_container(UI_CODE_LOC, ui_percent(3), ui_percent(100)); ui_push_container(UI_CODE_LOC, ui_percent(3), ui_percent(100));
static f32 scroller_percent;
f32 scroller_first = scroller_percent;
f32 scroller_second = 90 - scroller_percent;
ui_spacer(UI_CODE_LOC, ui_percent(100), ui_percent(scroller_first));
ui_signal_t sig = ui_scroller_button(UI_CODE_LOC, ui_percent(100), ui_percent(10));
if (sig.dragging) {
scroller_percent += (ev->mouse_delta.y / frame->window_size.y) * 100;
scroller_percent = CLAMP(scroller_percent, 0, 90);
}
ui_spacer(UI_CODE_LOC, ui_percent(100), ui_percent(scroller_second));
ui_pop_parent(); ui_pop_parent();
} }
} }
@@ -96,7 +107,7 @@ fn b32 app_update(app_frame_t *frame) {
rn_begin(); rn_begin();
ui_draw(); ui_draw();
rn_draw_stringf(&rn_state.main_font, v2f32(0,frame->window_size.y - 100), black_color_global, "ui_boxes: %d delta: %f update: %f event_count: %d", ui->allocated_boxes, frame->delta, frame->update, frame->event_count); rn_draw_stringf(&rn_state.main_font, v2f32(0,frame->window_size.y - 100), black_color_global, "ui_boxes: %d delta: %f update: %f event_count: %d, delta: %f %f", ui->allocated_boxes, frame->delta, frame->update, frame->event_count, frame->last_event->mouse_delta.x, frame->last_event->mouse_delta.y);
rn_end(frame->window_size, white_color_global); rn_end(frame->window_size, white_color_global);
ui_end_frame(); ui_end_frame();

View File

@@ -113,13 +113,14 @@ fn ui_box_t *ui_build_box_from_string(ui_code_loc_t loc, s8_t string, ui_box_fla
} }
fn ui_signal_t ui_signal_from_box(ui_box_t *box) { fn ui_signal_t ui_signal_from_box(ui_box_t *box) {
ui_signal_t result = {0}; ui_signal_t result = {box};
app_event_t *ev = ui->event; app_event_t *ev = ui->event;
b32 move = ev->kind == app_event_kind_mouse_move; b32 move = ev->kind == app_event_kind_mouse_move;
b32 inside = r2f32_contains(box->rect, ev->mouse_pos); b32 inside = r2f32_contains(box->rect, ev->mouse_pos);
if (ui_is_active_box(box)) { if (ui_is_active_box(box)) {
result.dragging = true;
if (ev_left_up(ev)) { if (ev_left_up(ev)) {
if (ui_is_hot_box(box)) { if (ui_is_hot_box(box)) {
result.clicked = true; result.clicked = true;
@@ -197,6 +198,20 @@ fn ui_box_t *ui_pop_parent(void) {
return top; return top;
} }
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_set_semantic_size(box, x, y);
return box;
}
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_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_set_semantic_size(box, x, y);
ui_signal_t signal = ui_signal_from_box(box);
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, ui_null_id, flag2(ui_box_flag_draw_rect, ui_box_flag_draw_border));
ui_push_top(box); ui_push_top(box);
@@ -267,8 +282,10 @@ fn void ui_draw(void) {
// compute standalone sizes: (pixels, text_content) // compute standalone sizes: (pixels, text_content)
for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) { for (ui_preorder_iter_t it = ui_iterate_preorder(ui->root); ui_preorder_iter_is_valid(it); ui_iter_advance_preorder(&it)) {
ui_box_t *box = it.box; ui_box_t *box = it.box;
if (box == ui->root) continue; // @todo: remove somehow
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];
assert(sem.kind != ui_size_kind_null);
if (sem.kind == ui_size_kind_pixels) { if (sem.kind == ui_size_kind_pixels) {
box->computed_size[axis] = sem.value; box->computed_size[axis] = sem.value;
} else if (sem.kind == ui_size_kind_text_content) { } else if (sem.kind == ui_size_kind_text_content) {
@@ -284,7 +301,7 @@ fn void ui_draw(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 <= 100.0); // assert(sem.value >= 0 && sem.value <= 100.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);
@@ -356,5 +373,8 @@ 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"));
}
} }
} }

View File

@@ -57,6 +57,7 @@ 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,
}; };
typedef struct ui_box_t ui_box_t; typedef struct ui_box_t ui_box_t;
@@ -92,13 +93,16 @@ struct ui_box_t {
typedef struct ui_signal_t ui_signal_t; typedef struct ui_signal_t ui_signal_t;
struct ui_signal_t { struct ui_signal_t {
ui_box_t *box;
b8 clicked; b8 clicked;
b8 double_clicked;
b8 right_clicked;
b8 pressed;
b8 released;
b8 dragging; b8 dragging;
b8 hovering;
// b8 double_clicked;
// b8 right_clicked;
// b8 pressed;
// b8 released;
// b8 dragging;
// b8 hovering;
}; };
typedef enum { typedef enum {