Clay custom dispatch improvements & DPI scaling fixes (#26)

Co-authored-by: Zachary Levy <zachary@sunforge.is>
Reviewed-on: #26
This commit was merged in pull request #26.
This commit is contained in:
2026-05-06 04:17:24 +00:00
parent e8ffa28de3
commit 43f08ed30c
19 changed files with 627 additions and 407 deletions
+40 -4
View File
@@ -63,7 +63,7 @@ hellope_shapes :: proc() {
outline_width = 2,
origin = draw.center_of(rect),
rotation = spin_angle,
feather_px = 1,
feather_ppx = 1,
)
// Rounded rectangle rotating around its center
@@ -287,6 +287,22 @@ hellope_custom :: proc() {
value = 0.45,
color = {200, 100, 50, 255},
}
// `clay.CustomElementConfig.customData` is a rawptr; the Clay integration in `draw`
// requires it to point at a `Clay_Custom` value. The explicit `rawptr(...)` cast is
// necessary because Odin does not chain `^Gauge -> rawptr -> Clay_Custom` implicitly
// (variant-to-union and ^T-to-rawptr are each implicit on their own, but not stacked).
gauge_custom: draw.Clay_Custom = rawptr(&gauge)
gauge2_custom: draw.Clay_Custom = rawptr(&gauge2)
// Backdrop variant: variant-to-union conversion is implicit, so no cast needed.
// `tint = draw.WHITE` is the no-op tint per the backdrop module's convention
// (matches `examples/backdrop.odin`'s "pure blur, no color" usage).
backdrop_custom: draw.Clay_Custom = draw.Backdrop_Marker {
sigma = 8,
tint = draw.WHITE,
}
spin_angle: f32 = 0
for {
@@ -320,20 +336,37 @@ hellope_custom :: proc() {
clay.Text("Custom Draw Demo", &text_config)
}
// gauge1 is BEHIND the backdrop — the backdrop is declared as a floating CHILD
// of gauge1, pinned to gauge1's LeftTop and sized 300x30 so it covers exactly
// gauge1's footprint. Clay emits a floating child's render command after the
// parent's, so the stream order is gauge1 → backdrop → gauge2: gauge1's pixels
// land in `source_texture` before the bracket samples (visible as a blurred
// reflection inside the strip), and gauge2 is deferred-replayed by
// `prepare_clay_batch` after the bracket closes (renders crisp on top of the
// bracket output — unrelated to the strip since they don't overlap).
if clay.UI()(
{
id = clay.ID("gauge"),
layout = {sizing = {clay.SizingFixed(300), clay.SizingFixed(30)}},
custom = {customData = &gauge},
custom = {customData = &gauge_custom},
backgroundColor = {80, 80, 80, 255},
},
) {}
) {
if clay.UI()(
{
id = clay.ID("backdrop"),
floating = {attachTo = .Parent, attachment = {parent = .LeftTop, element = .LeftTop}},
layout = {sizing = {clay.SizingFixed(300), clay.SizingFixed(30)}},
custom = {customData = &backdrop_custom},
},
) {}
}
if clay.UI()(
{
id = clay.ID("gauge2"),
layout = {sizing = {clay.SizingFixed(300), clay.SizingFixed(30)}},
custom = {customData = &gauge2},
custom = {customData = &gauge2_custom},
backgroundColor = {80, 80, 80, 255},
},
) {}
@@ -353,6 +386,9 @@ hellope_custom :: proc() {
}
draw_custom :: proc(layer: ^draw.Layer, bounds: draw.Rectangle, render_data: clay.CustomRenderData) {
// `render_data.customData` has been unwrapped from the `Clay_Custom` envelope by
// `prepare_clay_batch` — it points at the Gauge directly, the same as it would have
// before the union refactor.
gauge := cast(^Gauge)render_data.customData
border_width: f32 = 2