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; }; typedef enum { ui_text_align_left, ui_text_align_center, } ui_text_align_t; typedef enum { ui_op_cut_top, ui_op_cut_bottom, ui_op_cut_left, ui_op_cut_right, ui_op_idle, } ui_op_t; typedef struct ui_box_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; ui_box_flags_t flags; b8 created_new; ui_text_align_t text_align; ui_op_t op; r2f32_t full_rect; r2f32_t rect; // state ui_id_t id; ui_box_t *hash_next; ui_box_t *hash_prev; u64 last_touched_event_id; r2f32_t final_rect; b32 expanded; }; typedef struct ui_signal_t ui_signal_t; struct ui_signal_t { ui_box_t *box; b8 clicked; b8 dragging; }; typedef struct ui_t ui_t; struct ui_t { // building ui_box_t root; ui_box_t *top; app_event_t *event; stack_t(ui_id_t, 32) id_stack; ui_text_align_t pref_text_align; // 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; // drawing r2f32_t clip_rect; }; 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; } #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)) fn void ui_set_rect(ui_box_t *box, r2f32_t rect) { box->rect = box->full_rect = rect; } #define UILOC (ui_code_loc_t){.file = __FILE__, .line = __LINE__, .counter = __COUNTER__} #define ui_em(x) ((x) * rn_state.main_font->size) #define ui_max 200000000.f #define ui_box_flags(...) (ui_box_flag_t){__VA_ARGS__}