From 10d243055d60697382641b2a1aef11314e59409d Mon Sep 17 00:00:00 2001 From: Luka Jankovic Date: Tue, 24 Jun 2025 23:07:32 +0200 Subject: [PATCH] context state control and wall selection --- kubo_context.c | 59 +++++++++++++++++++++++++++++++++++-- kubo_context.h | 23 ++++++++++----- kubo_wall.c | 11 +++++-- kubo_wall.h | 5 ++-- kubo_window.c | 80 ++++++++++++++++++++++++++++++++++++++++---------- kubo_window.h | 6 +++- 6 files changed, 152 insertions(+), 32 deletions(-) diff --git a/kubo_context.c b/kubo_context.c index e30ba4d..d5050d3 100644 --- a/kubo_context.c +++ b/kubo_context.c @@ -26,6 +26,8 @@ struct kubo_context *kubo_context_init() { kubo_wall_arr_init(&context->walls); + context->wall_select_index = 0; + return context; } @@ -34,8 +36,33 @@ void kubo_context_cleanup(struct kubo_context *context) { free(context); } +void kubo_context_set_state(struct kubo_context *context, + enum kubo_context_state state) { + context->state = state; + + switch (context->state) { + case KUBO_CONTEXT_WALL_NEW: + break; + + case KUBO_CONTEXT_WALL_SELECT: + wall_select_refresh(context); + break; + + default: + break; + } +} + +const char *kubo_context_get_label(enum kubo_context_state state) { + return kubo_context_labels[state]; +} + struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context) { + if (context->state != KUBO_CONTEXT_WALL_NEW) { + return NULL; + } + if (context->walls.count > 0) { struct kubo_wall *last_wall = kubo_wall_arr_get(&context->walls, context->walls.count - 1); @@ -55,6 +82,34 @@ struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context) { return wall; } -const char *kubo_context_get_label(enum kubo_context_state state) { - return kubo_context_labels[state]; +void kubo_context_select_next_wall(struct kubo_context *context) { + if (context->state != KUBO_CONTEXT_WALL_SELECT || !context->walls.count) { + return; + } + + context->wall_select_index = + (context->wall_select_index + 1) % context->walls.count; + + wall_select_refresh(context); +} + +void kubo_context_select_prev_wall(struct kubo_context *context) { + if (context->state != KUBO_CONTEXT_WALL_SELECT || !context->walls.count) { + return; + } + + size_t count = context->walls.count; + + context->wall_select_index = + (context->wall_select_index + count - 1) % count; + + wall_select_refresh(context); +} + +static inline void wall_select_refresh(struct kubo_context *context) { + for (int i = 0; i < context->walls.count; i++) { + struct kubo_wall *wall = kubo_wall_arr_get(&context->walls, i); + wall->state = i == context->wall_select_index ? KUBO_WALL_SELECTED + : KUBO_WALL_DONE; + } } diff --git a/kubo_context.h b/kubo_context.h index 96e9ea0..4d15a07 100644 --- a/kubo_context.h +++ b/kubo_context.h @@ -29,26 +29,33 @@ KUBO_DYNARRAY_REGISTER(kubo_wall_arr, struct kubo_wall *); enum kubo_context_state { - KUBO_CONTEXT_STATE_WALL_NEW, - KUBO_CONTEXT_STATE_WALL_SELECT, + KUBO_CONTEXT_WALL_NEW, + KUBO_CONTEXT_WALL_SELECT, }; -static const char *kubo_context_labels[] = { - "Wall New", - "Wall Select" -}; +static const char *kubo_context_labels[] = {"Wall New", "Wall Select"}; struct kubo_context { bool exit_pending; struct kubo_wall_arr walls; enum kubo_context_state state; + + // KUBO_CONTEXT_WALL_SELECT + size_t wall_select_index; }; struct kubo_context *kubo_context_init(); void kubo_context_cleanup(struct kubo_context *context); -struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context); - +void kubo_context_set_state(struct kubo_context *context, + enum kubo_context_state state); const char *kubo_context_get_label(enum kubo_context_state state); +struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context); + +void kubo_context_select_next_wall(struct kubo_context *context); +void kubo_context_select_prev_wall(struct kubo_context *context); + +static inline void wall_select_refresh(struct kubo_context *context); + #endif diff --git a/kubo_wall.c b/kubo_wall.c index 586b4dd..6cefa8a 100644 --- a/kubo_wall.c +++ b/kubo_wall.c @@ -44,13 +44,18 @@ Vector2 kubo_wall_get_vertex(struct kubo_wall *wall, size_t index) { return kubo_vector2_arr_get(&wall->vertices, index); } -void kubo_wall_render(struct kubo_wall *wall) { - DrawSplineLinear(wall->vertices.data, wall->vertices.count, 10.f, BLACK); +void kubo_wall_render(struct kubo_wall *wall, bool select) { + + Color wall_color = + (select && wall->state == KUBO_WALL_SELECTED) ? BLUE : BLACK; + + DrawSplineLinear(wall->vertices.data, wall->vertices.count, 10.f, + wall_color); if (wall->state == KUBO_WALL_DRAWING) { Vector2 mouse = GetMousePosition(); Vector2 points[] = {wall->vertices.data[wall->vertices.count - 1], mouse}; - DrawSplineLinear(points, 2, 10.f, BLACK); + DrawSplineLinear(points, 2, 10.f, wall_color); } } diff --git a/kubo_wall.h b/kubo_wall.h index 976c466..52edf16 100644 --- a/kubo_wall.h +++ b/kubo_wall.h @@ -29,7 +29,8 @@ enum kubo_wall_state { KUBO_WALL_INIT, KUBO_WALL_DRAWING, - KUBO_WALL_DONE + KUBO_WALL_DONE, + KUBO_WALL_SELECTED }; KUBO_DYNARRAY_REGISTER(kubo_vector2_arr, Vector2) @@ -45,7 +46,7 @@ void kubo_wall_cleanup(struct kubo_wall *wall); bool kubo_wall_add_vertex(struct kubo_wall *wall, Vector2 vec); Vector2 kubo_wall_get_vertex(struct kubo_wall *wall, size_t index); -void kubo_wall_render(struct kubo_wall *wall); +void kubo_wall_render(struct kubo_wall *wall, bool select); #endif diff --git a/kubo_window.c b/kubo_window.c index cdb3457..5f55ff0 100644 --- a/kubo_window.c +++ b/kubo_window.c @@ -31,7 +31,12 @@ bool kubo_window_should_close(struct kubo_context *context) { void kubo_window_tick(struct kubo_context *context) { window_render(context); - window_mouse_input(context); + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + window_left_mouse(context); + } + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) { + window_right_mouse(context); + } window_key_input(context); } @@ -43,7 +48,7 @@ static void window_render(struct kubo_context *context) { struct kubo_wall *wall = kubo_wall_arr_get(&context->walls, i); assert(wall != NULL); - kubo_wall_render(wall); + kubo_wall_render(wall, context->state == KUBO_CONTEXT_WALL_SELECT); } kubo_bar_render(context); @@ -51,19 +56,23 @@ static void window_render(struct kubo_context *context) { EndDrawing(); } -static void window_mouse_input(struct kubo_context *context) { - int bar_limit = GetScreenHeight() - KUBO_BAR_HEIGHT; +static void window_left_mouse(struct kubo_context *context) { + switch (context->state) { + case KUBO_CONTEXT_WALL_NEW: + new_wall_click(context); + break; + case KUBO_CONTEXT_WALL_SELECT: + break; + } +} - struct kubo_wall *current_wall = kubo_context_get_pending_wall(context); - - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - Vector2 new_pos = GetMousePosition(); - if (new_pos.y < bar_limit) { - kubo_wall_add_vertex(current_wall, new_pos); - current_wall->state = KUBO_WALL_DRAWING; - } - } else if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) { - current_wall->state = KUBO_WALL_DONE; +static void window_right_mouse(struct kubo_context *context) { + switch (context->state) { + case KUBO_CONTEXT_WALL_NEW: + new_wall_end(context); + break; + case KUBO_CONTEXT_WALL_SELECT: + break; } } @@ -80,14 +89,53 @@ static void window_key_input(struct kubo_context *context) { break; case KEY_W: - context->state = KUBO_CONTEXT_STATE_WALL_NEW; + kubo_context_set_state(context, KUBO_CONTEXT_WALL_NEW); break; case KEY_S: - context->state = KUBO_CONTEXT_STATE_WALL_SELECT; + kubo_context_set_state(context, KUBO_CONTEXT_WALL_SELECT); + break; + + case KEY_RIGHT: + case KEY_UP: + case KEY_L: + case KEY_K: + kubo_context_select_next_wall(context); + break; + + case KEY_LEFT: + case KEY_DOWN: + case KEY_J: + case KEY_H: + kubo_context_select_prev_wall(context); break; default: break; } } + +static void new_wall_click(struct kubo_context *context) { + struct kubo_wall *current_wall = kubo_context_get_pending_wall(context); + + if (!current_wall) { + return; + } + + int bar_limit = GetScreenHeight() - KUBO_BAR_HEIGHT; + Vector2 new_pos = GetMousePosition(); + if (new_pos.y < bar_limit) { + kubo_wall_add_vertex(current_wall, new_pos); + current_wall->state = KUBO_WALL_DRAWING; + } +} + +static void new_wall_end(struct kubo_context *context) { + struct kubo_wall *current_wall = kubo_context_get_pending_wall(context); + + if (!current_wall) { + return; + } + + current_wall->state = KUBO_WALL_DONE; +} diff --git a/kubo_window.h b/kubo_window.h index 97b8038..57c1d79 100644 --- a/kubo_window.h +++ b/kubo_window.h @@ -36,7 +36,11 @@ bool kubo_window_should_close(struct kubo_context *context); void kubo_window_tick(struct kubo_context *context); static void window_render(struct kubo_context *context); -static void window_mouse_input(struct kubo_context *context); +static void window_left_mouse(struct kubo_context *context); +static void window_right_mouse(struct kubo_context *context); static void window_key_input(struct kubo_context *context); +static void new_wall_click(struct kubo_context *context); +static void new_wall_end(struct kubo_context *context); + #endif