Files
wschod/game/src/ui/uiman.c
T
2025-06-08 20:45:48 +02:00

207 lines
5.8 KiB
C

#include "uiman.h"
extern SDL_Window *sdl_window;
extern float delta_time;
extern int n_frame_ents, n_frame_chunks;
extern vec3 camera_position;
static Widget *ui_root;
static Widget *hovered_widget;
void
uiman_init ()
{
ui_widget_mesh_init ();
ui_root = Widget_root_new ();
Widget *container = Widget_container_new (false);
Widget_set_position (container, -0.5, 0.75);
Widget_set_scale (container, 0.4, 0.15);
Widget_set_background_color (container, 0.0, 0.0, 0.0, 0.8);
Widget_set_texture (container, RESTEX ("terrain4"));
Widget *game_name = Widget_label_new (NULL, TEXT_ALIGN_CENTER);
Widget_label_printf (game_name, "%s %s", GAME_NAME, GAME_VERSION);
Widget *frame_time = Widget_label_new (NULL, TEXT_ALIGN_LEFT);
Widget_set_on_tick (frame_time, uicb_label_show_float,
CallbackFormatData_new_float ("Frame: %.2f s", &delta_time));
Widget *entities_rendered = Widget_label_new (NULL, TEXT_ALIGN_LEFT);
Widget *chunks_rendered = Widget_label_new (NULL, TEXT_ALIGN_LEFT);
Widget_set_on_tick (entities_rendered, uicb_label_show_int,
CallbackFormatData_new_int ("Entities: %d", &n_frame_ents));
Widget_set_on_tick (chunks_rendered, uicb_label_show_int,
CallbackFormatData_new_int ("Chunks: %d", &n_frame_chunks));
Widget *container2 = Widget_container_new (true);
Widget_add_child (container2, entities_rendered);
Widget_add_child (container2, chunks_rendered);
Widget *pos_x = Widget_label_new (NULL, TEXT_ALIGN_RIGHT);
Widget *pos_y = Widget_label_new (NULL, TEXT_ALIGN_RIGHT);
Widget *pos_z = Widget_label_new (NULL, TEXT_ALIGN_RIGHT);
Widget_label_set_text_color (pos_x, 1.0, 0.0, 0.0, 1.0);
Widget_set_on_tick (pos_x, uicb_label_show_float,
CallbackFormatData_new_float ("X: %.2f", &camera_position[0]));
Widget_label_set_text_color (pos_y, 0.0, 1.0, 0.0, 1.0);
Widget_set_on_tick (pos_y, uicb_label_show_float,
CallbackFormatData_new_float ("Y: %.2f", &camera_position[1]));
Widget_label_set_text_color (pos_z, 0.0, 1.0, 1.0, 1.0);
Widget_set_on_tick (pos_z, uicb_label_show_float,
CallbackFormatData_new_float ("Z: %.2f", &camera_position[2]));
Widget *container3 = Widget_container_new (true);
Widget_add_child (container3, pos_x);
Widget_add_child (container3, pos_y);
Widget_add_child (container3, pos_z);
Widget *wireframe_button = Widget_label_new ("Toggle wireframe", TEXT_ALIGN_CENTER);
Widget_set_background_color (wireframe_button, 1.0, 1.0, 1.0, 0.2);
Widget_set_hover_background_color (wireframe_button, 1.0, 1.0, 1.0, 0.3);
Widget_set_on_left_click (wireframe_button, uicb_flag_switch, "wireframe_enabled");
Widget *flight_button = Widget_label_new ("Toggle flight", TEXT_ALIGN_CENTER);
Widget_set_background_color (flight_button, 1.0, 1.0, 1.0, 0.2);
Widget_set_hover_background_color (flight_button, 1.0, 1.0, 1.0, 0.3);
Widget_set_on_left_click (flight_button, uicb_flag_switch, "flight_enabled");
Widget *container4 = Widget_container_new (true);
Widget_add_child (container4, wireframe_button);
Widget_add_child (container4, flight_button);
Widget_add_child (container, game_name);
Widget_add_child (container, frame_time);
Widget_add_child (container, container2);
Widget_add_child (container, container3);
Widget_add_child (container, container4);
Widget_add_child (ui_root, container);
}
void
uiman_tick ()
{
Widget_tick (ui_root);
}
void
uiman_render ()
{
Widget_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;
}
gboolean
uiman_cb_switch_focus (SDL_Event *event, void *data)
{
UNUSED (event, data);
flags_switch ("ui_has_focus");
SDL_SetWindowRelativeMouseMode (sdl_window, !flags_get ("ui_has_focus"));
return true;
}
gboolean
uiman_cb_key_down (SDL_Event *event, void *data)
{
UNUSED (event, data);
return false;
}
gboolean
uiman_cb_key_up (SDL_Event *event, void *data)
{
UNUSED (event, data);
return false;
}
gboolean
uiman_cb_mouse_motion (SDL_Event *event, void *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);
Widget *widget = Widget_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos);
if (widget != hovered_widget)
{
if (hovered_widget)
{
hovered_widget->hovered = false;
}
if (widget)
{
widget->hovered = true;
}
hovered_widget = widget;
}
/* This callback always eats the event, because why would the game
need mouse motion if the UI has stolen the focus? */
return true;
}
gboolean
uiman_cb_button_down (SDL_Event *event, void *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);
Widget *widget = Widget_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos);
if (widget)
{
if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_click)
{
widget->on_left_click (widget, widget->left_click_data);
return true;
}
if (event->button.button == SDL_BUTTON_RIGHT && widget->on_right_click)
{
widget->on_right_click (widget, widget->right_click_data);
return true;
}
}
return false;
}
gboolean
uiman_cb_button_up (SDL_Event *event, void *data)
{
UNUSED (event, data);
return false;
}
gboolean
uiman_cb_mouse_wheel (SDL_Event *event, void *data)
{
UNUSED (event, data);
return false;
}
gboolean
uiman_cb_text_input (SDL_Event *event, void *data)
{
UNUSED (event, data);
return false;
}