#include "buffer16.h" typedef struct ui_code_loc_t ui_code_loc_t; struct ui_code_loc_t { char *file; int line; int counter; }; typedef struct ui_id_t ui_id_t; struct ui_id_t { u64 value; }; typedef struct ui_box_flags_t ui_box_flags_t; struct ui_box_flags_t { b8 draw_rect: 1; b8 draw_border: 1; b8 draw_text: 1; b8 clip_rect: 1; b8 animate_appear: 1; b8 children_sum_x: 1; b8 children_sum_y: 1; b8 keyboard_nav: 1; b8 sim_even_if_no_focus: 1; }; typedef enum { ui_text_align_left, ui_text_align_center, } ui_text_align_t; typedef enum { ui_axis2_invalid = -1, ui_axis2_x, ui_axis2_y, ui_axis2_count, } ui_axis2_t; typedef enum { ui_lop_cut_top, ui_lop_cut_bottom, ui_lop_cut_left, ui_lop_cut_right, ui_lop_idle, } ui_lop_t; #include "ui.gen.h" typedef struct ui_caret_t ui_caret_t; struct ui_caret_t { union { i32 e[2]; struct { r1i32_t range; }; }; i32 ifront; }; typedef struct ui_text_input_t ui_text_input_t; struct ui_text_input_t { union { struct { char *str; i64 len; }; s8_t string; }; i32 cap; ui_caret_t caret; }; typedef struct ui_box_t ui_box_t; typedef void ui_custom_draw_t(ui_box_t *); struct ui_box_t { ui_box_t *next; ui_box_t *prev; ui_box_t *first; ui_box_t *last; ui_box_t *parent; i32 node_count; ui_code_loc_t loc; s8_t string; v2f32_t string_size; ui_box_flags_t flags; b8 created_new; ui_custom_draw_t *custom_draw; ui_lop_t lop; UI_DECL_BOX_MEMBERS // state ui_id_t id; ui_box_t *hash_next; ui_box_t *hash_prev; u64 last_touched_event_id; f32 appear_t; f32 hot_t; f32 active_t; r2f32_t final_rect; b32 expanded; ui_text_input_t *text_input; view_id_t view; }; typedef struct ui_signal_t ui_signal_t; struct ui_signal_t { ui_box_t *box; v2f32_t drag; struct { b8 clicked: 1; b8 dragging: 1; b8 text_changed: 1; b8 text_commit: 1; }; }; typedef struct ui_t ui_t; struct ui_t { app_frame_t *frame; // building ui_box_t root; ui_box_t *top; app_event_t *event; ui_box_t *reverse_order_ref; UI_DECL_STACKS // allocation ma_arena_t *box_arena; i32 allocated_boxes; ui_box_t *free_first; ui_box_t *hash_first; ui_box_t *hash_last; // interaction ui_id_t hot; ui_id_t active; ui_id_t focus; // drawing r2f32_t clip_rect; }; gb ui_t *ui; gb_read_only ui_id_t ui_null_id; gb_read_only ui_box_t ui_null_box; gb_read_only ui_box_flags_t ui_null_flags; fn b32 ui_is_null_id(ui_id_t id) { return id.value == 0; } fn b32 ui_is_null_box(ui_box_t *box) { return box->id.value == 0; } fn b32 ui_is_hot_box(ui_box_t *box) { return !ui_is_null_box(box) && box->id.value == ui->hot.value; } fn b32 ui_is_active_box(ui_box_t *box) { return !ui_is_null_box(box) && box->id.value == ui->active.value; } fn b32 ui_is_focused_box(ui_box_t *box) { return !ui_is_null_box(box) && box->id.value == ui->focus.value; } #define ev_left(ev) ((ev)->mouse_button == app_mouse_button_left) #define ev_left_up(ev) ((ev)->kind == app_event_kind_mouse_up && ev_left(ev)) #define ev_left_down(ev) ((ev)->kind == app_event_kind_mouse_down && ev_left(ev)) #define ev_right(ev) ((ev)->mouse_button == app_mouse_button_right) #define ev_right_up(ev) ((ev)->kind == app_event_kind_mouse_up && ev_right(ev)) #define ev_right_down(ev) ((ev)->kind == app_event_kind_mouse_down && ev_right(ev)) #define UILOC (ui_code_loc_t){.file = __FILE__, .line = __LINE__, .counter = __COUNTER__} #define ui_em(x) ((x) * rn->main_font->size) #define ui_dm(V) ((V) * rn->main_font->computed_xchar_size) #define ui_max 200000000.f #define ui_children_sum 0 fn ui_id_t ui_id(s8_t string); fn ui_id_t ui_idf(char *str, ...); fn r2f32_t window_rect_from_frame(app_frame_t *frame);