GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
fix(widget): ramp preset selection lands — eager child registration made
coverage occlude the composite
The pre-existing bug (a preset ITEM click closed the popover without
selecting): TI's press scan asks the Ramp's hit_test, and
is_coordinate_covered flagged the ramp as occluded by its OWN child
dropdown's open popover — the registered preset dropdown reports a
popover_rect covering the point, and the coverage exclusion is exact-id
only, so the composite never passed its hit gate and the item press never
reached anything (instrumented: the Dropdown logged the OPEN press, never
the item press).
Fix: the ramps' register_embedded_children hooks are gone entirely — the
field widgets need no eager registry presence (the 6bc focus setters
self-register on demand, and the composite itself covers the spatial
grid), and an unregistered child cannot occlude its host. Verified live:
selecting "Peak" now reshapes the curve and updates the label — the
apply_preset drain fires through the pointer path for the first time.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018u7qTwzX95dd5ysAkaSCLk
src/widget/input/ramp.rs | 39 +++++----------------------------------
1 file changed, 5 insertions(+), 34 deletions(-)
diff --git a/src/widget/input/ramp.rs b/src/widget/input/ramp.rs
index 2a10a4c..fecbf42 100644
--- a/src/widget/input/ramp.rs
+++ b/src/widget/input/ramp.rs
@@ -373,24 +373,6 @@ impl Layout for ColorRamp {
}
- fn register_embedded_children(&mut self, host_id: WidgetId, ctx: &mut UiContext) {
- // Registered but NOT tree-linked (6bd self-routing, the TreeList rule): on_event
- // forwards every event class internally — descent double-delivered and starved
- // the composite-level sync/drains.
- let _ = host_id;
- let p = self.r_slider.as_ptr_mut();
- let id = self.r_slider.base().id();
- ctx.register_widget(id, p);
- let p = self.g_slider.as_ptr_mut();
- let id = self.g_slider.base().id();
- ctx.register_widget(id, p);
- let p = self.b_slider.as_ptr_mut();
- let id = self.b_slider.base().id();
- ctx.register_widget(id, p);
- let p = self.del_button.as_ptr_mut();
- let id = self.del_button.base().id();
- ctx.register_widget(id, p);
- }
}
impl Paint for ColorRamp {
@@ -837,22 +819,11 @@ impl Layout for Ramp {
}
- fn register_embedded_children(&mut self, host_id: WidgetId, ctx: &mut UiContext) {
- // Registered but NOT tree-linked (6bd self-routing, the TreeList rule).
- let _ = host_id;
- let p = self.preset_dropdown.as_ptr_mut();
- let id = self.preset_dropdown.base().id();
- ctx.register_widget(id, p);
- let p = self.line_type_dropdown.as_ptr_mut();
- let id = self.line_type_dropdown.base().id();
- ctx.register_widget(id, p);
- let p = self.val_slider.as_ptr_mut();
- let id = self.val_slider.base().id();
- ctx.register_widget(id, p);
- let p = self.del_button.as_ptr_mut();
- let id = self.del_button.base().id();
- ctx.register_widget(id, p);
- }
+ // register_embedded_children: gone entirely (6bd self-routing): the fields need no
+ // eager registry presence — focus setters self-register on demand (6bc), the composite
+ // itself covers the spatial grid, and an eagerly-registered child DROPDOWN's open
+ // popover made `is_coordinate_covered` occlude the composite's own hit gate (the
+ // exclusion is exact-id only), which is why preset-item clicks never landed.
}
impl Paint for Ramp {