#if 0 /* ** [x] Choosing a keying strategy from user code ** [x] Using parents ** [x] Using file and line ** [ ] Keyboard friendliness ** [x] ui_em size ** [ ] use strictness to 'solve violations' ** [ ] scrolling ** [ ] vieweing type info ** [ ] slider ** [ ] button ** [ ] pernament state */ typedef struct ui_id_t ui_id_t; struct ui_id_t { u64 value; }; typedef struct ui_code_loc_t ui_code_loc_t; struct ui_code_loc_t { char *file; int line; int counter; }; #define UI_CODE_LOC (ui_code_loc_t){.file = __FILE__, .line = __LINE__, .counter = __COUNTER__} typedef enum { ui_axis2_x, ui_axis2_y, ui_axis2_count, } ui_axis2_t; typedef enum { ui_size_kind_null, ui_size_kind_pixels, ui_size_kind_text_content, ui_size_kind_percent_of_parent, ui_size_kind_children_sum, } ui_size_kind_t; typedef struct ui_size_t ui_size_t; struct ui_size_t { ui_size_kind_t kind; f32 value; f32 strictness; }; typedef struct ui_box_flags_t ui_box_flags_t; struct ui_box_flags_t { b8 draw_border : 1; b8 draw_text : 1; b8 draw_rect : 1; b8 scroll : 1; }; typedef struct ui_box_t ui_box_t; struct ui_box_t { // recreated every frame in building code ui_box_t *next; ui_box_t *prev; ui_box_t *parent; ui_box_t *first; ui_box_t *last; i32 node_count; ui_box_flags_t flags; s8_t string; ui_size_t semantic_size[ui_axis2_count]; ui_axis2_t grow_axis; ui_code_loc_t loc; b32 created_new; // layout f32 iter_pos[ui_axis2_count]; // preserving state ui_id_t id; // important position!: offset(id) used for partial zeroing u64 last_touched_event_id; ui_box_t *hash_next; ui_box_t *hash_prev; // layout f32 computed_rel_pos[ui_axis2_count]; f32 computed_size[ui_axis2_count]; r2f32_t rect; v2f32_t view_offset; // state b32 expanded; }; typedef struct ui_signal_t ui_signal_t; struct ui_signal_t { ui_box_t *box; b8 clicked; b8 dragging; // b8 double_clicked; // b8 right_clicked; // b8 pressed; // b8 released; // b8 dragging; // b8 hovering; }; typedef struct ui_id_flags_t ui_id_flags_t; struct ui_id_flags_t { b8 use_hierarchy; b8 use_code_loc; b8 use_string; }; typedef struct ui_t ui_t; struct ui_t { ma_arena_t *box_arena; // required to be only used for boxes app_event_t *event; app_frame_t *frame; i32 allocated_boxes; ui_box_t *box_array; // first item on arena ui_box_t *root; ui_box_t *top; ui_box_t *free_first; ui_box_t *hash_first; ui_box_t *hash_last; ui_id_t hot; ui_id_t active; int indent_stack; ui_id_flags_t id_flags; }; gb ui_t *ui = NULL; gb_read_only ui_id_t ui_null_id; gb_read_only ui_box_t ui_null_box; 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 ui_size_t ui_size(ui_size_kind_t kind, f32 value) { return (ui_size_t){.kind = kind, .value = value}; } #define ui_pixels(value) ui_size(ui_size_kind_pixels, value) #define ui_em(value) ui_size(ui_size_kind_pixels, value * rn_state.main_font.size) #define ui_text() ui_size(ui_size_kind_text_content, 0) #define ui_children_sum() ui_size(ui_size_kind_children_sum, 0) #define ui_percent(value) ui_size(ui_size_kind_percent_of_parent, value)