196 lines
4.4 KiB
C
196 lines
4.4 KiB
C
typedef void ui_custom_draw_t(struct ui_box_t *box);
|
|
|
|
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_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;
|
|
};
|
|
|
|
fn ui_caret_t ui_caret_clamp(ui_caret_t c, i32 min, i32 max) {
|
|
return (ui_caret_t){CLAMP(c.e[0],min,max), CLAMP(c.e[1],min,max), c.ifront};
|
|
}
|
|
fn i32 ui_caret_front(ui_caret_t c) { return c.e[c.ifront]; }
|
|
fn i32 ui_caret_back(ui_caret_t c) { return c.e[c.ifront ? 0 : 1]; }
|
|
|
|
ui_caret_t ui_caret(i32 front, i32 back) {
|
|
ui_caret_t result = {0};
|
|
if (front >= back) {
|
|
result.range.min = back;
|
|
result.range.max = front;
|
|
result.ifront = 1;
|
|
} else {
|
|
result.range.min = front;
|
|
result.range.max = back;
|
|
result.ifront = 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
ui_caret_t ui_caret_set_back(ui_caret_t caret, i32 back) {
|
|
i32 front = ui_caret_front(caret);
|
|
ui_caret_t result = ui_caret(front, back);
|
|
return result;
|
|
}
|
|
|
|
ui_caret_t ui_caret_set_front(ui_caret_t caret, i32 front) {
|
|
i32 back = ui_caret_back(caret);
|
|
ui_caret_t result = ui_caret(front, back);
|
|
return result;
|
|
}
|
|
|
|
fn ui_caret_t ui_carets(i32 x) {
|
|
return ui_caret(x, x);
|
|
}
|
|
|
|
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;
|
|
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_custom_draw_t *custom_draw;
|
|
UI_DECL_BOX_MEMBERS
|
|
|
|
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;
|
|
|
|
f32 hot_t;
|
|
f32 active_t;
|
|
|
|
r2f32_t final_rect;
|
|
b32 expanded;
|
|
|
|
ui_text_input_t text_input;
|
|
};
|
|
|
|
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 {
|
|
app_frame_t *frame;
|
|
|
|
// building
|
|
ui_box_t root;
|
|
ui_box_t *top;
|
|
app_event_t *event;
|
|
|
|
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;
|
|
};
|
|
|
|
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))
|
|
|
|
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__}
|
|
|
|
fn ui_id_t ui_id(s8_t string);
|
|
fn ui_id_t ui_idf(char *str, ...);
|
|
fn v2f32_t ui_aligned_text_pos(ui_text_align_t text_align, r2f32_t rect, s8_t string); |