#ifndef _PIUMA_GUI_H_ #define _PIUMA_GUI_H_ #include "../lib/types.h" #include "../lib/math.h" #include "../lib/geometry.h" #include "../render/2d.h" #include "../lib/text.h" #include "../lib/event.h" typedef u32 Gui_Id; struct Gui_Input { v2 pointer_position; v2 absolute_pointer_position; bool mouse_pressed; bool mouse_pressed_this_frame; bool mouse_released_this_frame; s64 text_cursor_move; char text[32]; v2 absolute_pointer_position_last_frame; }; enum Gui_Text_Align { GUI_ALIGN_CENTER, GUI_ALIGN_LEFT, GUI_ALIGN_RIGHT }; struct Gui_Style { f32 font_size; f32 animation_base_time; v4 text_color; Gui_Text_Align text_align; v4 button_color; v4 button_color_hovered; v4 button_color_pressed; v4 button_text_color; v4 button_text_color_hovered; v4 button_text_color_pressed; f32 button_radius; v4 slider_fill_color; v4 window_background_color; v4 window_border_color; v4 window_background_color_inactive; v4 window_border_color_inactive; f32 window_corner_radius; v4 window_titlebar_color; v4 window_titlebar_color_inactive; }; struct Gui_Window { Gui_Id id; Rect r; r_framebuffer framebuffer; bool still_open; }; enum Gui_Widget_Status_Flags : u8 { GUI_WIDGET_STATUS_NONE, GUI_WIDGET_STATUS_PREVENT_HOT }; struct Gui_Context { u32 width; u32 height; f64 last_frame_time; f64 current_frame_time; Gui_Id active; // Are we interacting with the widget (pressed for buttons, ready to receive text for text inputs) Gui_Id hot; // Hovered the previous frame Gui_Id possibly_hot; // Might become hot this frame f64 active_start_time; f64 hot_start_time; u8 active_status; // Text input state u64 text_cursor_position; u64 text_length; // Windows Gui_Window *windows; u32 window_count; u32 window_capacity; Gui_Window *current_window; r_framebuffer *old_framebuffer; // ID Gui_Id *id_stack; u32 id_count; u32 id_capacity; Gui_Input input; Gui_Style style; }; struct Gui_State { Gui_Context default_context; Gui_Context *selected_context; }; extern Gui_State global_gui_state; bool gui_init(); void gui_deinit(); void gui_context_init(Gui_Context *ctx); //@Correctness: gui_context_deinit void gui_context_select(Gui_Context *ctx); // Set implicit Gui_Context void gui_frame_begin(Gui_Context *ctx, f64 curr_time); void gui_frame_begin(f64 curr_time); void gui_frame_end(Gui_Context *ctx); void gui_frame_end(); void gui_handle_event(Gui_Context *ctx, Event *e); void gui_handle_event(Event *e); // ### Widgets ### // Text void gui_text(Gui_Context *ctx, Rect r, const char *text); void gui_text(Rect r, const char *text); void gui_text_aligned(Gui_Context *ctx, Rect r, const char *text, Gui_Text_Align alignment); void gui_text_aligned(Rect r, const char *text, Gui_Text_Align alignment); v2 gui_text_compute_size(Gui_Context *ctx, const char *text); v2 gui_text_compute_size(const char *text); // Button bool gui_button(Gui_Context *ctx, Rect r, const char *text); bool gui_button(Rect r, const char *text); // Slider bool gui_slider(Gui_Context *ctx, Rect r, f32 min, f32 max, f32 *value); bool gui_slider(Rect r, f32 min, f32 max, f32 *value); bool gui_slider_text(Gui_Context *ctx, Rect r, f32 min, f32 max, f32 *value, const char *text); bool gui_slider_text(Rect r, f32 min, f32 max, f32 *value, const char *text); // Checkbox // Option buttons // Combo box // Tooltips // Images bool gui_image(Gui_Context *ctx, Rect r, r_texture *texture); bool gui_image(Rect r, r_texture *texture); bool gui_image(Gui_Context *ctx, Rect r, const u8 *bmp, u32 width, u32 height, u32 channels, u32 flags = 0); bool gui_image(Rect r, const u8 *bmp, u32 width, u32 height, u32 channels, u32 flags = 0); // Text input bool gui_text_input(Gui_Context *ctx, Rect r, char *text, u64 max_size); bool gui_text_input(Rect r, char *text, u64 max_size); // Panels void gui_panel(Gui_Context *ctx, Rect r); void gui_panel(Rect r); // Windows bool gui_window_start(Gui_Context *ctx, Rect r, Gui_Id id); // You have to provide some kind of unique id to identify windows bool gui_window_start(Rect r, Gui_Id id); void gui_window_end(Gui_Context *ctx); void gui_window_end(); bool gui_window_titlebar(Gui_Context *ctx, Rect r, const char *title, bool *close, v2 *move); bool gui_window_titlebar(Rect r, const char *title, bool *close, v2 *move); Gui_Window *gui_window_by_id(Gui_Context *ctx, Rect r, Gui_Id id); // Rect r might be needed for creation void gui_window_update_rect(Gui_Context *ctx, Gui_Window *window, Rect r); // Helpers bool gui_is_hovered (Gui_Context *ctx, Gui_Id widget_id, Rect r); bool gui_button_behaviuor (Gui_Context *ctx, Gui_Id widget_id, Rect r); bool gui_text_input_behaviuor(Gui_Context *ctx, Gui_Id widget_id, Rect r); bool gui_window_behaviour (Gui_Context *ctx, Gui_Id widget_id, Rect r); Gui_Id gui_id_from_pointer(Gui_Context *ctx, const void* ptr); void gui_id_stack_push(Gui_Context *ctx, Gui_Id id); void gui_id_stack_pop(Gui_Context *ctx); #endif