Fix faders, z indexing, svg rendering

This commit is contained in:
2026-03-04 00:20:16 -05:00
parent 2927335975
commit af33cf268a
12 changed files with 746 additions and 91 deletions

View File

@@ -204,7 +204,7 @@ void ui_begin_frame(UI_Context *ctx, F32 viewport_w, F32 viewport_h,
Clay_SetCurrentContext(ctx->clay_ctx);
Clay_SetLayoutDimensions(Clay_Dimensions{viewport_w, viewport_h});
Clay_SetPointerState(Clay_Vector2{mouse_pos.x, mouse_pos.y}, mouse_down != 0);
Clay_UpdateScrollContainers(true, Clay_Vector2{scroll_delta.x, scroll_delta.y}, dt);
Clay_UpdateScrollContainers(false, Clay_Vector2{scroll_delta.x, scroll_delta.y}, dt);
Clay_BeginLayout();
}

View File

@@ -170,8 +170,11 @@ struct CustomRotatedIconData {
#define WIDGET_SLIDER_V_THUMB_H uis(14)
#define WIDGET_FADER_HEIGHT uis(160)
#define WIDGET_FADER_TRACK_W uis(4)
#define WIDGET_FADER_CAP_W uis(38)
#define WIDGET_FADER_CAP_W uis(25)
#define WIDGET_FADER_CAP_H uis(52)
#define WIDGET_FADER_TICK_MAJOR_W uis(8)
#define WIDGET_FADER_TICK_MINOR_W uis(4)
#define WIDGET_FADER_TICK_H uis(1)
////////////////////////////////
// Corner radius (from theme)

View File

@@ -30,30 +30,80 @@ static const char *g_icon_svgs[UI_ICON_COUNT] = {
<line x1="12" y1="12" x2="12" y2="3" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
</svg>)",
// UI_ICON_SLIDER_THUMB - layered body with grip ridges
// UI_ICON_SLIDER_THUMB - solid body with grip ridges
R"(<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<rect x="2" y="1" width="20" height="22" rx="4" fill="white" opacity="0.15"/>
<rect x="3" y="2" width="18" height="20" rx="3" fill="white" opacity="0.55"/>
<rect x="4" y="3" width="16" height="1" rx="0.5" fill="white" opacity="0.3"/>
<line x1="6" y1="8" x2="18" y2="8" stroke="white" stroke-width="1" opacity="0.8"/>
<line x1="6" y1="11" x2="18" y2="11" stroke="white" stroke-width="1" opacity="0.8"/>
<line x1="6" y1="14" x2="18" y2="14" stroke="white" stroke-width="1" opacity="0.8"/>
<line x1="6" y1="17" x2="18" y2="17" stroke="white" stroke-width="1" opacity="0.8"/>
<rect x="2" y="1" width="20" height="22" rx="4" fill="white"/>
<line x1="6" y1="8" x2="18" y2="8" stroke="black" stroke-width="1.2" opacity="0.3"/>
<line x1="6" y1="11" x2="18" y2="11" stroke="black" stroke-width="1.2" opacity="0.3"/>
<line x1="6" y1="14" x2="18" y2="14" stroke="black" stroke-width="1.2" opacity="0.3"/>
<line x1="6" y1="17" x2="18" y2="17" stroke="black" stroke-width="1.2" opacity="0.3"/>
</svg>)",
// UI_ICON_FADER - Pro Tools-style fader cap: solid body, bright center indicator, beveled caps
R"(<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 48">
<rect x="1" y="0" width="22" height="48" rx="3" fill="white" opacity="0.7"/>
<rect x="2" y="1" width="20" height="5" rx="2" fill="white" opacity="0.85"/>
<rect x="2" y="1" width="20" height="1.5" rx="0.5" fill="white" opacity="0.95"/>
<line x1="5" y1="10" x2="19" y2="10" stroke="black" stroke-width="0.5" opacity="0.2"/>
<line x1="5" y1="14" x2="19" y2="14" stroke="black" stroke-width="0.5" opacity="0.2"/>
<rect x="1" y="22" width="22" height="4" rx="0.5" fill="white" opacity="1.0"/>
<line x1="5" y1="30" x2="19" y2="30" stroke="black" stroke-width="0.5" opacity="0.2"/>
<line x1="5" y1="34" x2="19" y2="34" stroke="black" stroke-width="0.5" opacity="0.2"/>
<rect x="2" y="42" width="20" height="5" rx="2" fill="white" opacity="0.85"/>
<rect x="2" y="45.5" width="20" height="1.5" rx="0.5" fill="white" opacity="0.6"/>
</svg>)",
// UI_ICON_FADER - exact asset fader cap from assets/fader.svg
R"SVG(<svg xmlns="http://www.w3.org/2000/svg" viewBox="847 488 62.2 129.3">
<defs>
<linearGradient id="linearGradient7718" y2="528.75" gradientUnits="userSpaceOnUse" x2="87.866" gradientTransform="matrix(1.0278,0,0,1,787.52,-27.904)" y1="516.83" x1="87.866">
<stop style="stop-color:#999999" offset="0"/>
<stop style="stop-color:#999999;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7720" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1.0235,0,0,1,242.38,-1008.6)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7722" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1,0,0,0.50643,256.46,265.42)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7724" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1,0,0,0.42746,256.46,317.38)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7726" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1,0,0,0.26952,256.46,405.1)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7728" y2="521.42" gradientUnits="userSpaceOnUse" x2="87.866" gradientTransform="matrix(1.0364,0,0,0.96441,786.64,-1114.5)" y1="516.83" x1="87.866">
<stop style="stop-color:#999999" offset="0"/>
<stop style="stop-color:#333333" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7730" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1.0364,0,0,0.96441,234.39,-1076.7)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7732" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1.0274,0,0,0.48841,240.25,-833.5)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7734" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1.0213,0,0,0.41225,243.85,-783.64)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient7736" y2="499.1" gradientUnits="userSpaceOnUse" x2="618.49" gradientTransform="matrix(1.0122,0,0,0.25993,249.26,-698.66)" y1="496.57" x1="618.49">
<stop style="stop-color:#cccccc" offset="0"/>
<stop style="stop-color:#cccccc;stop-opacity:0" offset="1"/>
</linearGradient>
</defs>
<rect style="fill:#4d4d4d" rx="3" ry="3" height="129.29" width="62.143" y="488.03" x="847.03"/>
<rect style="fill:#e6e6e6" height="3.5355" width="60.419" y="552.42" x="847.97"/>
<rect style="fill:url(#linearGradient7718)" rx="2.148" ry="2" height="21.071" width="60.613" y="488.74" x="847.72"/>
<rect style="fill:#333333" height="10.119" width="58.811" y="540.26" x="847.92"/>
<rect style="fill:#333333" height="8.793" width="61.133" y="530.89" x="847.03"/>
<rect style="fill:#1a1a1a" height="4.546" width="61.133" y="512.48" x="847.03"/>
<rect style="fill:#1a1a1a" height="11.364" width="61.133" y="518.25" x="847.03"/>
<rect style="fill:url(#linearGradient7720)" rx="1.024" ry="0.64" transform="scale(1,-1)" height="2.261" width="60.012" y="-511.76" x="847.72"/>
<rect style="fill:url(#linearGradient7722)" rx="1" ry="0.324" height="1.145" width="58.633" y="517.03" x="847.89"/>
<rect style="fill:url(#linearGradient7724)" rx="1" ry="0.273" height="0.967" width="58.633" y="529.76" x="847.89"/>
<rect style="fill:url(#linearGradient7726)" rx="1" ry="0.172" height="0.609" width="58.633" y="539.01" x="847.89"/>
<rect style="fill:url(#linearGradient7728)" transform="scale(1,-1)" rx="2.166" ry="1.929" height="20.321" width="61.118" y="-616.24" x="847.34"/>
<rect style="fill:#333333" transform="scale(1,-1)" height="9.759" width="58.811" y="-567.93" x="847.92"/>
<rect style="fill:#666666" transform="scale(1,-1)" height="8.48" width="61.133" y="-576.96" x="847.03"/>
<rect style="fill:#808080" transform="scale(1,-1)" height="4.384" width="61.133" y="-594.72" x="847.03"/>
<rect style="fill:#808080" transform="scale(1,-1)" height="10.96" width="61.133" y="-589.16" x="847.03"/>
<rect style="fill:url(#linearGradient7730)" transform="scale(1,-1)" rx="1.036" ry="0.617" height="2.181" width="60.767" y="-597.6" x="847.34"/>
<rect style="fill:url(#linearGradient7732)" transform="scale(1,-1)" rx="1.027" ry="0.312" height="1.104" width="60.24" y="-590.84" x="847.89"/>
<rect style="fill:url(#linearGradient7734)" transform="scale(1,-1)" rx="1.021" ry="0.264" height="0.932" width="59.883" y="-578.82" x="847.89"/>
<rect style="fill:url(#linearGradient7736)" transform="scale(1,-1)" rx="1.012" ry="0.166" height="0.588" width="59.347" y="-569.52" x="847.89"/>
</svg>)SVG",
};
U8 *ui_icons_rasterize_atlas(S32 *out_w, S32 *out_h, S32 icon_size) {
@@ -65,7 +115,7 @@ U8 *ui_icons_rasterize_atlas(S32 *out_w, S32 *out_h, S32 icon_size) {
if (atlas_w < 64) atlas_w = 64;
if (atlas_h < 64) atlas_h = 64;
U8 *atlas = (U8 *)calloc(atlas_w * atlas_h, 1);
U8 *atlas = (U8 *)calloc(atlas_w * atlas_h * 4, 1);
if (!atlas) return nullptr;
S32 pen_x = 0;
@@ -76,7 +126,7 @@ U8 *ui_icons_rasterize_atlas(S32 *out_w, S32 *out_h, S32 icon_size) {
lunasvg::Bitmap bmp = doc->renderToBitmap(icon_size, icon_size);
if (bmp.isNull()) continue;
// Extract alpha channel from ARGB32 premultiplied into R8
// Copy BGRA premultiplied → RGBA straight (un-premultiply)
U8 *src = bmp.data();
S32 bmp_w = bmp.width();
S32 bmp_h = bmp.height();
@@ -84,9 +134,18 @@ U8 *ui_icons_rasterize_atlas(S32 *out_w, S32 *out_h, S32 icon_size) {
for (S32 y = 0; y < bmp_h && y < atlas_h; y++) {
for (S32 x = 0; x < bmp_w && (pen_x + x) < atlas_w; x++) {
// ARGB32 premultiplied: bytes are B, G, R, A (little-endian)
U8 a = src[y * stride + x * 4 + 3];
atlas[y * atlas_w + pen_x + x] = a;
U8 *s = &src[y * stride + x * 4];
S32 dst_idx = (y * atlas_w + pen_x + x) * 4;
U8 b = s[0], g = s[1], r = s[2], a = s[3];
if (a > 0 && a < 255) {
r = (U8)((r * 255) / a);
g = (U8)((g * 255) / a);
b = (U8)((b * 255) / a);
}
atlas[dst_idx + 0] = r;
atlas[dst_idx + 1] = g;
atlas[dst_idx + 2] = b;
atlas[dst_idx + 3] = a;
}
}

View File

@@ -20,7 +20,7 @@ struct UI_IconInfo {
extern UI_IconInfo g_icons[UI_ICON_COUNT];
// Rasterizes all icons into an R8 atlas bitmap.
// Rasterizes all icons into an RGBA8 atlas bitmap (4 bytes per pixel).
// Returns malloc'd data (caller frees). Sets *out_w, *out_h to atlas dimensions.
// icon_size is the pixel height to rasterize each icon at.
U8 *ui_icons_rasterize_atlas(S32 *out_w, S32 *out_h, S32 icon_size);

View File

@@ -105,8 +105,8 @@ static void emit_shadow(Clay_BoundingBox bb, F32 ox, F32 oy, F32 radius,
.backgroundColor = {0, 0, 0, per_layer},
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS + expand),
.floating = {
.parentId = parent_id,
.offset = { -expand + ox, -expand + oy },
.parentId = parent_id,
.zIndex = z,
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
@@ -732,8 +732,8 @@ B32 ui_text_input(const char *id, char *buf, S32 buf_size) {
},
.backgroundColor = bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = border_color, .width = { 1, 1, 1, 1 } },
.custom = { .customData = inset_grad },
.border = { .color = border_color, .width = { 1, 1, 1, 1 } },
) {
if (len == 0 && !is_focused) {
// Placeholder
@@ -850,8 +850,8 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
},
.backgroundColor = bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = is_open ? g_theme.accent : g_theme.border, .width = { 1, 1, 1, 1 } },
.custom = { .customData = dd_grad },
.border = { .color = is_open ? g_theme.accent : g_theme.border, .width = { 1, 1, 1, 1 } },
) {
CLAY(text_eid,
.layout = {
@@ -902,7 +902,6 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
},
.backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
.border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } },
.floating = {
.parentId = eid.id,
.zIndex = 2000,
@@ -911,7 +910,8 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
.parent = CLAY_ATTACH_POINT_LEFT_BOTTOM,
},
.attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
}
},
.border = { .color = g_theme.border, .width = { 1, 1, 1, 1 } },
) {
for (S32 i = 0; i < count; i++) {
B32 is_item_selected = (*selected == i);
@@ -1056,8 +1056,8 @@ S32 ui_modal(const char *id, const char *title, const char *message,
},
.backgroundColor = g_theme.title_bar,
.cornerRadius = { CORNER_RADIUS, CORNER_RADIUS, 0, 0 },
.border = { .color = g_theme.border, .width = { .bottom = 1 } },
.custom = { .customData = mtb_grad },
.border = { .color = g_theme.border, .width = { .bottom = 1 } },
) {
CLAY_TEXT(clay_str(title), &g_widget_text_config);
}
@@ -1264,8 +1264,8 @@ B32 ui_window(const char *id, const char *title, B32 *open,
},
.backgroundColor = g_theme.title_bar,
.cornerRadius = { CORNER_RADIUS, CORNER_RADIUS, 0, 0 },
.border = { .color = g_theme.border, .width = { .bottom = 1 } },
.custom = { .customData = tb_grad },
.border = { .color = g_theme.border, .width = { .bottom = 1 } },
) {
// Title text (grows to push close button right)
CLAY(WIDI(id, 3002),
@@ -1916,7 +1916,6 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(thumb_w), .height = CLAY_SIZING_FIXED(thumb_h) },
},
.custom = { .customData = idata },
.floating = {
.offset = {
.x = normalized * (track_w - thumb_w),
@@ -1928,7 +1927,9 @@ B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32
},
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT,
}
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
},
.custom = { .customData = idata },
) {}
}
}
@@ -2092,7 +2093,6 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(thumb_w), .height = CLAY_SIZING_FIXED(thumb_h) },
},
.custom = { .customData = idata },
.floating = {
.offset = {
.x = 0,
@@ -2104,7 +2104,9 @@ B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32
},
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT,
}
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
},
.custom = { .customData = idata },
) {}
}
}
@@ -2210,9 +2212,12 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
S32 val_len = 0;
char *val_text = is_editing ? nullptr : value_format_text(*value, is_signed, &val_len);
// Dimmed accent for fill bar
Clay_Color fill_color = g_theme.accent;
fill_color.a = 160;
// Tick mark dimensions
F32 tick_major_w = WIDGET_FADER_TICK_MAJOR_W;
F32 tick_minor_w = WIDGET_FADER_TICK_MINOR_W;
F32 tick_h = WIDGET_FADER_TICK_H;
S32 num_ticks = 10;
F32 track_left = (cap_w - track_w) / 2.0f;
// Layout: vertical column (label → hit area with track → value/edit)
CLAY(WID(id),
@@ -2236,43 +2241,31 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
.childAlignment = { .x = CLAY_ALIGN_X_CENTER },
}
) {
// Visible track (centered inside hit area)
// Visible track (centered inside hit area, empty)
CLAY(CLAY_IDI("FdrTrack", (int)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(track_w), .height = CLAY_SIZING_FIXED(track_h) },
.childAlignment = { .y = CLAY_ALIGN_Y_BOTTOM },
},
.backgroundColor = g_theme.bg_dark,
.cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)
) {
// Fill bar (from bottom)
F32 fill_h = normalized * track_h;
if (fill_h < 1.0f) fill_h = 1.0f;
CLAY(CLAY_IDI("FdrFill", (int)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(fill_h) },
},
.backgroundColor = fill_color,
.cornerRadius = CLAY_CORNER_RADIUS(track_w / 2.0f)
) {}
}
) {}
// Floating fader cap (icon, silver colored)
if (g_icon_pool_count < UI_MAX_ICONS_PER_FRAME) {
CustomIconData *idata = &g_icon_pool[g_icon_pool_count++];
idata->type = CUSTOM_RENDER_ICON;
idata->icon_id = (S32)UI_ICON_FADER;
idata->color = Clay_Color{200, 200, 210, 255};
// Tick marks on both sides of the track
for (S32 i = 0; i <= num_ticks; i++) {
F32 norm = (F32)i / (F32)num_ticks;
F32 tick_y = (1.0f - norm) * (track_h - tick_h);
F32 tw = (i % 5 == 0) ? tick_major_w : tick_minor_w;
CLAY(CLAY_IDI("FdrCap", (int)hash),
// Left tick
CLAY(CLAY_IDI("FdrTkL", (int)(hash * 100 + i)),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) },
.sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) },
},
.custom = { .customData = idata },
.backgroundColor = g_theme.text_dim,
.floating = {
.offset = {
.x = 0,
.y = (1.0f - normalized) * (track_h - cap_h),
.x = track_left - tw,
.y = tick_y,
},
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
@@ -2280,7 +2273,78 @@ B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_
},
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT,
}
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
},
) {}
// Right tick
CLAY(CLAY_IDI("FdrTkR", (int)(hash * 100 + i)),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(tw), .height = CLAY_SIZING_FIXED(tick_h) },
},
.backgroundColor = g_theme.text_dim,
.floating = {
.offset = {
.x = track_left + track_w,
.y = tick_y,
},
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP,
},
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
},
) {}
}
// Floating fader cap (RGBA icon from asset SVG)
if (g_icon_pool_count < UI_MAX_ICONS_PER_FRAME) {
CustomIconData *idata = &g_icon_pool[g_icon_pool_count++];
idata->type = CUSTOM_RENDER_ICON;
idata->icon_id = (S32)UI_ICON_FADER;
idata->color = Clay_Color{255, 255, 255, 255};
F32 cap_y = (1.0f - normalized) * (track_h - cap_h);
CLAY(CLAY_IDI("FdrCap", (int)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) },
},
.floating = {
.offset = { .x = 0, .y = cap_y },
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP,
},
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
},
.custom = { .customData = idata },
) {}
// Color tint overlay on top of fader cap
Clay_Color tint = g_theme.accent;
tint.a = 80;
F32 cap_corner = cap_w * (3.0f / 62.2f);
CLAY(CLAY_IDI("FdrTint", (int)hash),
.layout = {
.sizing = { .width = CLAY_SIZING_FIXED(cap_w), .height = CLAY_SIZING_FIXED(cap_h) },
},
.backgroundColor = tint,
.cornerRadius = CLAY_CORNER_RADIUS(cap_corner),
.floating = {
.offset = { .x = 0, .y = cap_y },
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP,
},
.pointerCaptureMode = CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH,
.attachTo = CLAY_ATTACH_TO_PARENT,
.clipTo = CLAY_CLIP_TO_ATTACHED_PARENT,
},
) {}
}
}