diff --git a/game/src/ui/uiman.c b/game/src/ui/uiman.c index ae163aa..f5a60e5 100644 --- a/game/src/ui/uiman.c +++ b/game/src/ui/uiman.c @@ -4,9 +4,10 @@ extern SDL_Window *sdl_window; extern float delta_time; extern int n_frame_ents, n_frame_chunks; extern vec3 camera_position; +extern int render_distance; static Widget *ui_root; -static Widget *hovered_widget; +static Widget *hovered_widget, *clicked_widget; void uiman_init () @@ -19,64 +20,32 @@ uiman_init () 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_add_child (ui_root, container); + 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_add_child (container, game_name); + Widget *container1 = Widget_container_new (true); + Widget_add_child (container1, Widget_make_label_float ("Frame: %.2f s", &delta_time, TEXT_ALIGN_LEFT)); + Widget_add_child (container1, Widget_make_label_int ("Render distance: %d", &render_distance, TEXT_ALIGN_RIGHT)); + Widget_add_child (container, container1); + 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_add_child (container2, Widget_make_label_int ("Entities: %d", &n_frame_ents, TEXT_ALIGN_LEFT)); + Widget_add_child (container2, Widget_make_label_int ("Chunks: %d", &n_frame_chunks, TEXT_ALIGN_RIGHT)); + Widget_add_child (container, container2); 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 (container3, Widget_make_label_float ("X: %.1f", &camera_position[0], TEXT_ALIGN_LEFT)); + Widget_add_child (container3, Widget_make_label_float ("Y: %.1f", &camera_position[1], TEXT_ALIGN_CENTER)); + Widget_add_child (container3, Widget_make_label_float ("Z: %.1f", &camera_position[2], TEXT_ALIGN_RIGHT)); Widget_add_child (container, container3); + + Widget *container4 = Widget_container_new (true); + Widget_add_child (container4, Widget_make_button_flag_switch ("Toggle wireframe", "wireframe_enabled")); + Widget_add_child (container4, Widget_make_button_flag_switch ("Toggle flight", "wireframe_enabled")); Widget_add_child (container, container4); - - Widget_add_child (ui_root, container); } void @@ -166,6 +135,21 @@ uiman_cb_button_down (SDL_Event *event, void *data) Widget *widget = Widget_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos); + if (widget != clicked_widget) + { + if (clicked_widget) + { + clicked_widget->clicked = FALSE; + } + + if (widget) + { + widget->clicked = TRUE; + } + + clicked_widget = widget; + } + if (widget) { if (event->button.button == SDL_BUTTON_LEFT && widget->on_left_click) @@ -180,7 +164,7 @@ uiman_cb_button_down (SDL_Event *event, void *data) return true; } } - + return false; } @@ -188,6 +172,13 @@ gboolean uiman_cb_button_up (SDL_Event *event, void *data) { UNUSED (event, data); + + if (clicked_widget) + { + clicked_widget->clicked = FALSE; + clicked_widget = NULL; + } + return false; } diff --git a/game/src/ui/widget.c b/game/src/ui/widget.c index ad1ccd5..c7de06b 100644 --- a/game/src/ui/widget.c +++ b/game/src/ui/widget.c @@ -101,6 +101,12 @@ Widget_set_hover_background_color (Widget *widget, float r, float g, float b, fl glm_vec4_copy ((vec4) { r, g, b, a }, widget->hover_background_color); } +void +Widget_set_click_background_color (Widget *widget, float r, float g, float b, float a) +{ + glm_vec4_copy ((vec4) { r, g, b, a }, widget->click_background_color); +} + void Widget_add_child (Widget *parent, Widget *child) { @@ -160,7 +166,7 @@ Widget_label_render_text (Widget *widget, mat3 parent_model) } void -UIContainer_layout (Widget *widget) +Widget_container_layout (Widget *widget) { if (widget->children->len == 0) { @@ -212,15 +218,26 @@ Widget_render_with_model (Widget *widget, mat3 parent_model) if (widget->kind == WIDGET_CONTAINER) { - UIContainer_layout (widget); + Widget_container_layout (widget); } if (widget->kind != WIDGET_ROOT) { program_set_mat3 (RESPRG ("uiwidget"), "model", model); - program_set_vec4 (RESPRG ("uiwidget"), "background_color", - widget->hovered ? widget->hover_background_color - : widget->background_color); + + if (widget->clicked) + { + program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->click_background_color); + } + else if (widget->hovered) + { + program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->hover_background_color); + } + else + { + program_set_vec4 (RESPRG ("uiwidget"), "background_color", widget->background_color); + } + program_set_int (RESPRG ("uiwidget"), "has_texture", widget->has_texture); glActiveTexture (GL_TEXTURE0); @@ -352,6 +369,36 @@ CallbackFormatData_new_float (const char *format, float *value) return data; } +Widget * +Widget_make_label_float (const char *fmt, float *ptr, TextAlignment align) +{ + Widget *w = Widget_label_new (NULL, align); + Widget_set_on_tick (w, uicb_label_show_float, CallbackFormatData_new_float (fmt, ptr)); + return w; +} + +Widget * +Widget_make_label_int (const char *fmt, int *ptr, TextAlignment align) +{ + Widget *w = Widget_label_new (NULL, align); + Widget_set_on_tick (w, uicb_label_show_int, CallbackFormatData_new_int (fmt, ptr)); + return w; +} + +Widget * +Widget_make_button_flag_switch (const char *label, char *flag) +{ + Widget *w = Widget_label_new (label, TEXT_ALIGN_CENTER); + + Widget_set_background_color (w, 1.0, 1.0, 1.0, 0.2); + Widget_set_hover_background_color (w, 1.0, 1.0, 1.0, 0.4); + Widget_set_click_background_color (w, 1.0, 1.0, 1.0, 0.6); + + Widget_set_on_left_click (w, uicb_flag_switch, flag); + return w; +} + + void uicb_label_show_int (Widget *widget, void *userdata) { diff --git a/game/src/ui/widget.h b/game/src/ui/widget.h index 0002972..835f1ea 100644 --- a/game/src/ui/widget.h +++ b/game/src/ui/widget.h @@ -48,6 +48,7 @@ typedef struct Widget gboolean visible; gboolean hovered; + gboolean clicked; /* Remember that the coordinate system is -1 to 1. Both for the root element and all it's children. For the root it's relative to the @@ -58,7 +59,7 @@ typedef struct Widget parent widget. But it is the same on all sides VISUALLY. */ float padding; - vec4 background_color, hover_background_color; + vec4 background_color, hover_background_color, click_background_color; gboolean has_texture; unsigned int texture; @@ -105,12 +106,17 @@ void Widget_set_position (Widget *widget, float x, float y); void Widget_set_scale (Widget *widget, float x, float y); void Widget_set_background_color (Widget *widget, float r, float g, float b, float a); void Widget_set_hover_background_color (Widget *widget, float r, float g, float b, float a); +void Widget_set_click_background_color (Widget *widget, float r, float g, float b, float a); void Widget_set_texture (Widget *widget, unsigned int texture); Widget *Widget_find_xy (Widget *widget, mat3 parent_model, vec2 mouse_ui_pos); void Widget_tick (Widget *widget); void Widget_render (Widget *widget); +Widget *Widget_make_label_float (const char *fmt, float *ptr, TextAlignment align); +Widget *Widget_make_label_int (const char *fmt, int *ptr, TextAlignment align); +Widget *Widget_make_button_flag_switch (const char *label, char *flag); + void Widget_label_set_text (Widget *widget, const char *text); void Widget_label_printf (Widget *widget, const char *format, ...); void Widget_label_set_text_color (Widget *widget, float r, float g, float b, float a);