widget gallery and compositor test bench
refactor(widget)!: set_parent/add_child off Element — linking is a tree op (6bd)
Element 69 -> 67 (series count). Both methods move to inherent Adapted<W>
(files' ten set_parent(None) sites resolve unchanged); the dyn callers were
three:
- focus::link_parent_child body: the add_child + set_parent pair became the
register + tree.link + tree.set_parent ops it always was (the container
parent-back extra produced the same symmetric link).
- TI's page-selector/StatusBar pair of dyn roster calls -> one
link_parent_child call.
- TI ControlPanel arrange_children's per-child dummy-ctx set_parent: deleted —
every effect was discarded with the dummy ctx (same class as the ramp
rituals).
Adapted::add_child keeps the has_container_children parent-back extra as
direct tree ops.
Verified: 163 tests; workspace builds; A/B TI gallery (the flat-walk
parent() skip still resolves — no page-selector double-draw) and dm greeter
(link_parent_child consumer) — both empty 8% masks.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018u7qTwzX95dd5ysAkaSCLk
src/main.rs | 12 +++++++++---
src/ti_widgets.rs | 9 +++------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index eb02860..27bf5af 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -896,11 +896,17 @@ cascades in cce."
cp.add_child(ptr);
}
- // Set page selector (46) parent to StatusBar (2)
+ // Link page selector (46) under StatusBar (2) — the old set_parent + add_child
+ // pair as the one tree link it always was (6bd batch 4).
let statusbar_ptr = state.roster.get_dyn_mut(2).as_ptr_mut();
- state.roster.get_dyn_mut(46).set_parent(Some(statusbar_ptr), &mut state.ui_context);
let dropdown_ptr = state.roster.get_dyn_mut(46).as_ptr_mut();
- state.roster.get_dyn_mut(2).add_child(dropdown_ptr, &mut state.ui_context);
+ unsafe {
+ cce_ui::widget::focus::link_parent_child(
+ &mut *statusbar_ptr,
+ &mut *dropdown_ptr,
+ &mut state.ui_context,
+ );
+ }
} else {
state.focused_widget = Some(1);
let ramp = state.roster.get_dyn_mut(1).as_any_mut().downcast_mut::<Ramp>().expect("child ramp widget");
diff --git a/src/ti_widgets.rs b/src/ti_widgets.rs
index 130c2a9..59c9401 100644
--- a/src/ti_widgets.rs
+++ b/src/ti_widgets.rs
@@ -282,15 +282,13 @@ impl cce_ui::widget::Layout for ControlPanel {
// The old `set_rect` override's arrangement: children keep their label-matched slots
// in a ColumnLayout, laid out UNSCROLLED; the scroll offset is an aggregate-time
- // transform. `host` (the adapter) becomes the children's parent, as the legacy panel
- // set itself.
- fn arrange_children(&mut self, rect: Rect, host: *mut (dyn Element + 'static)) {
+ // transform. (The dummy-ctx child re-parenting onto the host adapter is gone,
+ // 6bd: every effect of it was discarded with the dummy ctx.)
+ fn arrange_children(&mut self, rect: Rect, _host: *mut (dyn Element + 'static)) {
let (x, y, w, h) = (rect.x, rect.y, rect.width, rect.height);
self.scroll_box.set_rect(x, y, w, h);
- let mut dummy = cce_ui::context::UiContext::new();
- let self_ptr_option = Some(host);
let padding = cce_ui::layout::control_panel_padding();
let gap = cce_ui::layout::control_panel_gap();
@@ -320,7 +318,6 @@ impl cce_ui::widget::Layout for ControlPanel {
for &child_ptr in &self.children {
let child = &mut *child_ptr;
- child.set_parent(self_ptr_option, &mut dummy);
let label = child.base().and_then(|b| b.label.as_ref()).map(|s| s.as_str()).unwrap_or("");
match label {
"Create Window" => create_btn = Some(child_ptr),