type alias refactor

This commit is contained in:
2026-03-04 16:26:17 -05:00
parent 75ac2883f7
commit fb358e3c4b
19 changed files with 614 additions and 603 deletions

View File

@@ -146,7 +146,7 @@ void ui_set_accent(S32 accent_id) {
static void clay_error_handler(Clay_ErrorData error) {
char buf[512];
int len = error.errorText.length < 511 ? error.errorText.length : 511;
S32 len = error.errorText.length < 511 ? error.errorText.length : 511;
memcpy(buf, error.errorText.chars, len);
buf[len] = '\0';
fprintf(stderr, "[Clay Error] %s\n", buf);
@@ -161,7 +161,7 @@ static UI_Context *g_measure_ctx = nullptr;
static Clay_Dimensions clay_measure_text(Clay_StringSlice text, Clay_TextElementConfig *config, void *user_data) {
UI_Context *ctx = (UI_Context *)user_data;
if (!ctx || !ctx->measure_text_fn || text.length == 0) {
return Clay_Dimensions{0, (float)config->fontSize};
return Clay_Dimensions{0, (F32)config->fontSize};
}
Vec2F32 result = ctx->measure_text_fn(text.chars, text.length, (F32)config->fontSize, ctx->measure_text_user_data);
return Clay_Dimensions{result.x, result.y};
@@ -173,7 +173,7 @@ static Clay_Dimensions clay_measure_text(Clay_StringSlice text, Clay_TextElement
UI_Context *ui_create(F32 viewport_w, F32 viewport_h) {
UI_Context *ctx = (UI_Context *)calloc(1, sizeof(UI_Context));
uint32_t min_memory = Clay_MinMemorySize();
U32 min_memory = Clay_MinMemorySize();
ctx->clay_memory = malloc(min_memory);
Clay_Arena clay_arena = Clay_CreateArenaWithCapacityAndMemory(min_memory, ctx->clay_memory);

View File

@@ -92,14 +92,14 @@ void ui_set_accent(S32 accent_id);
extern F32 g_ui_scale;
// Scale a float value (for CLAY_SIZING_FIXED, corner radii, etc.)
static inline float uis(float x) { return x * g_ui_scale; }
// Scale a F32 value (for CLAY_SIZING_FIXED, corner radii, etc.)
static inline F32 uis(F32 x) { return x * g_ui_scale; }
// Scale to uint16_t (for Clay_Padding, childGap, etc.)
static inline uint16_t uip(float x) { return (uint16_t)(x * g_ui_scale + 0.5f); }
// Scale to U16 (for Clay_Padding, childGap, etc.)
static inline U16 uip(F32 x) { return (U16)(x * g_ui_scale + 0.5f); }
// Scale to uint16_t font size
static inline uint16_t uifs(float x) { return (uint16_t)(x * g_ui_scale + 0.5f); }
// Scale to U16 font size
static inline U16 uifs(F32 x) { return (U16)(x * g_ui_scale + 0.5f); }
////////////////////////////////
// Tab styling

View File

@@ -44,7 +44,7 @@ static CustomGradientData *alloc_gradient(Clay_Color top, Clay_Color bottom) {
// Per-frame shadow layer ID counter (each shadow uses N unique IDs)
static S32 g_shadow_id_counter = 0;
// Frame counter for double-click detection
// Frame counter for F64-click detection
static S32 g_frame_number = 0;
// Emit a smooth multi-layer drop shadow as floating rects.
@@ -59,16 +59,16 @@ static S32 g_frame_number = 0;
#define SHADOW_LAYERS 7
static void emit_shadow(Clay_BoundingBox bb, F32 ox, F32 oy, F32 radius,
float peak_alpha, int16_t z,
B32 attach_to_root, uint32_t parent_id,
F32 peak_alpha, S16 z,
B32 attach_to_root, U32 parent_id,
Clay_FloatingAttachPointType parent_attach) {
if (bb.width <= 0) return;
float per_layer = peak_alpha / (float)SHADOW_LAYERS;
F32 per_layer = peak_alpha / (F32)SHADOW_LAYERS;
// Draw outermost first (largest, lowest alpha contribution), innermost last
for (S32 i = SHADOW_LAYERS - 1; i >= 0; i--) {
float t = (float)(i + 1) / (float)SHADOW_LAYERS; // 1/N .. 1.0
F32 t = (F32)(i + 1) / (F32)SHADOW_LAYERS; // 1/N .. 1.0
F32 expand = radius * t;
S32 sid = g_shadow_id_counter++;
@@ -268,8 +268,8 @@ B32 ui_button(const char *id, const char *text) {
B32 hovered = Clay_PointerOver(eid);
Clay_Color base = hovered ? g_theme.accent_hover : g_theme.accent;
Clay_Color top = {(float)Min((int)base.r+12,255), (float)Min((int)base.g+12,255), (float)Min((int)base.b+12,255), base.a};
Clay_Color bot = {(float)Max((int)base.r-15,0), (float)Max((int)base.g-15,0), (float)Max((int)base.b-15,0), base.a};
Clay_Color top = {(F32)Min((S32)base.r+12,255), (F32)Min((S32)base.g+12,255), (F32)Min((S32)base.b+12,255), base.a};
Clay_Color bot = {(F32)Max((S32)base.r-15,0), (F32)Max((S32)base.g-15,0), (F32)Max((S32)base.b-15,0), base.a};
CustomGradientData *grad = alloc_gradient(top, bot);
CLAY(eid,
@@ -526,7 +526,7 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
// Key events
for (S32 k = 0; k < g_wstate.input.key_count; k++) {
uint8_t key = g_wstate.input.keys[k];
U8 key = g_wstate.input.keys[k];
// Skip Tab — handled via tab cycling
if (key == PKEY_TAB) continue;
@@ -656,7 +656,7 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
// Character input (printable only, skip control chars)
if (is_focused) {
for (S32 c = 0; c < g_wstate.input.char_count; c++) {
uint16_t ch = g_wstate.input.chars[c];
U16 ch = g_wstate.input.chars[c];
if (ch >= 32 && ch < 127) {
// Delete selection first if any
if (text_input_has_sel()) {
@@ -726,8 +726,8 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
Clay_Color border_color = is_focused ? g_theme.accent : g_theme.border;
// Inset effect: darker top, lighter bottom (recessed look)
Clay_Color inset_top = {(float)Max((int)bg.r-8,0), (float)Max((int)bg.g-8,0), (float)Max((int)bg.b-8,0), bg.a};
Clay_Color inset_bot = {(float)Min((int)bg.r+3,255), (float)Min((int)bg.g+3,255), (float)Min((int)bg.b+3,255), bg.a};
Clay_Color inset_top = {(F32)Max((S32)bg.r-8,0), (F32)Max((S32)bg.g-8,0), (F32)Max((S32)bg.b-8,0), bg.a};
Clay_Color inset_bot = {(F32)Min((S32)bg.r+3,255), (F32)Min((S32)bg.g+3,255), (F32)Min((S32)bg.b+3,255), bg.a};
CustomGradientData *inset_grad = alloc_gradient(inset_top, inset_bot);
CLAY(eid,
@@ -820,13 +820,13 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
static char dd_trunc_buf[256];
const char *display_label = current_label;
Clay_ElementId text_eid = WIDI(id, 500);
float avail_w = Clay_GetElementData(text_eid).boundingBox.width;
F32 avail_w = Clay_GetElementData(text_eid).boundingBox.width;
if (avail_w > 0) {
S32 label_len = (S32)strlen(current_label);
Vec2F32 text_size = ui_measure_text(current_label, label_len, FONT_SIZE_NORMAL);
if (text_size.x > avail_w) {
Vec2F32 dots = ui_measure_text("...", 3, FONT_SIZE_NORMAL);
float target_w = avail_w - dots.x;
F32 target_w = avail_w - dots.x;
S32 lo = 0, hi = label_len;
while (lo < hi) {
S32 mid = (lo + hi + 1) / 2;
@@ -845,7 +845,7 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
Clay_Color bg = is_open ? g_theme.bg_dark : g_theme.bg_medium;
if (header_hovered && !is_open) bg = g_theme.bg_lighter;
Clay_Color dd_top = {(float)Min((int)bg.r+6,255), (float)Min((int)bg.g+6,255), (float)Min((int)bg.b+6,255), bg.a};
Clay_Color dd_top = {(F32)Min((S32)bg.r+6,255), (F32)Min((S32)bg.g+6,255), (F32)Min((S32)bg.b+6,255), bg.a};
CustomGradientData *dd_grad = alloc_gradient(dd_top, bg);
CLAY(eid,
@@ -892,7 +892,7 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
// Draw dropdown list if open (floating so it escapes modal/container clipping)
if (is_open) {
Clay_ElementId list_id = WIDI(id, 502);
float header_width = Clay_GetElementData(eid).boundingBox.width;
F32 header_width = Clay_GetElementData(eid).boundingBox.width;
// Dropdown list shadow
{
@@ -1052,7 +1052,7 @@ S32 ui_modal(const char *id, const char *title, const char *message,
// Title bar (gradient: lighter top)
{
Clay_Color mtb = g_theme.title_bar;
Clay_Color mtb_top = {(float)Min((int)mtb.r+12,255), (float)Min((int)mtb.g+12,255), (float)Min((int)mtb.b+12,255), mtb.a};
Clay_Color mtb_top = {(F32)Min((S32)mtb.r+12,255), (F32)Min((S32)mtb.g+12,255), (F32)Min((S32)mtb.b+12,255), mtb.a};
CustomGradientData *mtb_grad = alloc_gradient(mtb_top, mtb);
CLAY(WIDI(id, 2002),
@@ -1099,8 +1099,8 @@ S32 ui_modal(const char *id, const char *title, const char *message,
B32 btn_hovered = Clay_PointerOver(btn_id);
Clay_Color mbtn_base = btn_hovered ? g_theme.accent_hover : g_theme.accent;
Clay_Color mbtn_top = {(float)Min((int)mbtn_base.r+12,255), (float)Min((int)mbtn_base.g+12,255), (float)Min((int)mbtn_base.b+12,255), mbtn_base.a};
Clay_Color mbtn_bot = {(float)Max((int)mbtn_base.r-15,0), (float)Max((int)mbtn_base.g-15,0), (float)Max((int)mbtn_base.b-15,0), mbtn_base.a};
Clay_Color mbtn_top = {(F32)Min((S32)mbtn_base.r+12,255), (F32)Min((S32)mbtn_base.g+12,255), (F32)Min((S32)mbtn_base.b+12,255), mbtn_base.a};
Clay_Color mbtn_bot = {(F32)Max((S32)mbtn_base.r-15,0), (F32)Max((S32)mbtn_base.g-15,0), (F32)Max((S32)mbtn_base.b-15,0), mbtn_base.a};
CustomGradientData *mbtn_grad = alloc_gradient(mbtn_top, mbtn_bot);
CLAY(btn_id,
@@ -1136,7 +1136,7 @@ S32 ui_modal(const char *id, const char *title, const char *message,
////////////////////////////////
// Draggable window
static UI_WindowSlot *find_or_create_window_slot(uint32_t id, Vec2F32 initial_pos, Vec2F32 initial_size) {
static UI_WindowSlot *find_or_create_window_slot(U32 id, Vec2F32 initial_pos, Vec2F32 initial_size) {
// Look for existing slot
for (S32 i = 0; i < g_wstate.window_count; i++) {
if (g_wstate.windows[i].id == id) {
@@ -1157,25 +1157,25 @@ static UI_WindowSlot *find_or_create_window_slot(uint32_t id, Vec2F32 initial_po
static void bring_window_to_front(UI_WindowSlot *slot) {
// Renormalize if approaching modal z-range
if (g_wstate.next_z > 800) {
int16_t sorted[UI_WIDGET_MAX_WINDOWS];
S16 sorted[UI_WIDGET_MAX_WINDOWS];
S32 count = g_wstate.window_count;
for (S32 i = 0; i < count; i++) sorted[i] = g_wstate.windows[i].z_order;
// Bubble sort (tiny array)
for (S32 i = 0; i < count - 1; i++) {
for (S32 j = i + 1; j < count; j++) {
if (sorted[j] < sorted[i]) {
int16_t tmp = sorted[i]; sorted[i] = sorted[j]; sorted[j] = tmp;
S16 tmp = sorted[i]; sorted[i] = sorted[j]; sorted[j] = tmp;
}
}
}
for (S32 i = 0; i < count; i++) {
for (S32 j = 0; j < count; j++) {
if (g_wstate.windows[j].z_order == sorted[i]) {
g_wstate.windows[j].z_order = (int16_t)i;
g_wstate.windows[j].z_order = (S16)i;
}
}
}
g_wstate.next_z = (int16_t)count;
g_wstate.next_z = (S16)count;
}
slot->z_order = g_wstate.next_z++;
}
@@ -1233,7 +1233,7 @@ B32 ui_window(const char *id, const char *title, B32 *open,
// Use absolute position since window uses offset-based floating
Clay_BoundingBox shadow_bb = { slot->position.x, slot->position.y, win_bb.width, win_bb.height };
emit_shadow(shadow_bb, uis(3), uis(3), uis(8),
g_theme.shadow.a, (int16_t)(100 + slot->z_order - 1),
g_theme.shadow.a, (S16)(100 + slot->z_order - 1),
1, 0, CLAY_ATTACH_POINT_LEFT_TOP);
}
@@ -1247,7 +1247,7 @@ B32 ui_window(const char *id, const char *title, B32 *open,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.floating = {
.offset = { slot->position.x, slot->position.y },
.zIndex = (int16_t)(100 + slot->z_order),
.zIndex = (S16)(100 + slot->z_order),
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP,
@@ -1259,7 +1259,7 @@ B32 ui_window(const char *id, const char *title, B32 *open,
) {
// Title bar (gradient: lighter top)
Clay_Color tb = g_theme.title_bar;
Clay_Color tb_top = {(float)Min((int)tb.r+12,255), (float)Min((int)tb.g+12,255), (float)Min((int)tb.b+12,255), tb.a};
Clay_Color tb_top = {(F32)Min((S32)tb.r+12,255), (F32)Min((S32)tb.g+12,255), (F32)Min((S32)tb.b+12,255), tb.a};
CustomGradientData *tb_grad = alloc_gradient(tb_top, tb);
CLAY(title_bar_id,
@@ -1346,7 +1346,7 @@ S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected) {
.border = { .color = g_theme.border, .width = { .bottom = 1 } },
) {
for (S32 i = 0; i < count; i++) {
Clay_ElementId tab_eid = Clay__HashStringWithOffset(id_str, (uint32_t)i, 0);
Clay_ElementId tab_eid = Clay__HashStringWithOffset(id_str, (U32)i, 0);
B32 is_active = (i == *selected);
B32 hovered = Clay_PointerOver(tab_eid);
@@ -1421,7 +1421,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
};
for (S32 k = 0; k < g_wstate.input.key_count; k++) {
uint8_t key = g_wstate.input.keys[k];
U8 key = g_wstate.input.keys[k];
if (ctrl) {
if (key == PKEY_A) {
@@ -1500,7 +1500,7 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
if (!commit && !cancel) {
for (S32 c = 0; c < g_wstate.input.char_count; c++) {
uint16_t ch = g_wstate.input.chars[c];
U16 ch = g_wstate.input.chars[c];
B32 valid = (ch >= '0' && ch <= '9') || ch == '.' || ch == '-';
if (valid) {
if (KE_HAS_SEL()) elen = ke_delete_sel();
@@ -1537,8 +1537,8 @@ static S32 value_edit_process_keys(F32 *value, F32 max_val, B32 is_signed, B32 *
}
// Render the text edit box with selection/cursor display.
static void value_edit_render(uint32_t hash, F32 width) {
Clay_ElementId edit_eid = CLAY_IDI("ValEdit", (int)hash);
static void value_edit_render(U32 hash, F32 width) {
Clay_ElementId edit_eid = CLAY_IDI("ValEdit", (S32)hash);
char *ebuf = g_wstate.knob_edit_buf;
S32 elen = (S32)strlen(ebuf);
@@ -1588,7 +1588,7 @@ static void value_edit_render(uint32_t hash, F32 width) {
S32 n = sel_hi - sel_lo;
memcpy(ke_dbuf_sel, &ebuf[sel_lo], n); ke_dbuf_sel[n] = '\0';
Clay_String s_sel = { .length = n, .chars = ke_dbuf_sel };
CLAY(CLAY_IDI("ValEditSel", (int)hash),
CLAY(CLAY_IDI("ValEditSel", (S32)hash),
.layout = { .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() } },
.backgroundColor = g_theme.accent
) {
@@ -1616,8 +1616,8 @@ static void value_edit_render(uint32_t hash, F32 width) {
}
// Get the Clay element ID of the current edit box (for click-away detection).
static Clay_ElementId value_edit_eid(uint32_t hash) {
return CLAY_IDI("ValEdit", (int)hash);
static Clay_ElementId value_edit_eid(U32 hash) {
return CLAY_IDI("ValEdit", (S32)hash);
}
// Handle click-outside to commit the edit.
@@ -1636,7 +1636,7 @@ static void value_edit_click_away(Clay_ElementId eid, F32 *value, F32 max_val, B
}
// Enter text edit mode for a widget.
static void value_edit_enter(uint32_t hash, F32 value, B32 is_signed) {
static void value_edit_enter(U32 hash, F32 value, B32 is_signed) {
g_wstate.knob_edit_id = hash;
g_wstate.focused_id = 0;
if (is_signed) {
@@ -1684,7 +1684,7 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
F32 deg_to_rad = 3.14159265f / 180.0f;
F32 angle_rad = (-135.0f + normalized * 270.0f) * deg_to_rad;
uint32_t knob_hash = Clay__HashString(clay_str(id), 0).id;
U32 knob_hash = Clay__HashString(clay_str(id), 0).id;
B32 is_editing = (editable && g_wstate.knob_edit_id == knob_hash);
UI_KnobDragState *kd = &g_wstate.knob_drag;
@@ -1732,7 +1732,7 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
.layoutDirection = CLAY_TOP_TO_BOTTOM,
}
) {
Clay_ElementId knob_eid = CLAY_IDI("KnobBg", (int)knob_hash);
Clay_ElementId knob_eid = CLAY_IDI("KnobBg", (S32)knob_hash);
B32 hovered = Clay_PointerOver(knob_eid);
CLAY(knob_eid,
@@ -1761,7 +1761,7 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
}
}
// Click: double-click resets, single click starts drag
// Click: F64-click resets, single click starts drag
if (!is_editing && hovered && g_wstate.mouse_clicked && kd->dragging_id == 0) {
B32 is_double_click = (kd->last_click_id == knob_hash &&
(g_frame_number - kd->last_click_frame) < 20);
@@ -1785,7 +1785,7 @@ B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_s
value_edit_render(knob_hash, knob_size);
value_edit_click_away(value_edit_eid(knob_hash), value, max_val, is_signed, &changed);
} else if (val_text && val_len > 0) {
Clay_ElementId val_eid = CLAY_IDI("KnobVal", (int)knob_hash);
Clay_ElementId val_eid = CLAY_IDI("KnobVal", (S32)knob_hash);
B32 val_hovered = Clay_PointerOver(val_eid);
Clay_String val_str = { .isStaticallyAllocated = false, .length = val_len, .chars = val_text };
@@ -1824,7 +1824,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
B32 changed = 0;
F32 normalized = value_normalize(*value, max_val, is_signed);
uint32_t hash = Clay__HashString(clay_str(id), 0).id;
U32 hash = Clay__HashString(clay_str(id), 0).id;
B32 is_editing = (editable && g_wstate.knob_edit_id == hash);
UI_KnobDragState *kd = &g_wstate.knob_drag;
@@ -1883,7 +1883,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
CLAY_TEXT(clay_str(label), &g_widget_text_config_dim);
// Hit area (transparent, sized to encompass thumb travel)
Clay_ElementId hit_eid = CLAY_IDI("SlHHit", (int)hash);
Clay_ElementId hit_eid = CLAY_IDI("SlHHit", (S32)hash);
B32 hovered = Clay_PointerOver(hit_eid);
CLAY(hit_eid,
@@ -1893,7 +1893,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
}
) {
// Visible track (centered inside hit area)
CLAY(CLAY_IDI("SlHTrack", (int)hash),
CLAY(CLAY_IDI("SlHTrack", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
},
@@ -1903,7 +1903,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
// Fill bar
F32 fill_w = normalized * track_w;
if (fill_w < 1.0f) fill_w = 1.0f;
CLAY(CLAY_IDI("SlHFill", (int)hash),
CLAY(CLAY_IDI("SlHFill", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(fill_w), .height = CLAY_SIZING_GROW() },
},
@@ -1919,7 +1919,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
idata->icon_id = (S32)UI_ICON_SLIDER_THUMB;
idata->color = g_theme.accent;
CLAY(CLAY_IDI("SlHThumb", (int)hash),
CLAY(CLAY_IDI("SlHThumb", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(thumb_w), .height = CLAY_SIZING_FIXED(thumb_h) },
},
@@ -1941,7 +1941,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
}
}
// Click: double-click resets, single click starts drag
// Click: F64-click resets, single click starts drag
if (!is_editing && hovered && g_wstate.mouse_clicked && kd->dragging_id == 0) {
B32 is_double_click = (kd->last_click_id == hash &&
(g_frame_number - kd->last_click_frame) < 20);
@@ -1964,7 +1964,7 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
value_edit_render(hash, track_w);
value_edit_click_away(value_edit_eid(hash), value, max_val, is_signed, &changed);
} else if (val_text && val_len > 0) {
Clay_ElementId val_eid = CLAY_IDI("SlHVal", (int)hash);
Clay_ElementId val_eid = CLAY_IDI("SlHVal", (S32)hash);
B32 val_hovered = Clay_PointerOver(val_eid);
Clay_String val_str = { .isStaticallyAllocated = false, .length = val_len, .chars = val_text };
@@ -2000,7 +2000,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
B32 changed = 0;
F32 normalized = value_normalize(*value, max_val, is_signed);
uint32_t hash = Clay__HashString(clay_str(id), 0).id;
U32 hash = Clay__HashString(clay_str(id), 0).id;
B32 is_editing = (editable && g_wstate.knob_edit_id == hash);
UI_KnobDragState *kd = &g_wstate.knob_drag;
@@ -2059,7 +2059,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
CLAY_TEXT(clay_str(label), &g_widget_text_config_dim);
// Hit area (transparent, sized to encompass thumb travel)
Clay_ElementId hit_eid = CLAY_IDI("SlVHit", (int)hash);
Clay_ElementId hit_eid = CLAY_IDI("SlVHit", (S32)hash);
B32 hovered = Clay_PointerOver(hit_eid);
CLAY(hit_eid,
@@ -2069,7 +2069,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
}
) {
// Visible track (centered inside hit area)
CLAY(CLAY_IDI("SlVTrack", (int)hash),
CLAY(CLAY_IDI("SlVTrack", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
.childAlignment = { .y = CLAY_ALIGN_Y_BOTTOM },
@@ -2080,7 +2080,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
// Fill bar (from bottom)
F32 fill_h = normalized * track_h;
if (fill_h < 1.0f) fill_h = 1.0f;
CLAY(CLAY_IDI("SlVFill", (int)hash),
CLAY(CLAY_IDI("SlVFill", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(fill_h) },
},
@@ -2096,7 +2096,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
idata->icon_id = (S32)UI_ICON_SLIDER_THUMB;
idata->color = g_theme.accent;
CLAY(CLAY_IDI("SlVThumb", (int)hash),
CLAY(CLAY_IDI("SlVThumb", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(thumb_w), .height = CLAY_SIZING_FIXED(thumb_h) },
},
@@ -2118,7 +2118,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
}
}
// Click: double-click resets, single click starts drag
// Click: F64-click resets, single click starts drag
if (!is_editing && hovered && g_wstate.mouse_clicked && kd->dragging_id == 0) {
B32 is_double_click = (kd->last_click_id == hash &&
(g_frame_number - kd->last_click_frame) < 20);
@@ -2141,7 +2141,7 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
value_edit_render(hash, thumb_w * 2.0f);
value_edit_click_away(value_edit_eid(hash), value, max_val, is_signed, &changed);
} else if (val_text && val_len > 0) {
Clay_ElementId val_eid = CLAY_IDI("SlVVal", (int)hash);
Clay_ElementId val_eid = CLAY_IDI("SlVVal", (S32)hash);
B32 val_hovered = Clay_PointerOver(val_eid);
Clay_String val_str = { .isStaticallyAllocated = false, .length = val_len, .chars = val_text };
@@ -2177,7 +2177,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
B32 changed = 0;
F32 normalized = value_normalize(*value, max_val, is_signed);
uint32_t hash = Clay__HashString(clay_str(id), 0).id;
U32 hash = Clay__HashString(clay_str(id), 0).id;
B32 is_editing = (editable && g_wstate.knob_edit_id == hash);
UI_KnobDragState *kd = &g_wstate.knob_drag;
@@ -2239,7 +2239,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
CLAY_TEXT(clay_str(label), &g_widget_text_config_dim);
// Hit area (transparent, sized to encompass fader cap travel)
Clay_ElementId hit_eid = CLAY_IDI("FdrHit", (int)hash);
Clay_ElementId hit_eid = CLAY_IDI("FdrHit", (S32)hash);
B32 hovered = Clay_PointerOver(hit_eid);
CLAY(hit_eid,
@@ -2249,7 +2249,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
}
) {
// Visible track (centered inside hit area, empty)
CLAY(CLAY_IDI("FdrTrack", (int)hash),
CLAY(CLAY_IDI("FdrTrack", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
},
@@ -2264,7 +2264,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
F32 tw = (i % 5 == 0) ? tick_major_w : tick_minor_w;
// Left tick
CLAY(CLAY_IDI("FdrTkL", (int)(hash * 100 + i)),
CLAY(CLAY_IDI("FdrTkL", (S32)(hash * 100 + i)),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) },
},
@@ -2285,7 +2285,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
) {}
// Right tick
CLAY(CLAY_IDI("FdrTkR", (int)(hash * 100 + i)),
CLAY(CLAY_IDI("FdrTkR", (S32)(hash * 100 + i)),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) },
},
@@ -2315,7 +2315,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
F32 cap_y = (1.0f - normalized) * (track_h - cap_h);
CLAY(CLAY_IDI("FdrCap", (int)hash),
CLAY(CLAY_IDI("FdrCap", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) },
},
@@ -2336,7 +2336,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
Clay_Color tint = g_theme.accent;
tint.a = 80;
F32 cap_corner = cap_w * (3.0f / 62.2f);
CLAY(CLAY_IDI("FdrTint", (int)hash),
CLAY(CLAY_IDI("FdrTint", (S32)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) },
},
@@ -2356,7 +2356,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
}
}
// Click: double-click resets, single click starts drag
// Click: F64-click resets, single click starts drag
if (!is_editing && hovered && g_wstate.mouse_clicked && kd->dragging_id == 0) {
B32 is_double_click = (kd->last_click_id == hash &&
(g_frame_number - kd->last_click_frame) < 20);
@@ -2379,7 +2379,7 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
value_edit_render(hash, cap_w * 2.0f);
value_edit_click_away(value_edit_eid(hash), value, max_val, is_signed, &changed);
} else if (val_text && val_len > 0) {
Clay_ElementId val_eid = CLAY_IDI("FdrVal", (int)hash);
Clay_ElementId val_eid = CLAY_IDI("FdrVal", (S32)hash);
B32 val_hovered = Clay_PointerOver(val_eid);
Clay_String val_str = { .isStaticallyAllocated = false, .length = val_len, .chars = val_text };

View File

@@ -19,51 +19,51 @@
struct UI_ModalState {
B32 active;
uint32_t id; // Hash of the modal's string ID
U32 id; // Hash of the modal's string ID
S32 result; // Button index pressed, -1 = pending
};
struct UI_WindowSlot {
uint32_t id; // Hash of the window's string ID (0 = unused)
U32 id; // Hash of the window's string ID (0 = unused)
Vec2F32 position;
Vec2F32 size;
B32 open;
int16_t z_order;
S16 z_order;
};
struct UI_KnobDragState {
uint32_t dragging_id; // Hash of the knob being dragged (0 = none)
U32 dragging_id; // Hash of the knob being dragged (0 = none)
F32 drag_start_y; // Mouse Y when drag started
F32 drag_start_x; // Mouse X when drag started (for h-slider)
F32 value_at_start; // Value when drag started
B32 was_shift; // Shift state last frame (to re-anchor on change)
uint32_t last_click_id; // Knob hash of last click (for double-click detection)
U32 last_click_id; // Knob hash of last click (for F64-click detection)
S32 last_click_frame; // Frame number of last click
};
struct UI_DragState {
uint32_t dragging_id; // Window ID currently being dragged (0 = none)
U32 dragging_id; // Window ID currently being dragged (0 = none)
Vec2F32 drag_anchor; // Mouse position when drag started
Vec2F32 pos_anchor; // Window position when drag started
};
struct UI_WidgetState {
// Text input focus
uint32_t focused_id; // Clay element ID hash of the focused text input (0 = none)
int32_t cursor_pos; // Cursor position in focused text input
U32 focused_id; // Clay element ID hash of the focused text input (0 = none)
S32 cursor_pos; // Cursor position in focused text input
F32 cursor_blink; // Blink timer (seconds)
// Text selection (sel_start == sel_end means no selection)
int32_t sel_start; // Selection anchor (where selection began)
int32_t sel_end; // Selection extent (moves with cursor)
S32 sel_start; // Selection anchor (where selection began)
S32 sel_end; // Selection extent (moves with cursor)
// Tab cycling: registered text input IDs in order of declaration
uint32_t text_input_ids[UI_WIDGET_MAX_TEXT_INPUTS];
int32_t text_input_count;
U32 text_input_ids[UI_WIDGET_MAX_TEXT_INPUTS];
S32 text_input_count;
B32 tab_pressed; // True on the frame Tab was pressed
// Dropdown
uint32_t open_dropdown_id; // Clay element ID hash of the open dropdown (0 = none)
U32 open_dropdown_id; // Clay element ID hash of the open dropdown (0 = none)
// Input for this frame
PlatformInput input;
@@ -77,14 +77,14 @@ struct UI_WidgetState {
// Window state
UI_WindowSlot windows[UI_WIDGET_MAX_WINDOWS];
S32 window_count;
int16_t next_z;
S16 next_z;
UI_DragState drag;
// Knob drag state
UI_KnobDragState knob_drag;
// Knob text edit state
uint32_t knob_edit_id; // Hash of knob in text edit mode (0 = none)
U32 knob_edit_id; // Hash of knob in text edit mode (0 = none)
char knob_edit_buf[32]; // Text buffer for numeric entry
S32 knob_edit_cursor; // Cursor position in edit buffer
S32 knob_edit_sel_start; // Selection anchor
@@ -154,7 +154,7 @@ B32 ui_window(const char *id, const char *title, B32 *open,
// Knob / potentiometer. Vertical drag to change value.
// unsigned (is_signed=0): value in [0, max_val]
// signed (is_signed=1): value in [-max_val, +max_val]
// default_val: value restored on double-click.
// default_val: value restored on F64-click.
// editable: if true, clicking the value text opens a text input for direct entry.
// Hold Shift while dragging for fine control.
// Returns true if value changed this frame.