327 lines
8.0 KiB
C
327 lines
8.0 KiB
C
////////////////////////////////////////////////////////////
|
|
//~ Key types
|
|
|
|
#define UI_NilKey ((UI_Key) { 0 })
|
|
#define UI_RootKey ((UI_Key) { 0xa3deb3749ef35a7aUll })
|
|
|
|
Struct(UI_Key)
|
|
{
|
|
u64 hash;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Size types
|
|
|
|
Enum(UI_SizeKind)
|
|
{
|
|
UI_SizeKind_Fit, /* Size to contents */
|
|
UI_SizeKind_Fill, /* Size as percent of parent size */
|
|
UI_SizeKind_Pixel, /* Exact size */
|
|
};
|
|
|
|
Struct(UI_Size)
|
|
{
|
|
UI_SizeKind kind;
|
|
f32 v;
|
|
f32 strictness;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Rounding types
|
|
|
|
Enum(UI_RoundKind)
|
|
{
|
|
UI_RoundKind_Pixel, /* Exact radius */
|
|
UI_RoundKind_Fill, /* Radius as percent of size */
|
|
};
|
|
|
|
Struct(UI_Round)
|
|
{
|
|
UI_RoundKind kind;
|
|
f32 v;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Box flag types
|
|
|
|
Enum(UI_BoxFlag)
|
|
{
|
|
UI_BoxFlag_None = 0,
|
|
UI_BoxFlag_DrawText = (1 << 0),
|
|
UI_BoxFlag_NoTextTruncation = (1 << 1),
|
|
UI_BoxFlag_Floating = (1 << 2),
|
|
UI_BoxFlag_NoFloatingClamp = (1 << 3),
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Style types
|
|
|
|
#define UI_StyleKindsXMacro(x) \
|
|
x(Flags, UI_BoxFlag) \
|
|
x(Parent, struct UI_Box *) \
|
|
x(Tag, UI_Tag) \
|
|
x(LayoutAxis, Axis) \
|
|
x(Width, UI_Size) \
|
|
x(Height, UI_Size) \
|
|
x(Size, UI_Size) \
|
|
x(BackgroundColor, u32) \
|
|
x(BorderColor, u32) \
|
|
x(Tint, u32) \
|
|
x(Border, f32) \
|
|
x(Font, ResourceKey) \
|
|
x(FontSize, u32) \
|
|
x(Text, String) \
|
|
x(Padding, f32) \
|
|
x(Rounding, UI_Round) \
|
|
x(FloatingPos, Vec2) \
|
|
/* ------------------------------------------- */
|
|
|
|
Struct(UI_Tag)
|
|
{
|
|
String name;
|
|
u64 hash;
|
|
};
|
|
|
|
Enum(UI_StyleKind)
|
|
{
|
|
#define X(name, type) UI_StyleKind_##name,
|
|
UI_StyleKind_None,
|
|
UI_StyleKindsXMacro(X)
|
|
UI_StyleKind_Count,
|
|
#undef X
|
|
};
|
|
|
|
Struct(UI_Style)
|
|
{
|
|
UI_StyleKind kind;
|
|
b32 pop_when_used;
|
|
b32 forced;
|
|
/* Union of all style fields */
|
|
union
|
|
{
|
|
#define X(name, type) type name;
|
|
UI_StyleKindsXMacro(X)
|
|
#undef X
|
|
};
|
|
};
|
|
|
|
Struct(UI_StyleNode)
|
|
{
|
|
UI_StyleNode *next;
|
|
u64 checkpoint;
|
|
UI_Style style;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Checkpoint types
|
|
|
|
Struct(UI_Checkpoint)
|
|
{
|
|
UI_Checkpoint *next;
|
|
u64 v;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Event types
|
|
|
|
Enum(UI_EventFlag)
|
|
{
|
|
UI_EventFlag_None = 0,
|
|
UI_EventFlag_Active = (1 << 0),
|
|
UI_EventFlag_Hovered = (1 << 1),
|
|
};
|
|
|
|
Struct(UI_Event)
|
|
{
|
|
UI_EventFlag flags;
|
|
Vec2 activation_offset;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Box types
|
|
|
|
Struct(UI_Box)
|
|
{
|
|
//- Hash list
|
|
UI_Box *next_in_bin;
|
|
UI_Box *prev_in_bin;
|
|
|
|
//- Tree
|
|
UI_Box *parent;
|
|
UI_Box *first;
|
|
UI_Box *last;
|
|
UI_Box *next;
|
|
UI_Box *prev;
|
|
u64 count;
|
|
|
|
//- Persistent data
|
|
UI_Key key;
|
|
UI_Event event;
|
|
|
|
//- Per-build data
|
|
UI_BoxFlag flags;
|
|
|
|
GPU_Resource *background_texture;
|
|
Vec2 background_texture_uv0;
|
|
Vec2 background_texture_uv1;
|
|
|
|
UI_Size pref_size[Axis_CountXY];
|
|
UI_Round rounding;
|
|
u32 background_color;
|
|
u32 border_color;
|
|
u32 text_color;
|
|
u32 tint;
|
|
f32 border;
|
|
Vec2 floating_pos;
|
|
String text;
|
|
Axis layout_axis;
|
|
ResourceKey font_resource;
|
|
f32 font_size;
|
|
f32 padding;
|
|
|
|
//- Pre-layout data
|
|
u64 pre_index;
|
|
u64 post_index;
|
|
|
|
//- Layout data
|
|
F_Run glyph_run;
|
|
F_Font *font;
|
|
f32 solved_dims[Axis_CountXY];
|
|
f32 layout_cursor;
|
|
|
|
//- Post-layout data
|
|
Vec2 p0;
|
|
Vec2 p1;
|
|
f32 rounding_tl;
|
|
f32 rounding_tr;
|
|
f32 rounding_br;
|
|
f32 rounding_bl;
|
|
};
|
|
|
|
Struct(UI_BoxBin)
|
|
{
|
|
UI_Box *first;
|
|
UI_Box *last;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ State types
|
|
|
|
#define UI_NumBoxLookupBins 16384
|
|
|
|
Struct(UI_SharedState)
|
|
{
|
|
//- Control state
|
|
Vec2 cursor_pos;
|
|
Xform ui_to_screen_xf;
|
|
|
|
//- Build state
|
|
Arena *build_arena;
|
|
Arena *back_build_arena;
|
|
|
|
UI_BoxBin *box_bins;
|
|
UI_BoxBin *back_box_bins;
|
|
|
|
UI_Box *root_box;
|
|
UI_Box *back_root_box;
|
|
|
|
u64 boxes_count;
|
|
u64 back_boxes_count;
|
|
|
|
UI_Checkpoint *top_checkpoint;
|
|
UI_StyleNode *style_tops[UI_StyleKind_Count];
|
|
UI_Checkpoint *first_free_checkpoint;
|
|
UI_StyleNode *first_free_style_node;
|
|
|
|
//- Layout state
|
|
UI_Box **boxes_pre;
|
|
UI_Box **boxes_post;
|
|
UI_Box **back_boxes_pre;
|
|
UI_Box **back_boxes_post;
|
|
|
|
//- Render state
|
|
i64 gpu_submit_fence_target;
|
|
GPU_TransientBuffer draw_rects_tbuff;
|
|
Arena *draw_rects_arena;
|
|
|
|
} extern UI_shared_state;
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Startup
|
|
|
|
void UI_Startup(void);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Font helpers
|
|
|
|
ResourceKey UI_GetDefaultFontResource(void);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Key helpers
|
|
|
|
UI_Box *UI_BackBoxFromKey(UI_Key key);
|
|
UI_Box *UI_FrontBoxFromKey(UI_Key key);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Checkpoint helpers
|
|
|
|
void UI_PushCP(UI_Box *parent);
|
|
void UI_PopCP(void);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Style helpers
|
|
|
|
UI_StyleNode *UI_PushStyleNode(UI_Style desc);
|
|
UI_Style UI_PopStyleNode(UI_StyleKind kind);
|
|
UI_StyleNode *UI_PeekTopStyleNode(UI_StyleKind kind);
|
|
UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use);
|
|
|
|
#define UI_SetNext(name, ...) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__, .pop_when_used = 1 })
|
|
#define UI_Push(name, ...) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__ })
|
|
#define UI_ForceNext(name, ...) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__, .pop_when_used = 1, .forced = 1 })
|
|
#define UI_ForcePush(name, ...) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = __VA_ARGS__, .forced = 1 })
|
|
#define UI_Pop(name) UI_PopStyleNode(UI_StyleKind_##name).name
|
|
#define UI_UseTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 1).name
|
|
#define UI_PeekTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 0).name
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Size helpers
|
|
|
|
#define UI_SIZE(_kind, _v, _s) (UI_Size) { .kind = (_kind), .v = (_v), .strictness = (_s) }
|
|
|
|
#define UI_PIX(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (_v), (_s))
|
|
#define UI_FIT(_s) UI_SIZE(UI_SizeKind_Fit, 0, (_s))
|
|
#define UI_FILL(_v, _s) UI_SIZE(UI_SizeKind_Fill, (_v), (_s))
|
|
#define UI_FNT(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (f32)UI_PeekTop(FontSize) * (_v), (_s))
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Rounding helpers
|
|
|
|
#define UI_ROUND(_kind, _v) (UI_Round) { .kind = (_kind), .v = (_v)}
|
|
|
|
#define UI_RPIX(_v) UI_ROUND(UI_RoundKind_Pixel, (_v))
|
|
#define UI_RFILL(_v) UI_ROUND(UI_RoundKind_Fill, (_v))
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Box
|
|
|
|
UI_Box *UI_BuildBox(String seed);
|
|
|
|
void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Event
|
|
|
|
UI_Event UI_EventFromKey(UI_Key key);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Begin build
|
|
|
|
void UI_BeginBuild(ControllerEventsArray controller_events);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ End build
|
|
|
|
GPU_ResourceDesc UI_GetRenderTargetDesc(Vec2I32 size);
|
|
i64 UI_EndBuild(GPU_Resource *render_target, Xform ui_to_screen_xf);
|