UI system improvements, event handling

This commit is contained in:
2025-06-07 12:31:35 +02:00
parent 04b28f0bcb
commit d6920acd38
17 changed files with 292 additions and 91 deletions
+91 -12
View File
@@ -3,8 +3,10 @@
extern SDL_Window *sdl_window;
extern float delta_time;
extern int n_frame_ents, n_frame_chunks;
extern vec3 camera_position;
static UIElement *ui_root;
static UIElement *hovered_element;
void
uiman_init ()
@@ -13,26 +15,47 @@ uiman_init ()
ui_root = UIElement_root_new ();
UIElement *container = UIElement_container_new (false);
container->scale[0] = 0.4;
container->scale[1] = 0.07;
container->position[0] = -0.5;
container->position[1] = 0.83;
glm_vec3_copy ((vec4) { 1.0, 0.0, 0.0, 1.0 }, container->background_color);
UIElement_set_position (container, -0.5, 0.75);
UIElement_set_scale (container, 0.4, 0.15);
UIElement_set_background_color (container, 1.0, 0.0, 0.0, 1.0);
UIElement *frame_time = UIElement_label_new ("Frame time: ");
UIElement *container2 = UIElement_container_new (true);
UIElement_set_on_tick (frame_time, uicb_label_show_float, &delta_time);
UIElement *game_name = UIElement_label_new (NULL);
UIElement_label_printf (game_name, "%s %s", GAME_NAME, GAME_VERSION);
UIElement *entities_rendered = UIElement_label_new ("Entities rendered: ");
UIElement *chunks_rendered = UIElement_label_new ("Chunks rendered: ");
UIElement_set_on_tick (entities_rendered, uicb_label_show_int, &n_frame_ents);
UIElement_set_on_tick (chunks_rendered, uicb_label_show_int, &n_frame_chunks);
UIElement_set_on_tick (frame_time, UILabel_on_tick_show_float, &delta_time);
UIElement_set_on_tick (entities_rendered, UILabel_on_tick_show_int, &n_frame_ents);
UIElement_set_on_tick (chunks_rendered, UILabel_on_tick_show_int, &n_frame_chunks);
UIElement *container2 = UIElement_container_new (true);
UIElement_add_child (container2, entities_rendered);
UIElement_add_child (container2, chunks_rendered);
UIElement *pos_x = UIElement_label_new ("X: ");
UIElement *pos_y = UIElement_label_new ("Y: ");
UIElement *pos_z = UIElement_label_new ("Z: ");
UIElement_set_on_tick (pos_x, uicb_label_show_float, &camera_position[0]);
UIElement_set_on_tick (pos_y, uicb_label_show_float, &camera_position[1]);
UIElement_set_on_tick (pos_z, uicb_label_show_float, &camera_position[2]);
UIElement *container3 = UIElement_container_new (true);
UIElement_add_child (container3, pos_x);
UIElement_add_child (container3, pos_y);
UIElement_add_child (container3, pos_z);
UIElement *wireframe_button = UIElement_label_new ("Toggle wireframe");
UIElement_set_background_color (wireframe_button, 0.2, 0.2, 0.2, 1.0);
UIElement_set_hover_background_color (wireframe_button, 0.3, 0.3, 0.3, 1.0);
UIElement_set_on_left_click (wireframe_button, uicb_flag_switch, "wireframe_enabled");
UIElement_add_child (container, game_name);
UIElement_add_child (container, frame_time);
UIElement_add_child (container, container2);
UIElement_add_child (container, container3);
UIElement_add_child (container, wireframe_button);
UIElement_add_child (ui_root, container);
}
@@ -49,6 +72,12 @@ uiman_render ()
UIElement_render (ui_root);
}
static inline void
screen_to_ui_coords (int mouse_x, int mouse_y, int screen_w, int screen_h, vec2 out_coords) {
out_coords[0] = (float) mouse_x / (float) screen_w * 2.0 - 1.0;
out_coords[1] = 1.0 - (float) mouse_y / (float) screen_h * 2.0;
}
bool
uiman_cb_switch_focus (SDL_Event *event, void *data)
{
@@ -75,14 +104,64 @@ uiman_cb_key_up (SDL_Event *event, void *data)
bool
uiman_cb_mouse_motion (SDL_Event *event, void *data)
{
UNUSED (event, data);
/* What even is in data at this point? No fucking idea. */
UNUSED (data);
int win_w, win_h;
SDL_GetWindowSize (sdl_window, &win_w, &win_h);
vec2 ui_pos;
screen_to_ui_coords (event->motion.x, event->motion.y, win_w, win_h, ui_pos);
UIElement *element = UIElement_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos);
if (element != hovered_element)
{
if (hovered_element)
{
hovered_element->hovered = false;
}
if (element)
{
element->hovered = true;
}
hovered_element = element;
}
/* This callback always eats the event, because why would the game
need mouse motion if the UI has stolen the focus? */
return true;
}
bool
uiman_cb_button_down (SDL_Event *event, void *data)
{
UNUSED (event, data);
UNUSED (data);
int win_w, win_h;
SDL_GetWindowSize (sdl_window, &win_w, &win_h);
vec2 ui_pos;
screen_to_ui_coords (event->motion.x, event->motion.y, win_w, win_h, ui_pos);
UIElement *element = UIElement_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos);
if (element)
{
if (event->button.button == SDL_BUTTON_LEFT && element->on_left_click)
{
element->on_left_click (element, element->userdata);
return true;
}
if (event->button.button == SDL_BUTTON_RIGHT && element->on_right_click)
{
element->on_right_click (element, element->userdata);
return true;
}
}
return false;
}