GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
refactor(widget)!: Element is DELETED — the trait is WidgetHost (6bd flip)
The rename that ends the god-trait: after the census-driven shrink batches
(125 -> ~65 methods) and the base() guarantee, `Element` matched the measured
host blueprint and became `WidgetHost` — the single surface the machinery
(context routing, paint walk, render loop, app dyn broadcasts) sees.
`Adapted<W>` remains the one production implementor; concrete behavior lives
on the narrow Layout/Paint/Input traits. `ElementState` (the input enum) is
unrelated and keeps its name; cce-layout-interface's local `Element` document
enum is untouched (it aliased the trait as UiElement).
634 occurrences across 18 crates, word-boundary exact; the workspace compiled
on the first pass. CLAUDE.md updated.
Verified: 163 tests; settings audio render stream byte-identical to the
pre-flip baseline.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018u7qTwzX95dd5ysAkaSCLk
CLAUDE.md | 23 ++--
src/backend/window_runner.rs | 18 +--
src/context.rs | 44 +++----
src/layout.rs | 56 ++++-----
src/main.rs | 4 +-
src/scene/arena.rs | 14 +--
src/scene/painter.rs | 36 +++---
src/scene/tree.rs | 36 +++---
src/widget/container/breadcrumb.rs | 2 +-
src/widget/container/container_layout.rs | 32 ++---
src/widget/container/menu.rs | 22 ++--
src/widget/container/paginator.rs | 16 +--
src/widget/container/parameters_bg.rs | 18 +--
src/widget/container/scroll_box.rs | 18 +--
src/widget/container/spreadsheet.rs | 32 ++---
src/widget/container/treelist.rs | 4 +-
src/widget/core.rs | 28 ++---
src/widget/display/float3.rs | 16 +--
src/widget/display/graph.rs | 20 ++--
src/widget/display/label.rs | 12 +-
src/widget/display/node.rs | 14 +--
src/widget/display/panel.rs | 4 +-
src/widget/display/progress_bar.rs | 26 ++---
src/widget/display/separator.rs | 18 +--
src/widget/display/serialize.rs | 6 +-
src/widget/display/sidebar.rs | 4 +-
src/widget/display/splitter.rs | 4 +-
src/widget/display/status_bar.rs | 20 ++--
src/widget/display/status_dot.rs | 10 +-
src/widget/display/usage_bar.rs | 8 +-
src/widget/input/button.rs | 16 +--
src/widget/input/checkbox.rs | 48 ++++----
src/widget/input/dropdown.rs | 20 ++--
src/widget/input/slider.rs | 54 ++++-----
src/widget/input/spinbox.rs | 16 +--
src/widget/input/text_box.rs | 8 +-
src/widget/layout_helper.rs | 8 +-
src/widget/mod.rs | 28 +++--
src/widget/model.rs | 194 +++++++++++++++----------------
39 files changed, 482 insertions(+), 475 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index b8a4943..b87c45f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -87,7 +87,7 @@ appended as a final unclipped batch drawn on top.
## The `scene/` core rebuild (read `docs/rfc-core-rebuild.md` before touching it)
`src/scene/` is a **retained scene graph being grown additively** to replace three overlaid legacy
-subsystems (tripled tree ownership via raw `*mut dyn Element`; three uncoordinated render paths;
+subsystems (tripled tree ownership via raw widget pointers; three uncoordinated render paths;
layout smeared across five mechanisms). The RFC (`docs/rfc-core-rebuild.md`) is the authoritative
design and phase tracker — its inline "DONE" notes are the source of truth for what has landed.
Modules:
@@ -99,20 +99,21 @@ Modules:
- `layout.rs` — the hand-rolled measure→arrange solver (`Style`/`Size`/`Rect`/`LayoutBox`).
Deliberately **not** taffy: a compact row/column + flex + align + gap/padding box model.
- `paint.rs` / `painter.rs` — `DisplayList` + `PaintCtx` (clip/transform stack) and the single
- paint walk. Each widget emits its own geometry via `Element::paint_self`; the walk owns recursion
- and clipping (`Element::clips_children`), instead of every container re-deriving intersections.
- `renders_own_subtree` is an escape hatch for legacy subtree painters.
+ paint walk. Each widget emits its own geometry via `WidgetHost::paint_self`; the walk owns
+ recursion and clipping (`WidgetHost::clips_children`), instead of every container re-deriving
+ intersections. `renders_own_subtree` is an escape hatch for legacy subtree painters.
- `anim.rs` — `Animated<T>` (tween + spring + easing), the Phase 4 animation primitive replacing
ad-hoc bool flips.
-### `Element` scene hooks (migration surface)
+### `WidgetHost` (formerly the `Element` god-trait)
-The legacy `Element` trait (`src/widget/mod.rs`, ~125 methods — the god-trait the RFC is
-dismantling) carries the opt-in hooks that move a widget onto the new core, all defaulting to the
-legacy path: `layout_style()` / `intrinsic_size()` (→ layout engine), `paint_self()` /
-`clips_children()` / `renders_own_subtree()` (→ single paint path), `children()`. Migrate a widget
-by implementing these; leave them defaulted to keep it on the legacy path. This is what lets a
-single container be moved and verified in a running app without disturbing the rest.
+`WidgetHost` (`src/widget/mod.rs`) is the single ~65-method host surface the machinery
+(context routing, paint walk, render loop, app dyn broadcasts) sees, produced by the RFC's 6bd
+shrink-then-rename of the old ~125-method `Element` god-trait. Its ONE production implementor
+is `Adapted<W>`; concrete widget behavior lives on the narrow `Layout`/`Paint`/`Input` traits
+(`src/widget/model.rs`). `base()` is guaranteed (`&Widget`, no Option). The direct-dispatch
+block (mouse/key/drag) and value block shrink further as apps adopt routed events and
+concrete slots — see the RFC's blueprint notes before adding anything to this trait.
**Runtime verification matters here.** Several scene changes are "compiles + tests pass; runtime
verification pending" per the RFC — the headless tests can't catch paint/event regressions. When
diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index 4dbd156..2d768b3 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -37,7 +37,7 @@ use glyphon::{
FontSystem, Resolution, TextArea,
TextBounds, Buffer, Attrs, Metrics,
};
-use crate::widget::{Element, TextItem, MouseButton, ElementState, MouseScrollDelta, KeyEvent, Key, NamedKey, Position};
+use crate::widget::{WidgetHost, TextItem, MouseButton, ElementState, MouseScrollDelta, KeyEvent, Key, NamedKey, Position};
use crate::wayland::detect_scale_factor;
use crate::backend::WgpuAdapter;
@@ -986,13 +986,13 @@ pub fn push_plate_solid_border_vertices_legacy(
push_plate_solid_border_vertices(x, y, ww, h, radii, t, sw, sh, color, clip_circle, out);
}
-pub fn widget_vertices(w: &dyn crate::widget::Element, sw: f32, sh: f32, clip_circle: [f32; 3]) -> Vec<Vertex> {
+pub fn widget_vertices(w: &dyn crate::widget::WidgetHost, sw: f32, sh: f32, clip_circle: [f32; 3]) -> Vec<Vertex> {
let mut verts = Vec::new();
push_widget_vertices(w, sw, sh, clip_circle, &mut verts);
verts
}
-pub fn push_widget_vertices(w: &dyn crate::widget::Element, sw: f32, sh: f32, clip_circle: [f32; 3], out: &mut Vec<Vertex>) {
+pub fn push_widget_vertices(w: &dyn crate::widget::WidgetHost, sw: f32, sh: f32, clip_circle: [f32; 3], out: &mut Vec<Vertex>) {
let (x, y, ww, h) = w.rect();
let radii = w.corner_radii();
if let Some(thickness) = w.plate_bevel() {
@@ -1106,7 +1106,7 @@ pub fn tessellate_display_list(
}
pub fn extra_quad_vertices(
- w: &dyn crate::widget::Element,
+ w: &dyn crate::widget::WidgetHost,
qx: f32, qy: f32, qw: f32, qh: f32,
sw: f32, sh: f32,
qc: [f32; 4],
@@ -1118,9 +1118,9 @@ pub fn extra_quad_vertices(
}
fn get_child_widget_for_quad<'a>(
- w: &'a dyn crate::widget::Element,
+ w: &'a dyn crate::widget::WidgetHost,
qx: f32, qy: f32, qw: f32, qh: f32,
-) -> &'a dyn crate::widget::Element {
+) -> &'a dyn crate::widget::WidgetHost {
if let Some(pbg) = w.as_any().downcast_ref::<crate::widget::ParametersBg>() {
for s_opt in &pbg.sliders {
if let Some(s) = s_opt {
@@ -1191,7 +1191,7 @@ fn get_child_widget_for_quad<'a>(
}
pub fn push_extra_quad_vertices(
- w: &dyn crate::widget::Element,
+ w: &dyn crate::widget::WidgetHost,
qx: f32, qy: f32, qw: f32, qh: f32,
sw: f32, sh: f32,
qc: [f32; 4],
@@ -1245,7 +1245,7 @@ pub fn push_extra_quad_vertices(
}
pub fn extra_quad_vertices_clipped(
- w: &dyn crate::widget::Element,
+ w: &dyn crate::widget::WidgetHost,
qx: f32, qy: f32, qw: f32, qh: f32,
sw: f32, sh: f32,
qc: [f32; 4],
@@ -1258,7 +1258,7 @@ pub fn extra_quad_vertices_clipped(
}
pub fn push_extra_quad_vertices_clipped(
- w: &dyn crate::widget::Element,
+ w: &dyn crate::widget::WidgetHost,
qx: f32, qy: f32, qw: f32, qh: f32,
sw: f32, sh: f32,
qc: [f32; 4],
diff --git a/src/context.rs b/src/context.rs
index f05994f..d19a078 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -1,5 +1,5 @@
use std::collections::HashMap;
-use crate::widget::{Element, WidgetId, Key, NamedKey, MouseButton, ElementState, Event};
+use crate::widget::{WidgetHost, WidgetId, Key, NamedKey, MouseButton, ElementState, Event};
use crate::widget::core::hover_animation::HoverState;
use crate::widget::core::context_menu::ContextMenuState;
@@ -104,15 +104,15 @@ impl UiContext {
}
}
- pub fn get_widget(&self, id: WidgetId) -> Option<&(dyn Element + 'static)> {
+ pub fn get_widget(&self, id: WidgetId) -> Option<&(dyn WidgetHost + 'static)> {
self.tree.get_ptr(id).map(|ptr| unsafe { &*ptr })
}
- pub fn get_widget_mut(&mut self, id: WidgetId) -> Option<&mut (dyn Element + 'static)> {
+ pub fn get_widget_mut(&mut self, id: WidgetId) -> Option<&mut (dyn WidgetHost + 'static)> {
self.tree.get_ptr(id).map(|ptr| unsafe { &mut *ptr })
}
- pub fn propagate_event(&mut self, event: &Event, root: *mut (dyn Element + 'static)) -> bool {
+ pub fn propagate_event(&mut self, event: &Event, root: *mut (dyn WidgetHost + 'static)) -> bool {
if let Event::MouseWheel { .. } = event {
let now = std::time::Instant::now();
let elapsed_ms = match self.last_scroll_time {
@@ -167,7 +167,7 @@ impl UiContext {
self.propagate_event_impl(event, root)
}
- fn propagate_event_impl(&mut self, event: &Event, root: *mut (dyn Element + 'static)) -> bool {
+ fn propagate_event_impl(&mut self, event: &Event, root: *mut (dyn WidgetHost + 'static)) -> bool {
if root.is_null() {
return false;
}
@@ -332,7 +332,7 @@ impl UiContext {
pub fn clear_dirty(&mut self) {
self.any_dirty = false;
- let ptrs: Vec<*mut (dyn Element + 'static)> =
+ let ptrs: Vec<*mut (dyn WidgetHost + 'static)> =
self.tree.iter_registered().map(|(_, ptr)| ptr).collect();
for ptr in ptrs {
unsafe {
@@ -344,7 +344,7 @@ impl UiContext {
pub fn rebuild_spatial_grid(&mut self) {
self.spatial_grid.clear();
- let entries: Vec<(WidgetId, *mut (dyn Element + 'static))> =
+ let entries: Vec<(WidgetId, *mut (dyn WidgetHost + 'static))> =
self.tree.iter_registered().collect();
for (id, ptr) in entries {
unsafe {
@@ -411,13 +411,13 @@ impl UiContext {
}
// --- Focus management (id-keyed; Phase 6bc) ---
- pub fn set_focused(&mut self, w: &mut dyn Element) {
+ pub fn set_focused(&mut self, w: &mut dyn WidgetHost) {
let id = w.base().id();
// Refresh the registry with the pointer we were just handed, so focus on a
// not-yet-registered widget keeps working (the legacy code stored this pointer
// directly; the id must resolve for FocusOut/KeyInput dispatch to reach it).
let new_ptr = unsafe {
- std::mem::transmute::<*mut dyn Element, *mut (dyn Element + 'static)>(w as *mut dyn Element)
+ std::mem::transmute::<*mut dyn WidgetHost, *mut (dyn WidgetHost + 'static)>(w as *mut dyn WidgetHost)
};
self.tree.register(id, new_ptr);
self.set_focused_id(id);
@@ -426,7 +426,7 @@ impl UiContext {
/// Transitional pointer form (TreeList focuses its adapter via `EventCtx::host_ptr`). The
/// pointer must be live at the call — it is only used to derive the id and refresh the
/// registry, never stored.
- pub fn set_focused_ptr(&mut self, new_ptr: *mut (dyn Element + 'static)) {
+ pub fn set_focused_ptr(&mut self, new_ptr: *mut (dyn WidgetHost + 'static)) {
if new_ptr.is_null() {
return;
}
@@ -461,7 +461,7 @@ impl UiContext {
}
}
- pub fn is_focused(&self, w: &dyn Element) -> bool {
+ pub fn is_focused(&self, w: &dyn WidgetHost) -> bool {
self.is_focused_id(w.base().id())
}
@@ -480,7 +480,7 @@ impl UiContext {
}
}
- pub fn clear_if_matches(&mut self, w: &dyn Element) {
+ pub fn clear_if_matches(&mut self, w: &dyn WidgetHost) {
if self.focused_widget == Some(w.base().id()) {
self.focused_widget = None;
}
@@ -556,7 +556,7 @@ impl UiContext {
}
// --- Registry (backed by the generational WidgetTree; see scene/tree.rs) ---
- pub fn register_widget(&mut self, id: WidgetId, ptr: *mut (dyn Element + 'static)) {
+ pub fn register_widget(&mut self, id: WidgetId, ptr: *mut (dyn WidgetHost + 'static)) {
self.tree.register(id, ptr);
unsafe {
if !ptr.is_null() && (*ptr).wants_tick() {
@@ -588,15 +588,15 @@ impl UiContext {
/// Register an open popover. Takes `&mut` so the registry can be refreshed with the
/// pointer we are handed (the occlusion walks resolve the stored id through the tree).
- pub fn register_popover(&mut self, w: &mut (dyn Element + 'static)) {
+ pub fn register_popover(&mut self, w: &mut (dyn WidgetHost + 'static)) {
let id = w.base().id();
- self.tree.register(id, w as *mut (dyn Element + 'static));
+ self.tree.register(id, w as *mut (dyn WidgetHost + 'static));
if !self.active_popovers.contains(&id) {
self.active_popovers.push(id);
}
}
- pub fn register_popover_ptr(&mut self, ptr: *mut (dyn Element + 'static)) {
+ pub fn register_popover_ptr(&mut self, ptr: *mut (dyn WidgetHost + 'static)) {
if ptr.is_null() {
return;
}
@@ -692,7 +692,7 @@ impl UiContext {
crate::widget::context_menu::is_visible()
}
- pub fn show_context_menu(&mut self, x: f32, y: f32, options: Vec<String>, header_count: usize, target: *mut (dyn Element + 'static)) {
+ pub fn show_context_menu(&mut self, x: f32, y: f32, options: Vec<String>, header_count: usize, target: *mut (dyn WidgetHost + 'static)) {
if target.is_null() {
return;
}
@@ -701,7 +701,7 @@ impl UiContext {
crate::widget::context_menu::show(x, y, options, header_count, id);
}
- pub fn handle_right_click(&mut self, target: *mut (dyn Element + 'static), px: f32, py: f32) {
+ pub fn handle_right_click(&mut self, target: *mut (dyn WidgetHost + 'static), px: f32, py: f32) {
if target.is_null() {
return;
}
@@ -863,7 +863,7 @@ impl UiContext {
false
}
- fn find_hovered_scrollable(&self, root: *mut (dyn Element + 'static), cx: f32, cy: f32) -> Option<*mut (dyn Element + 'static)> {
+ fn find_hovered_scrollable(&self, root: *mut (dyn WidgetHost + 'static), cx: f32, cy: f32) -> Option<*mut (dyn WidgetHost + 'static)> {
unsafe {
if root.is_null() {
return None;
@@ -890,13 +890,13 @@ impl UiContext {
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::{Element, Widget};
+ use crate::widget::{WidgetHost, Widget};
- /// A plain drag-blocking widget (the `Element` default) at a fixed rect.
+ /// A plain drag-blocking widget (the `WidgetHost` default) at a fixed rect.
struct Block {
base: Widget,
}
- impl Element for Block {
+ impl WidgetHost for Block {
crate::impl_widget_base!(Block);
fn color(&self) -> [f32; 4] {
[0.0, 0.0, 0.0, 1.0]
diff --git a/src/layout.rs b/src/layout.rs
index 7a8d500..931ec54 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -1,4 +1,4 @@
-use crate::widget::Element;
+use crate::widget::WidgetHost;
use crate::context::UiContext;
use std::sync::RwLock;
use std::collections::HashMap;
@@ -3141,7 +3141,7 @@ impl RenderTarget for PopoverCollector {
}
-pub fn render_widget<T: Element + 'static>(pc: &mut dyn RenderTarget, w: &mut T, x: f32, y: f32, ww: f32, wh: f32, ctx: &mut UiContext) {
+pub fn render_widget<T: WidgetHost + 'static>(pc: &mut dyn RenderTarget, w: &mut T, x: f32, y: f32, ww: f32, wh: f32, ctx: &mut UiContext) {
let id = Some(w.base().id());
if let Some(w_id) = id {
ctx.register_widget(w_id, w.as_ptr_mut());
@@ -3373,7 +3373,7 @@ impl Column {
pc.text(text, x, y, font_size, color);
}
- pub fn widget<T: Element + 'static>(&mut self, pc: &mut dyn RenderTarget, w: &mut T, x_off: f32, ww: f32, mut wh: f32, ctx: &mut UiContext) {
+ pub fn widget<T: WidgetHost + 'static>(&mut self, pc: &mut dyn RenderTarget, w: &mut T, x_off: f32, ww: f32, mut wh: f32, ctx: &mut UiContext) {
if let Some(pref) = w.preferred_height() {
wh = pref;
}
@@ -3424,7 +3424,7 @@ impl<'a> Row<'a> {
self.cursor_x += width + self.spacing;
}
- pub fn widget<T: Element + 'static>(&mut self, w: &mut T, ww: f32, mut wh: f32, ctx: &mut UiContext) {
+ pub fn widget<T: WidgetHost + 'static>(&mut self, w: &mut T, ww: f32, mut wh: f32, ctx: &mut UiContext) {
if let Some(pref) = w.preferred_height() {
wh = pref;
}
@@ -3553,7 +3553,7 @@ impl Section {
pc.text(text, self.ax(x_off), self.ay() + y_off, font_size, color);
}
- pub fn widget<T: Element + 'static>(&mut self, pc: &mut dyn RenderTarget, w: &mut T, _x_off: f32, _ww: f32, mut wh: f32, ctx: &mut UiContext) {
+ pub fn widget<T: WidgetHost + 'static>(&mut self, pc: &mut dyn RenderTarget, w: &mut T, _x_off: f32, _ww: f32, mut wh: f32, ctx: &mut UiContext) {
if let Some(pref) = w.preferred_height() {
wh = pref;
}
@@ -3605,7 +3605,7 @@ impl Section {
}
}
- pub fn widget_full<T: Element + 'static>(&mut self, pc: &mut dyn RenderTarget, w: &mut T, wh: f32, ctx: &mut UiContext) {
+ pub fn widget_full<T: WidgetHost + 'static>(&mut self, pc: &mut dyn RenderTarget, w: &mut T, wh: f32, ctx: &mut UiContext) {
let x_off = 12.0;
let ww = self.cw - 2.0 * (self.padding() + x_off);
self.widget(pc, w, x_off, ww, wh, ctx);
@@ -3744,7 +3744,7 @@ pub struct SectionVStack<'a> {
}
impl<'a> SectionVStack<'a> {
- pub fn add_widget<T: Element + 'static>(&mut self, w: &mut T, ww: f32, wh: f32, ctx: &mut UiContext) {
+ pub fn add_widget<T: WidgetHost + 'static>(&mut self, w: &mut T, ww: f32, wh: f32, ctx: &mut UiContext) {
self.section.widget(self.pc, w, Section::DEFAULT_MARGIN_X, ww, wh, ctx);
self.section.spacing(self.spacing);
}
@@ -3967,8 +3967,8 @@ pub trait LayoutStrategy: std::fmt::Debug {
fn get_column_width(&self) -> Option<f32> { None }
fn get_gap(&self) -> f32 { 20.0 }
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn crate::widget::Element + 'static)], ctx: &mut crate::context::UiContext) -> f32;
- fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::Element + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size;
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], ctx: &mut crate::context::UiContext) -> f32;
+ fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size;
fn box_clone(&self) -> Box<dyn LayoutStrategy>;
}
@@ -4042,7 +4042,7 @@ impl LayoutStrategy for FlexLayout {
self.spacing
}
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn crate::widget::Element + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
let mut cur_x = x;
let mut cur_y = y;
match self.direction {
@@ -4074,7 +4074,7 @@ impl LayoutStrategy for FlexLayout {
}
}
- fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::Element + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
+ fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
match self.direction {
FlexDirection::Row => {
let mut total_w = 0.0f32;
@@ -4164,7 +4164,7 @@ impl LayoutStrategy for ColumnLayout {
self.gap
}
- fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn crate::widget::Element + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
let mut cur_y = y;
for &child_ptr in children {
unsafe {
@@ -4178,7 +4178,7 @@ impl LayoutStrategy for ColumnLayout {
(cur_y - y).max(0.0)
}
- fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::Element + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
+ fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
let mut total_h = 0.0f32;
let mut max_w = 0.0f32;
for (i, &child_ptr) in children.iter().enumerate() {
@@ -4298,7 +4298,7 @@ impl LayoutStrategy for AdaptiveGrid {
crate::layout::grid_gap()
}
- fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn crate::widget::Element + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
let usable_w = w.max(1.0);
let min_col_width = crate::layout::grid_min_col_width();
let gap = crate::layout::grid_gap();
@@ -4341,7 +4341,7 @@ impl LayoutStrategy for AdaptiveGrid {
(max_h - y).max(0.0)
}
- fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::Element + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
+ fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
let usable_w = constraints.max_width.max(1.0);
let min_col_width = crate::layout::grid_min_col_width();
let gap = crate::layout::grid_gap();
@@ -4429,7 +4429,7 @@ impl LayoutStrategy for RadialLayout {
}
}
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn crate::widget::Element + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], _ctx: &mut crate::context::UiContext) -> f32 {
let cx = x + w / 2.0;
let cy = y + h / 2.0;
let aspect = if self.aspect_ratio > 0.0 {
@@ -4452,7 +4452,7 @@ impl LayoutStrategy for RadialLayout {
h
}
- fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::Element + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
+ fn measure(&self, constraints: crate::widget::LayoutConstraints, children: &[*mut (dyn crate::widget::WidgetHost + 'static)], ctx: &crate::context::UiContext) -> crate::widget::Size {
let cx = constraints.max_width / 2.0;
let cy = constraints.max_height / 2.0;
let aspect = if self.aspect_ratio > 0.0 {
@@ -4692,7 +4692,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
}
}
- pub fn widget<T: Element + 'static>(&mut self, w: &mut T, _x_off: f32, _ww: f32, mut wh: f32, ctx: &mut UiContext) {
+ pub fn widget<T: WidgetHost + 'static>(&mut self, w: &mut T, _x_off: f32, _ww: f32, mut wh: f32, ctx: &mut UiContext) {
if let Some(pref) = w.preferred_height() {
wh = pref;
}
@@ -4753,7 +4753,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
}
}
- pub fn widget_full<T: Element + 'static>(&mut self, w: &mut T, wh: f32, ctx: &mut UiContext) {
+ pub fn widget_full<T: WidgetHost + 'static>(&mut self, w: &mut T, wh: f32, ctx: &mut UiContext) {
let x_off = 12.0;
let ww = self.cw - 2.0 * (self.padding() + x_off); // cw - 40.0
self.widget(w, x_off, ww, wh, ctx);
@@ -4928,7 +4928,7 @@ pub struct VStack<'b, 'a, P> {
}
impl<'b, 'a, P: RenderTarget> VStack<'b, 'a, P> {
- pub fn add_widget<T: Element + 'static>(&mut self, w: &mut T, _ww: f32, wh: f32, ctx: &mut UiContext) {
+ pub fn add_widget<T: WidgetHost + 'static>(&mut self, w: &mut T, _ww: f32, wh: f32, ctx: &mut UiContext) {
let pad = self.context.padding();
let margin_x = 2.0 * pad + 12.0;
let x = self.context.left + margin_x;
@@ -5103,7 +5103,7 @@ mod tests {
h: f32,
}
- impl Element for MockWidget {
+ impl WidgetHost for MockWidget {
crate::impl_widget_base!(MockWidget);
fn rect(&self) -> (f32, f32, f32, f32) {
(self.x, self.y, self.w, self.h)
@@ -5123,7 +5123,7 @@ mod tests {
base: crate::widget::Widget,
}
- impl Element for MockWidgetWithLabel {
+ impl WidgetHost for MockWidgetWithLabel {
crate::impl_widget_base!(MockWidgetWithLabel);
fn rect(&self) -> (f32, f32, f32, f32) {
let offset = crate::widget::label_offset(self);
@@ -5462,9 +5462,9 @@ mod tests {
let mut w3 = MockWidget { base: crate::widget::Widget::new(), x: 0.0, y: 0.0, w: 80.0, h: 40.0 };
let children = vec![
- &mut w1 as *mut MockWidget as *mut (dyn Element + 'static),
- &mut w2 as *mut MockWidget as *mut (dyn Element + 'static),
- &mut w3 as *mut MockWidget as *mut (dyn Element + 'static),
+ &mut w1 as *mut MockWidget as *mut (dyn WidgetHost + 'static),
+ &mut w2 as *mut MockWidget as *mut (dyn WidgetHost + 'static),
+ &mut w3 as *mut MockWidget as *mut (dyn WidgetHost + 'static),
];
let _ = layout.layout(10.0, 20.0, 250.0, 500.0, &children, &mut dummy);
@@ -5494,9 +5494,9 @@ mod tests {
let mut w3 = MockWidget { base: crate::widget::Widget::new(), x: 0.0, y: 0.0, w: 80.0, h: 40.0 };
let children = vec![
- &mut w1 as *mut MockWidget as *mut (dyn Element + 'static),
- &mut w2 as *mut MockWidget as *mut (dyn Element + 'static),
- &mut w3 as *mut MockWidget as *mut (dyn Element + 'static),
+ &mut w1 as *mut MockWidget as *mut (dyn WidgetHost + 'static),
+ &mut w2 as *mut MockWidget as *mut (dyn WidgetHost + 'static),
+ &mut w3 as *mut MockWidget as *mut (dyn WidgetHost + 'static),
];
let _ = layout.layout(10.0, 20.0, 250.0, 300.0, &children, &mut dummy);
diff --git a/src/main.rs b/src/main.rs
index 84bd5e4..b9a5691 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -26,7 +26,7 @@ use cce_ui::scene::layout::{
};
use cce_ui::scene::paint::{DisplayList, PaintCtx};
use cce_ui::widget::{
- Adapted, Button, Dropdown, Element, ElementState, Event, KeyEvent, MouseButton,
+ Adapted, Button, Dropdown, WidgetHost, ElementState, Event, KeyEvent, MouseButton,
MouseScrollDelta, Slider, TextBox, Toggle,
};
use wayland_client::QueueHandle;
@@ -64,7 +64,7 @@ struct DemoApp {
impl DemoApp {
/// The widget roots, in paint order (events route over the same list).
- fn roots(&mut self) -> [*mut (dyn Element + 'static); 5] {
+ fn roots(&mut self) -> [*mut (dyn WidgetHost + 'static); 5] {
[
self.button.as_ptr_mut(),
self.toggle.as_ptr_mut(),
diff --git a/src/scene/arena.rs b/src/scene/arena.rs
index c44fa40..76eef38 100644
--- a/src/scene/arena.rs
+++ b/src/scene/arena.rs
@@ -2,8 +2,8 @@
//!
//! This is Phase 1 of the core rebuild (see `docs/rfc-core-rebuild.md`). It replaces the old
//! model where the widget tree was smeared across three parallel stores kept in sync by hand
-//! (`Backplate.children: Vec<*mut dyn Element>`, `UiContext.layout_tree`, and
-//! `UiContext.widget_registry`) and traversed through raw `*mut dyn Element` pointers that
+//! (`Backplate.children: Vec<*mut dyn WidgetHost>`, `UiContext.layout_tree`, and
+//! `UiContext.widget_registry`) and traversed through raw `*mut dyn WidgetHost` pointers that
//! `Drop` did not fully clear.
//!
//! Here there is exactly **one** store. Every node lives in the [`Arena`], addressed by a
@@ -562,12 +562,12 @@ mod tests {
}
// Validation against a real trait object: the arena must be able to *own* and tree actual
- // `dyn Element` widgets (the payload type Phase 3 will use), not just Copy scalars.
+ // `dyn WidgetHost` widgets (the payload type Phase 3 will use), not just Copy scalars.
#[test]
fn holds_and_trees_real_dyn_element_payloads() {
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
- // A minimal real `Element` — `color` is the trait's only required method, everything
+ // A minimal real `WidgetHost` — `color` is the trait's only required method, everything
// else is defaulted, so this exercises the actual trait object without dragging in a
// heavyweight widget constructor.
struct Marker {
@@ -575,7 +575,7 @@ mod tests {
tint: [f32; 4],
painted: std::cell::Cell<bool>,
}
- impl Element for Marker {
+ impl WidgetHost for Marker {
crate::impl_widget_base!(Marker);
fn color(&self) -> [f32; 4] {
self.painted.set(true);
@@ -583,7 +583,7 @@ mod tests {
}
}
- let mut arena: Arena<Box<dyn Element>> = Arena::new();
+ let mut arena: Arena<Box<dyn WidgetHost>> = Arena::new();
let root = arena.insert(Box::new(Marker { base: crate::widget::Widget::new(), tint: [1.0, 0.0, 0.0, 1.0], painted: false.into() }));
let child = arena.insert(Box::new(Marker { base: crate::widget::Widget::new(), tint: [0.0, 1.0, 0.0, 1.0], painted: false.into() }));
arena.append_child(root, child);
diff --git a/src/scene/painter.rs b/src/scene/painter.rs
index 34f3415..d399954 100644
--- a/src/scene/painter.rs
+++ b/src/scene/painter.rs
@@ -3,8 +3,8 @@
//! One traversal of the widget tree that emits every widget's own primitives into a single
//! [`DisplayList`], in draw order, through a [`PaintCtx`]. Recursion and clipping live *here*
//! (not smeared across each container's `all_*` methods): a widget contributes its own geometry
-//! via [`Element::paint_self`], then the walk descends into its children — pushing the widget's
-//! rect as a clip first when [`Element::clips_children`] is set, so the clip stack composes
+//! via [`WidgetHost::paint_self`], then the walk descends into its children — pushing the widget's
+//! rect as a clip first when [`WidgetHost::clips_children`] is set, so the clip stack composes
//! automatically instead of every container re-deriving intersections by hand.
//!
//! This replaces, once wired into the backend, the three uncoordinated render paths (top-level
@@ -14,15 +14,15 @@
use crate::scene::layout::Rect;
use crate::scene::paint::{DisplayList, PaintCtx, Prim};
-use crate::widget::{Element, TextLabel, UiContext};
+use crate::widget::{WidgetHost, TextLabel, UiContext};
-type ElemPtr = *mut (dyn Element + 'static);
+type ElemPtr = *mut (dyn WidgetHost + 'static);
/// Walk the widget subtree rooted at `root` and produce its ordered, clipped [`DisplayList`].
///
/// # Safety
-/// `root` and every widget reachable through `Element::children` must be live — the same
-/// invariant the rest of the toolkit relies on for its `*mut dyn Element` tree.
+/// `root` and every widget reachable through `WidgetHost::children` must be live — the same
+/// invariant the rest of the toolkit relies on for its `*mut dyn WidgetHost` tree.
pub fn paint_tree(ui: &UiContext, root: ElemPtr) -> DisplayList {
let mut pc = PaintCtx::new();
paint_root_into(ui, root, &mut pc);
@@ -43,13 +43,13 @@ pub fn paint_root_into(ui: &UiContext, root: ElemPtr, pc: &mut PaintCtx) {
/// bounds). For hosts that build their frame as a [`PaintCtx`] and already emit a widget's
/// geometry another way, but want its text without re-deriving it through the legacy
/// `text_labels*` getters (the four hand-aggregate clients). The walk only reads through the
-/// widget, so a shared `&dyn Element` is enough.
-pub fn append_widget_text(ui: &UiContext, root: &dyn Element, pc: &mut PaintCtx) {
+/// widget, so a shared `&dyn WidgetHost` is enough.
+pub fn append_widget_text(ui: &UiContext, root: &dyn WidgetHost, pc: &mut PaintCtx) {
// SAFETY: the walk only reads through `root` (paint_self/children/visible are all `&self`),
// and widgets are concrete `'static` types — the invariant the toolkit's whole
- // `*mut dyn Element` tree already relies on. Erase the borrowed trait-object lifetime bound
+ // `*mut dyn WidgetHost` tree already relies on. Erase the borrowed trait-object lifetime bound
// to the `'static` `ElemPtr` the walk takes.
- let ptr: ElemPtr = unsafe { std::mem::transmute::<*const dyn Element, ElemPtr>(root as *const dyn Element) };
+ let ptr: ElemPtr = unsafe { std::mem::transmute::<*const dyn WidgetHost, ElemPtr>(root as *const dyn WidgetHost) };
let mut scratch = PaintCtx::new();
paint_node(ui, ptr, &mut scratch);
for item in scratch.finish().items {
@@ -65,7 +65,7 @@ pub fn append_widget_text(ui: &UiContext, root: &dyn Element, pc: &mut PaintCtx)
}
}
-/// The `Element` default `paint_self`'s LEAF branch as a reusable body: leaf geometry
+/// The `WidgetHost` default `paint_self`'s LEAF branch as a reusable body: leaf geometry
/// (rounded quads, plain quads, arcs, circles) followed by the widget's fonted labels.
/// Legacy leaf widgets' `paint_self` overrides call this with their own labels — the
/// labels are PASSED IN rather than fetched through the per-widget text getters, so this
@@ -73,7 +73,7 @@ pub fn append_widget_text(ui: &UiContext, root: &dyn Element, pc: &mut PaintCtx)
/// app-local legacy widgets (display-manager's status/session widgets, cloud's fuzzel)
/// can use it too.
pub fn paint_legacy_leaf(
- w: &dyn Element,
+ w: &dyn WidgetHost,
ui: &UiContext,
pc: &mut PaintCtx,
labels: Vec<(TextLabel, Option<String>, Option<[f32; 4]>)>,
@@ -98,14 +98,14 @@ pub fn paint_legacy_leaf(
/// The scroll-ancestor text clamp the deleted default fonted getter applied. Always `None`
/// since Phase 6av: ScrollBox (the last scroll ancestor type) was demoted to a plain
/// embedded struct — it never appeared as a tree parent, so the walk never matched.
-pub fn scroll_ancestor_text_bounds(_w: &dyn Element, _ui: &UiContext) -> Option<[f32; 4]> {
+pub fn scroll_ancestor_text_bounds(_w: &dyn WidgetHost, _ui: &UiContext) -> Option<[f32; 4]> {
None
}
-/// The deleted `Element::text_labels` default's base-label synthesis: the control label
+/// The deleted `WidgetHost::text_labels` default's base-label synthesis: the control label
/// stored on the widget base, positioned by the configured control-label layout. For
/// legacy widgets whose only text was that label (List's columns=None frame).
-pub fn base_control_label(w: &dyn Element) -> Vec<TextLabel> {
+pub fn base_control_label(w: &dyn WidgetHost) -> Vec<TextLabel> {
{
let b = w.base();
if let Some(ref label) = b.label {
@@ -128,7 +128,7 @@ pub fn base_control_label(w: &dyn Element) -> Vec<TextLabel> {
/// default fonted getter produced: the widget's control font on every label plus the
/// scroll-ancestor clamp.
pub fn fonted_leaf_labels(
- w: &dyn Element,
+ w: &dyn WidgetHost,
ui: &UiContext,
labels: Vec<TextLabel>,
) -> Vec<(TextLabel, Option<String>, Option<[f32; 4]>)> {
@@ -191,7 +191,7 @@ mod tests {
Box::new(P { base: Widget::new(), tag, clips: false, vis: true })
}
}
- impl Element for P {
+ impl WidgetHost for P {
crate::impl_widget_base!(P);
fn color(&self) -> [f32; 4] {
[self.tag, 0.0, 0.0, 1.0]
@@ -333,7 +333,7 @@ mod tests {
struct Rounded {
base: Widget,
}
- impl Element for Rounded {
+ impl WidgetHost for Rounded {
crate::impl_widget_base!(Rounded);
fn color(&self) -> [f32; 4] {
[0.2, 0.4, 0.6, 1.0]
diff --git a/src/scene/tree.rs b/src/scene/tree.rs
index 070b142..ae1d538 100644
--- a/src/scene/tree.rs
+++ b/src/scene/tree.rs
@@ -2,7 +2,7 @@
//!
//! Today `UiContext` keeps the widget tree in two parallel `HashMap`s that must be maintained in
//! lockstep by hand:
-//! * `widget_registry: HashMap<WidgetId, *mut dyn Element>` — id → live pointer, and
+//! * `widget_registry: HashMap<WidgetId, *mut dyn WidgetHost>` — id → live pointer, and
//! * `layout_tree: { parents: HashMap<WidgetId, WidgetId>, children: HashMap<WidgetId, Vec<WidgetId>> }`.
//!
//! This type folds both into a single generational [`Arena`], keyed through a `WidgetId → NodeId`
@@ -13,7 +13,7 @@
//!
//! ## One deliberate semantic change vs. the legacy maps
//!
-//! The legacy maps are sometimes left **asymmetric**: `Element::set_parent(Some(p))` writes
+//! The legacy maps are sometimes left **asymmetric**: `WidgetHost::set_parent(Some(p))` writes
//! `parents[child] = p` but does *not* add `child` to `children[p]`; `plate`/`parameters_bg`
//! detach by doing `parents.remove(child)` while leaving `child` in `children[p]`. The arena keeps
//! parent and child links **symmetric** by construction, so here `set_parent`/`detach` update both
@@ -27,23 +27,23 @@
use std::collections::HashMap;
use crate::scene::arena::{Arena, NodeId};
-use crate::widget::{Element, WidgetId};
+use crate::widget::{WidgetHost, WidgetId};
/// One arena node's payload: the widget's stable id plus its live pointer. The pointer is `None`
/// for a node that has been *linked* into the tree (as a parent/child) but not yet *registered*
/// with a real widget — mirroring the legacy maps, where a `layout_tree` link can precede the
-/// `widget_registry` entry. (`*mut dyn Element` is a fat pointer, so `Option` is the natural
+/// `widget_registry` entry. (`*mut dyn WidgetHost` is a fat pointer, so `Option` is the natural
/// "absent" representation — there is no thin null to use as a sentinel.)
#[derive(Clone, Copy)]
struct Entry {
id: WidgetId,
- ptr: Option<*mut (dyn Element + 'static)>,
+ ptr: Option<*mut (dyn WidgetHost + 'static)>,
}
/// Resolve an entry's pointer to a usable, non-null pointer (skipping link-only and null-data
/// pointers exactly as the legacy `filter_map` over the registry did).
#[inline]
-fn live_ptr(entry: &Entry) -> Option<*mut (dyn Element + 'static)> {
+fn live_ptr(entry: &Entry) -> Option<*mut (dyn WidgetHost + 'static)> {
match entry.ptr {
Some(p) if !p.is_null() => Some(p),
_ => None,
@@ -93,7 +93,7 @@ impl WidgetTree {
/// Register (or overwrite) the live pointer for `id`. Mirrors `register_widget`'s
/// insert-overwrite semantics. Registering a `null` pointer is allowed (the node exists but
/// resolves to `None`), matching the legacy behavior where a link can precede registration.
- pub fn register(&mut self, id: WidgetId, ptr: *mut (dyn Element + 'static)) {
+ pub fn register(&mut self, id: WidgetId, ptr: *mut (dyn WidgetHost + 'static)) {
let node = self.ensure_node(id);
// `ensure_node` guarantees the node exists.
self.arena.value_mut(node).unwrap().ptr = Some(ptr);
@@ -113,7 +113,7 @@ impl WidgetTree {
/// Set or clear `child`'s parent. `Some(p)` links symmetrically (as [`link`](WidgetTree::link));
/// `None` detaches `child` from its current parent. Replaces the legacy asymmetric
- /// `Element::set_parent`.
+ /// `WidgetHost::set_parent`.
pub fn set_parent(&mut self, child: WidgetId, parent: Option<WidgetId>) {
match parent {
Some(p) => self.link(p, child),
@@ -172,7 +172,7 @@ impl WidgetTree {
}
/// The live pointer for `id`, or `None` if unknown, link-only (null), or stale.
- pub fn get_ptr(&self, id: WidgetId) -> Option<*mut (dyn Element + 'static)> {
+ pub fn get_ptr(&self, id: WidgetId) -> Option<*mut (dyn WidgetHost + 'static)> {
let node = *self.by_id.get(&id)?;
live_ptr(self.arena.value(node)?)
}
@@ -185,7 +185,7 @@ impl WidgetTree {
}
/// `id`'s parent pointer, if the parent is registered (non-null).
- pub fn parent_ptr(&self, id: WidgetId) -> Option<*mut (dyn Element + 'static)> {
+ pub fn parent_ptr(&self, id: WidgetId) -> Option<*mut (dyn WidgetHost + 'static)> {
self.parent_id(id).and_then(|p| self.get_ptr(p))
}
@@ -196,8 +196,8 @@ impl WidgetTree {
}
/// `id`'s child pointers in order, skipping any child that is link-only (null pointer) —
- /// exactly matching the legacy `Element::children` `filter_map` over the registry.
- pub fn children_ptrs(&self, id: WidgetId) -> Vec<*mut (dyn Element + 'static)> {
+ /// exactly matching the legacy `WidgetHost::children` `filter_map` over the registry.
+ pub fn children_ptrs(&self, id: WidgetId) -> Vec<*mut (dyn WidgetHost + 'static)> {
let Some(&node) = self.by_id.get(&id) else { return Vec::new() };
self.arena
.children(node)
@@ -208,7 +208,7 @@ impl WidgetTree {
/// Iterate every registered `(id, ptr)` with a non-null pointer, for the passes that sweep the
/// whole registry (`clear_dirty`, `rebuild_spatial_grid`, coverage tests).
- pub fn iter_registered(&self) -> impl Iterator<Item = (WidgetId, *mut (dyn Element + 'static))> + '_ {
+ pub fn iter_registered(&self) -> impl Iterator<Item = (WidgetId, *mut (dyn WidgetHost + 'static))> + '_ {
self.by_id.values().filter_map(move |&node| {
let entry = self.arena.value(node)?;
live_ptr(entry).map(|p| (entry.id, p))
@@ -220,7 +220,7 @@ impl WidgetTree {
mod tests {
use super::*;
- // A minimal real `Element` so tests exercise genuine `*mut dyn Element` payloads. The boxes
+ // A minimal real `WidgetHost` so tests exercise genuine `*mut dyn WidgetHost` payloads. The boxes
// are kept alive in a local `Vec` for the duration of each test; we hand the tree raw
// pointers into them, mirroring how widgets (owned by the app) are referenced by the tree.
struct Marker {
@@ -228,7 +228,7 @@ mod tests {
#[allow(dead_code)]
tag: u32,
}
- impl Element for Marker {
+ impl WidgetHost for Marker {
crate::impl_widget_base!(Marker);
fn color(&self) -> [f32; 4] {
[0.0, 0.0, 0.0, 0.0]
@@ -243,10 +243,10 @@ mod tests {
fn new() -> Self {
Widgets { boxes: Vec::new() }
}
- /// Create a widget, returning `(WidgetId, *mut dyn Element)`.
- fn make(&mut self, tag: u32) -> (WidgetId, *mut (dyn Element + 'static)) {
+ /// Create a widget, returning `(WidgetId, *mut dyn WidgetHost)`.
+ fn make(&mut self, tag: u32) -> (WidgetId, *mut (dyn WidgetHost + 'static)) {
let mut b = Box::new(Marker { base: crate::widget::Widget::new(), tag: tag });
- let ptr: *mut (dyn Element + 'static) = &mut *b;
+ let ptr: *mut (dyn WidgetHost + 'static) = &mut *b;
self.boxes.push(b);
(WidgetId(tag as usize), ptr)
}
diff --git a/src/widget/container/breadcrumb.rs b/src/widget/container/breadcrumb.rs
index 9c293e4..3f1318a 100644
--- a/src/widget/container/breadcrumb.rs
+++ b/src/widget/container/breadcrumb.rs
@@ -209,7 +209,7 @@ impl PathController for Breadcrumb {
mod tests {
use super::*;
use crate::context::UiContext;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
#[test]
fn test_breadcrumb_clicks() {
diff --git a/src/widget/container/container_layout.rs b/src/widget/container/container_layout.rs
index 83fbb33..aec6729 100644
--- a/src/widget/container/container_layout.rs
+++ b/src/widget/container/container_layout.rs
@@ -31,7 +31,7 @@ impl crate::layout::LayoutStrategy for OverlayLayout {
(self.left, self.top, self.width, self.height)
}
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn Element + 'static)], _ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn WidgetHost + 'static)], _ctx: &mut UiContext) -> f32 {
for &child_ptr in children {
unsafe {
(*child_ptr).set_rect(x, y, w, h);
@@ -40,7 +40,7 @@ impl crate::layout::LayoutStrategy for OverlayLayout {
h
}
- fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn Element + 'static)], ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn WidgetHost + 'static)], ctx: &UiContext) -> Size {
let mut max_w = 0.0f32;
let mut max_h = 0.0f32;
for &child_ptr in children {
@@ -87,11 +87,11 @@ impl crate::layout::LayoutStrategy for ManualLayout {
(self.left, self.top, self.width, self.height)
}
- fn layout(&self, _x: f32, _y: f32, _w: f32, _h: f32, _children: &[*mut (dyn Element + 'static)], _ctx: &mut UiContext) -> f32 {
+ fn layout(&self, _x: f32, _y: f32, _w: f32, _h: f32, _children: &[*mut (dyn WidgetHost + 'static)], _ctx: &mut UiContext) -> f32 {
self.height
}
- fn measure(&self, constraints: LayoutConstraints, _children: &[*mut (dyn Element + 'static)], _ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, _children: &[*mut (dyn WidgetHost + 'static)], _ctx: &UiContext) -> Size {
Size {
width: self.width.clamp(constraints.min_width, constraints.max_width),
height: self.height.clamp(constraints.min_height, constraints.max_height),
@@ -148,7 +148,7 @@ impl crate::layout::LayoutStrategy for VerticalLayout {
self.spacing
}
- fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn Element + 'static)], ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn WidgetHost + 'static)], ctx: &mut UiContext) -> f32 {
let left_x = x + self.padding_x;
let available_w = (w - 2.0 * self.padding_x).max(1.0);
let mut current_y = y + self.padding_y;
@@ -169,7 +169,7 @@ impl crate::layout::LayoutStrategy for VerticalLayout {
(current_y - y).max(0.0)
}
- fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn Element + 'static)], ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn WidgetHost + 'static)], ctx: &UiContext) -> Size {
let mut total_h = self.padding_y * 2.0;
let mut max_w = 0.0f32;
let spacing = self.spacing;
@@ -246,7 +246,7 @@ impl crate::layout::LayoutStrategy for GridLayout {
self.gap
}
- fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn Element + 'static)], ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn WidgetHost + 'static)], ctx: &mut UiContext) -> f32 {
let count = children.len();
if count == 0 {
return 0.0;
@@ -288,7 +288,7 @@ impl crate::layout::LayoutStrategy for GridLayout {
(max_h - y).max(0.0)
}
- fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn Element + 'static)], ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn WidgetHost + 'static)], ctx: &UiContext) -> Size {
let cols = self.columns.max(1);
let mut col_heights = vec![self.padding_y; cols];
let total_gap = self.gap * (cols - 1) as f32;
@@ -374,7 +374,7 @@ impl crate::layout::LayoutStrategy for AdaptiveGridLayout {
self.gap
}
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn Element + 'static)], ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn WidgetHost + 'static)], ctx: &mut UiContext) -> f32 {
let usable_w = (w - 2.0 * self.padding_x).max(1.0);
let cols = (((usable_w + self.gap) / (self.min_col_width + self.gap)).floor().max(1.0)) as usize;
let grid = GridLayout {
@@ -387,7 +387,7 @@ impl crate::layout::LayoutStrategy for AdaptiveGridLayout {
grid.layout(x, y, w, h, children, ctx)
}
- fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn Element + 'static)], ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn WidgetHost + 'static)], ctx: &UiContext) -> Size {
let usable_w = (constraints.max_width - 2.0 * self.padding_x).max(1.0);
let cols = (((usable_w + self.gap) / (self.min_col_width + self.gap)).floor().max(1.0)) as usize;
let grid = GridLayout {
@@ -433,7 +433,7 @@ impl crate::layout::LayoutStrategy for ColumnsLayout {
fn allocate(&mut self, ww: f32, wh: f32) -> (f32, f32, f32, f32) { (0.0, 0.0, ww, wh) }
fn get_gap(&self) -> f32 { self.spacing }
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn Element + 'static)], ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn WidgetHost + 'static)], ctx: &mut UiContext) -> f32 {
let count = children.len();
if count == 0 {
return 0.0;
@@ -460,7 +460,7 @@ impl crate::layout::LayoutStrategy for ColumnsLayout {
use_h + 2.0 * self.padding_y
}
- fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn Element + 'static)], ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn WidgetHost + 'static)], ctx: &UiContext) -> Size {
let count = children.len();
if count == 0 {
return Size { width: constraints.min_width, height: constraints.min_height };
@@ -577,7 +577,7 @@ impl crate::layout::LayoutStrategy for MosaicLayout {
fn allocate(&mut self, ww: f32, wh: f32) -> (f32, f32, f32, f32) { (0.0, 0.0, ww, wh) }
fn get_gap(&self) -> f32 { self.gap }
- fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn Element + 'static)], ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, _h: f32, children: &[*mut (dyn WidgetHost + 'static)], ctx: &mut UiContext) -> f32 {
let count = children.len();
if count == 0 {
return 0.0;
@@ -607,7 +607,7 @@ impl crate::layout::LayoutStrategy for MosaicLayout {
(packer.max_h - y).max(0.0)
}
- fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn Element + 'static)], ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, children: &[*mut (dyn WidgetHost + 'static)], ctx: &UiContext) -> Size {
let count = children.len();
if count == 0 {
return Size { width: constraints.min_width, height: constraints.min_height };
@@ -663,7 +663,7 @@ impl crate::layout::LayoutStrategy for ReverseMosaicLayout {
fn allocate(&mut self, ww: f32, wh: f32) -> (f32, f32, f32, f32) { (0.0, 0.0, ww, wh) }
fn get_gap(&self) -> f32 { self.gap }
- fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn Element + 'static)], ctx: &mut UiContext) -> f32 {
+ fn layout(&self, x: f32, y: f32, w: f32, h: f32, children: &[*mut (dyn WidgetHost + 'static)], ctx: &mut UiContext) -> f32 {
let count = children.len();
if count == 0 {
return 0.0;
@@ -729,7 +729,7 @@ impl crate::layout::LayoutStrategy for ReverseMosaicLayout {
h
}
- fn measure(&self, constraints: LayoutConstraints, _children: &[*mut (dyn Element + 'static)], _ctx: &UiContext) -> Size {
+ fn measure(&self, constraints: LayoutConstraints, _children: &[*mut (dyn WidgetHost + 'static)], _ctx: &UiContext) -> Size {
Size {
width: constraints.max_width,
height: constraints.max_height,
diff --git a/src/widget/container/menu.rs b/src/widget/container/menu.rs
index b00ff09..77412d0 100644
--- a/src/widget/container/menu.rs
+++ b/src/widget/container/menu.rs
@@ -1,6 +1,6 @@
//! Narrow-trait `MenuBar` (Phase 5o) — a titled bar of dropdown menus with an optional
//! context selector on the title. The menu buttons live in an EMBEDDED legacy [`ButtonStrip`]
-//! (owned by value in the model, driven through `Element` calls — events reach it via
+//! (owned by value in the model, driven through `WidgetHost` calls — events reach it via
//! `EventCtx::ui`, and [`Layout::arrange_children`] parents it back to the adapter so its
//! parent-chain styling walks keep working). Dropdowns are painted through the popover hooks
//! ([`Paint::popover`] / [`Paint::draw_popover`]) and layered by [`Layout::z_order`]. The
@@ -23,7 +23,7 @@ use crate::scene::layout::Rect;
use crate::scene::paint::PaintCtx;
use crate::widget::display::TextLabel;
use crate::widget::{
- Adapted, ButtonStrip, Element, ElementState, Event, EventCtx, Input, Key, Layout,
+ Adapted, ButtonStrip, WidgetHost, ElementState, Event, EventCtx, Input, Key, Layout,
MenuController, MouseButton, NamedKey, PageSelector, Paint, DROPDOWN_ITEM_H,
};
@@ -94,7 +94,7 @@ impl MenuBar {
clicked_dropdown_item: None,
last_arranged: None,
});
- Element::set_rect(&mut bar, x, y, w, h);
+ WidgetHost::set_rect(&mut bar, x, y, w, h);
bar
}
@@ -423,7 +423,7 @@ impl Layout for MenuBar {
self.z_level
}
- fn arrange_children(&mut self, rect: Rect, _host: *mut (dyn Element + 'static)) {
+ fn arrange_children(&mut self, rect: Rect, _host: *mut (dyn WidgetHost + 'static)) {
self.layout_strip(rect);
}
}
@@ -1068,7 +1068,7 @@ mod tests {
let mut mb = bar();
let (id, ptr) = (mb.id(), mb.as_ptr_mut());
ctx.register_widget(id, ptr);
- Element::set_rect(&mut mb, 0.0, 0.0, 400.0, 24.0);
+ WidgetHost::set_rect(&mut mb, 0.0, 0.0, 400.0, 24.0);
// Click the "File" strip button (the strip commits selection on release): the dropdown
// opens, the bar reports focused (conditional focus), and a popover rect exists.
@@ -1077,14 +1077,14 @@ mod tests {
assert!(mb.mouse_input(MouseButton::Left, ElementState::Pressed, bx + bw / 2.0, by + bh / 2.0, &mut ctx));
assert!(mb.mouse_input(MouseButton::Left, ElementState::Released, bx + bw / 2.0, by + bh / 2.0, &mut ctx));
assert!(MenuController::is_menu_open(&*mb), "dropdown open");
- assert!(Element::focused(&mb, &ctx), "bar holds focus while open");
- let (dx, dy, _, _) = Element::popover_rect(&mb).expect("dropdown popover");
+ assert!(WidgetHost::focused(&mb, &ctx), "bar holds focus while open");
+ let (dx, dy, _, _) = WidgetHost::popover_rect(&mb).expect("dropdown popover");
// Click the second item ("Save"): menu_click reports (0, 1) and everything closes.
assert!(mb.mouse_input(MouseButton::Left, ElementState::Pressed, dx + 10.0, dy + DROPDOWN_ITEM_H * 1.5, &mut ctx));
assert_eq!(MenuController::menu_click(&mut *mb), Some((0, 1)));
assert!(!MenuController::is_menu_open(&*mb));
- assert!(!Element::focused(&mb, &ctx), "focus released after the click");
+ assert!(!WidgetHost::focused(&mb, &ctx), "focus released after the click");
// The PageSelector capability is reached through the concrete adapter too.
assert!(PageSelector::sidebar_w(&*mb) > 0.0);
@@ -1096,11 +1096,11 @@ mod tests {
let mut mb = bar();
let (id, ptr) = (mb.id(), mb.as_ptr_mut());
ctx.register_widget(id, ptr);
- Element::set_rect(&mut mb, 0.0, 0.0, 400.0, 24.0);
+ WidgetHost::set_rect(&mut mb, 0.0, 0.0, 400.0, 24.0);
- Element::set_visible(&mut mb, false);
+ WidgetHost::set_visible(&mut mb, false);
assert!(!MenuController::is_menu_bar(&*mb), "hidden bar is not a menu bar");
- assert!(!Element::hit_test(&mb, 10.0, 10.0, &ctx));
+ assert!(!WidgetHost::hit_test(&mb, 10.0, 10.0, &ctx));
assert!(MenuController::get_menu_items_at(&*mb, 10.0, 10.0).is_none());
}
}
diff --git a/src/widget/container/paginator.rs b/src/widget/container/paginator.rs
index d578c36..2993902 100644
--- a/src/widget/container/paginator.rs
+++ b/src/widget/container/paginator.rs
@@ -19,7 +19,7 @@ use crate::scene::layout::Rect;
use crate::scene::paint::PaintCtx;
use crate::widget::input::ButtonStrip;
use crate::widget::{
- Adapted, Element, Event, EventCtx, Input, Layout, MenuController, PageSelector, Paint,
+ Adapted, WidgetHost, Event, EventCtx, Input, Layout, MenuController, PageSelector, Paint,
UiContext, WidgetId,
};
@@ -150,12 +150,12 @@ impl Layout for Paginator {
true
}
- fn container_children(&self) -> Vec<*mut (dyn Element + 'static)> {
- vec![&self.sidebar_menu as &dyn Element as *const (dyn Element + 'static) as *mut (dyn Element + 'static)]
+ fn container_children(&self) -> Vec<*mut (dyn WidgetHost + 'static)> {
+ vec![&self.sidebar_menu as &dyn WidgetHost as *const (dyn WidgetHost + 'static) as *mut (dyn WidgetHost + 'static)]
}
/// The legacy `set_rect` body: strip on the left at its measured width.
- fn arrange_children(&mut self, rect: Rect, _host: *mut (dyn Element + 'static)) {
+ fn arrange_children(&mut self, rect: Rect, _host: *mut (dyn WidgetHost + 'static)) {
let (x, y, h) = (rect.x, rect.y, rect.height);
let sidebar_w = self.sidebar_w();
self.sidebar_menu.set_rect(x, y, sidebar_w, h);
@@ -282,7 +282,7 @@ mod tests {
fn paginator() -> Adapted<Paginator> {
let mut p = Paginator::new(vec!["One".to_string(), "Two".to_string()]);
- Element::set_rect(&mut p, 0.0, 0.0, 400.0, 300.0);
+ WidgetHost::set_rect(&mut p, 0.0, 0.0, 400.0, 300.0);
p
}
@@ -319,19 +319,19 @@ mod tests {
// Legacy split: `extra_quads` is the children's chrome only; the sidebar background
// quad lives in `all_quads` alone (email/layout-interface draw their own backgrounds
// under `extra_quads`).
- let extra = Element::extra_quads(&p);
+ let extra = WidgetHost::extra_quads(&p);
let strip_extra = p.sidebar_menu.extra_quads();
assert_eq!(extra.len(), strip_extra.len(), "children-only plain view (pages emit none)");
let bg = colors::sidebar_bg_color();
if bg[3] > 0.0 {
let bg_quad = (0.0, 0.0, 400.0, 300.0, bg);
assert!(!extra.contains(&bg_quad), "no own bg in extra_quads");
- assert!(Element::all_quads(&p, &ctx).contains(&bg_quad), "own bg in all_quads");
+ assert!(WidgetHost::all_quads(&p, &ctx).contains(&bg_quad), "own bg in all_quads");
}
// The embedded strip + pages land in the registry on tick (the spatial grid feeds off
// it — the registered strip is what blocks backplate drags over the sidebar).
- Element::tick(&mut p, 0.016, &mut ctx);
+ WidgetHost::tick(&mut p, 0.016, &mut ctx);
let strip_id = p.sidebar_menu.id();
assert!(
ctx.tree.iter_registered().any(|(w_id, _)| w_id == strip_id),
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index 9e44da9..3cd8ece 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -3,7 +3,7 @@
//! buttons, section borders, and an inline emacs-flavored code editor), each row's widget owned
//! by value in parallel `Vec<Option<..>>` fields (most already `Adapted<W>` from earlier
//! phases), plus a raw-pointer `children` container list. The designer stores it as
-//! `Box<dyn Element>` and drives it through direct `dyn Element` calls; `window_runner`'s
+//! `Box<dyn WidgetHost>` and drives it through direct `dyn WidgetHost` calls; `window_runner`'s
//! `get_child_widget_for_quad` downcasts to the concrete type through `as_any` (which the
//! adapter forwards to the inner widget) and reads the pub sub-widget fields — both keep
//! working unchanged.
@@ -27,7 +27,7 @@ use crate::scene::paint::PaintCtx;
use crate::widget::display::{Float3, TextLabel};
use crate::widget::input::{Button, Checkbox, ColorSelector, Dropdown, Slider, Spinbox, TextBox};
use crate::widget::{
- Adapted, Element, ElementState, Event, EventCtx, Input, Key, Layout, MouseButton,
+ Adapted, WidgetHost, ElementState, Event, EventCtx, Input, Key, Layout, MouseButton,
MouseScrollDelta, NamedKey, Paint, ParamController, TextEditorState, UiContext,
};
@@ -1747,7 +1747,7 @@ mod tests {
.map(|(a, b, c)| (a.to_string(), b.to_string(), c.to_string()))
.collect();
ParamController::set_display_params(&mut *p, ¶ms);
- Element::set_rect(&mut p, 0.0, 0.0, 300.0, 400.0);
+ WidgetHost::set_rect(&mut p, 0.0, 0.0, 300.0, 400.0);
p
}
@@ -1784,7 +1784,7 @@ mod tests {
assert_eq!(p.focused_param, Some(0), "code row focused");
assert!(p.code_editor.is_some());
p.code_editor.as_mut().unwrap().insert_text("y");
- Element::unfocus(&mut p);
+ WidgetHost::unfocus(&mut p);
assert_eq!(p.focused_param, None);
assert!(p.code_editor.is_none());
assert!(ParamController::node_params(&*p)[0].1.contains('y'), "editor buffer committed on unfocus");
@@ -1796,16 +1796,16 @@ mod tests {
let p = panel_with(&[("Size", "1.00", "slider:0:2")]);
// The designer's plain path: extra_quads carries the row chrome (clipped), including
// the slider background it reads via rect()+color()...
- let extra = Element::extra_quads(&p);
+ let extra = WidgetHost::extra_quads(&p);
assert!(!extra.is_empty(), "row chrome served through extra_quads");
// ...but NOT the panel's own PARAM_BG plate (the host draws that from color()).
- let (x, y, w, h) = Element::rect(&p);
+ let (x, y, w, h) = WidgetHost::rect(&p);
assert!(
!extra.iter().any(|q| (q.0, q.1, q.2, q.3) == (x, y, w, h)),
"panel bg plate is the host's, not extra_quads'"
);
// The no-double-draw contract of the plain-quad hatch.
- assert!(Element::all_quads(&p, &ctx).is_empty());
+ assert!(WidgetHost::all_quads(&p, &ctx).is_empty());
// Per-label hatch: the walk's text prims carry the widget font and viewport bounds.
let mut scratch = crate::scene::paint::PaintCtx::new();
crate::scene::painter::append_widget_text(&ctx, &p, &mut scratch);
@@ -1830,9 +1830,9 @@ mod tests {
.collect();
let mut p = ParametersBg::new();
ParamController::set_display_params(&mut *p, &rows);
- Element::set_rect(&mut p, 0.0, 0.0, 300.0, 200.0);
+ WidgetHost::set_rect(&mut p, 0.0, 0.0, 300.0, 200.0);
assert!(p.content_h > 200.0);
- assert!(Element::is_scrollable(&p));
+ assert!(WidgetHost::is_scrollable(&p));
// Wheel over the panel body but off every slider row's x-span is impossible (rows are
// full-width), so scroll via the region below the last visible row: use a y between
// rows (the 2px slack above a row) — simplest is the bottom padding strip.
diff --git a/src/widget/container/scroll_box.rs b/src/widget/container/scroll_box.rs
index f509ddc..410b0f9 100644
--- a/src/widget/container/scroll_box.rs
+++ b/src/widget/container/scroll_box.rs
@@ -1,7 +1,7 @@
-//! Embedded scroll-math + scrollbar-chrome helper (Phase 6av: DEMOTED from `Element` to a
+//! Embedded scroll-math + scrollbar-chrome helper (Phase 6av: DEMOTED from `WidgetHost` to a
//! plain struct). Never registered into the ctx tree by either consumer — TreeList and
//! cce-test-interface's panel copy drive it entirely through concrete calls — so the
-//! `Element` impl was pure dyn-dispatch ballast. The former Element-default entry points the
+//! `WidgetHost` impl was pure dyn-dispatch ballast. The former WidgetHost-default entry points the
//! consumers forward (`cursor_moved`, `tick`, drag hooks, `is_dragging`) are kept as
//! inherent methods with the exact default-derived behavior.
@@ -82,7 +82,7 @@ impl ScrollBox {
self.viewport_h = h + self.viewport_offset_h;
}
- /// The legacy `Element` default hit test over the base rect (ScrollBox never carried a
+ /// The legacy `WidgetHost` default hit test over the base rect (ScrollBox never carried a
/// label or row expansion, so those branches are folded away).
fn hit_test(&self, px: f32, py: f32, ctx: &UiContext) -> bool {
if ctx.is_coordinate_covered(self.base.id(), px, py) {
@@ -98,7 +98,7 @@ impl ScrollBox {
/// The legacy focus claim on scrollbar/list clicks: its only observable effect was
/// unfocusing the previously focused widget (nothing ever queried focus ON the scroll
/// box through the thread-local, and its own `unfocus` was a no-op) — so just release
- /// the current holder instead of storing a pointer to a non-Element.
+ /// the current holder instead of storing a pointer to a non-WidgetHost.
fn claim_focus(&self, ctx: &mut UiContext) {
focus::clear_focus(Some(ctx));
}
@@ -154,7 +154,7 @@ impl ScrollBox {
self.scrollbar_dragging
}
- /// Legacy `Element` default parity: ScrollBox never overrode `is_dragging` — TreeList
+ /// Legacy `WidgetHost` default parity: ScrollBox never overrode `is_dragging` — TreeList
/// forwards it and always got `false`.
pub fn is_dragging(&self) -> bool {
false
@@ -192,7 +192,7 @@ impl ScrollBox {
self.scrollbar_dragging = false;
}
- /// The legacy `Element` default `cursor_moved` entry (cce-test-interface's panel copy
+ /// The legacy `WidgetHost` default `cursor_moved` entry (cce-test-interface's panel copy
/// calls it): cover-check clears hover, otherwise falls into `on_cursor_moved`. The
/// MouseLeave dispatch the default performed was a no-op for ScrollBox.
pub fn cursor_moved(&mut self, px: f32, py: f32, ctx: &mut UiContext) -> bool {
@@ -242,7 +242,7 @@ impl ScrollBox {
changed
}
- /// Legacy `Element` default parity (cce-test-interface's panel copy ticks it).
+ /// Legacy `WidgetHost` default parity (cce-test-interface's panel copy ticks it).
pub fn tick(&mut self, _dt: f32, _ctx: &mut UiContext) -> bool {
false
}
@@ -301,7 +301,7 @@ impl ScrollBox {
}
pub fn keyboard_input(&mut self, event: &KeyEvent, ctx: &mut UiContext) -> bool {
- // Focus never lands on the box itself (post-6av it is not an `Element`), and its id is
+ // Focus never lands on the box itself (post-6av it is not an `WidgetHost`), and its id is
// never a tree ancestor of the focused widget — like the legacy address walk, this
// gate only ever passes via the hover check below.
let self_id = self.base.id();
@@ -431,7 +431,7 @@ mod tests {
sb.update_bounds(300.0, 20.0, 100.0); // max_scroll = 200.0
let mut ctx = UiContext::new();
- // Hover the scroll box (the focus path took a ctx-registered Element; as a plain
+ // Hover the scroll box (the focus path took a ctx-registered WidgetHost; as a plain
// struct the hovered branch is the live gate).
ctx.set_cursor_pos(50.0, 50.0);
diff --git a/src/widget/container/spreadsheet.rs b/src/widget/container/spreadsheet.rs
index a3cfdb5..3bab1c2 100644
--- a/src/widget/container/spreadsheet.rs
+++ b/src/widget/container/spreadsheet.rs
@@ -63,7 +63,7 @@ impl Spreadsheet {
scrollbar_thumb_hovered: false,
});
// The spreadsheet pane starts hidden (the designer toggles it in later).
- crate::widget::Element::set_visible(&mut s, false);
+ crate::widget::WidgetHost::set_visible(&mut s, false);
s
}
@@ -109,7 +109,7 @@ impl Paint for Spreadsheet {
}
fn corner_style(&self, _rect: Rect) -> Option<(f32, (bool, bool, bool, bool))> {
- // Legacy: rounded_corners override (all corners) with the Element-default 12.0 radius.
+ // Legacy: rounded_corners override (all corners) with the WidgetHost-default 12.0 radius.
Some((12.0, (true, true, true, true)))
}
@@ -365,12 +365,12 @@ impl SpreadsheetController for Spreadsheet {
mod tests {
use super::*;
use crate::context::UiContext;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
fn filled(rows: usize) -> Adapted<Spreadsheet> {
let mut s = Spreadsheet::new();
s.set_visible(true);
- Element::set_rect(&mut s, 0.0, 0.0, 200.0, 124.0); // viewport: 100 = ~4 rows of 24
+ WidgetHost::set_rect(&mut s, 0.0, 0.0, 200.0, 124.0); // viewport: 100 = ~4 rows of 24
let data: Vec<Vec<String>> =
(0..rows).map(|i| vec![format!("r{i}"), format!("v{i}")]).collect();
SpreadsheetController::set_spreadsheet_data(&mut *s, vec!["a".into(), "b".into()], data);
@@ -396,9 +396,9 @@ mod tests {
assert!(s.handle_event(&wheel, &mut ctx), "in-rect wheel consumed");
// …which tick integrates into scroll movement and decays to a stop.
- assert!(Element::tick(&mut s, 0.016, &mut ctx), "first tick moves the scroll");
+ assert!(WidgetHost::tick(&mut s, 0.016, &mut ctx), "first tick moves the scroll");
let mut guard = 0;
- while Element::tick(&mut s, 0.016, &mut ctx) {
+ while WidgetHost::tick(&mut s, 0.016, &mut ctx) {
guard += 1;
assert!(guard < 1000, "inertia must decay to a stop");
}
@@ -417,20 +417,20 @@ mod tests {
let rect = Rect { x: 0.0, y: 0.0, width: 200.0, height: 124.0 };
// content 1200, viewport 100 -> overflowing, so the host may drag it.
- assert!(Element::draggable(&s));
+ assert!(WidgetHost::draggable(&s));
// Press on the scrollbar track (x >= 200-6-2-4): thumb jumps, drag engages.
- Element::drag_begin(&mut s, 195.0, 80.0);
- assert!(Element::is_dragging(&s));
- assert!(Element::drag_update(&mut s, 195.0, 110.0), "thumb drag scrolls");
+ WidgetHost::drag_begin(&mut s, 195.0, 80.0);
+ assert!(WidgetHost::is_dragging(&s));
+ assert!(WidgetHost::drag_update(&mut s, 195.0, 110.0), "thumb drag scrolls");
let dragged_to = s.inner().geom(rect).unwrap().scroll;
assert!(dragged_to > 0.0);
- Element::drag_end(&mut s);
- assert!(!Element::is_dragging(&s));
+ WidgetHost::drag_end(&mut s);
+ assert!(!WidgetHost::is_dragging(&s));
// A body press (left of the scrollbar) engages no drag.
- Element::drag_begin(&mut s, 50.0, 60.0);
- assert!(!Element::is_dragging(&s), "body press is not a scrollbar drag");
+ WidgetHost::drag_begin(&mut s, 50.0, 60.0);
+ assert!(!WidgetHost::is_dragging(&s), "body press is not a scrollbar drag");
// End key jumps to max; Home returns to zero. (Keys route via keyboard_input.)
let end = crate::widget::KeyEvent {
@@ -441,12 +441,12 @@ mod tests {
ctrl: false,
shift: false,
};
- assert!(Element::keyboard_input(&mut s, &end, &mut ctx));
+ assert!(WidgetHost::keyboard_input(&mut s, &end, &mut ctx));
let g = s.inner().geom(rect).unwrap();
assert_eq!(g.scroll, g.max_scroll);
// Hidden: the focused-widget keyboard path must not consume keys.
s.set_visible(false);
- assert!(!Element::keyboard_input(&mut s, &end, &mut ctx), "hidden widget ignores keys");
+ assert!(!WidgetHost::keyboard_input(&mut s, &end, &mut ctx), "hidden widget ignores keys");
}
}
diff --git a/src/widget/container/treelist.rs b/src/widget/container/treelist.rs
index c30125c..55f526b 100644
--- a/src/widget/container/treelist.rs
+++ b/src/widget/container/treelist.rs
@@ -357,7 +357,7 @@ impl TreeList {
}
}
- fn mouse_body(&mut self, button: MouseButton, state: ElementState, px: f32, py: f32, ui: &mut UiContext, host: Option<*mut (dyn Element + 'static)>, host_id: WidgetId) -> bool {
+ fn mouse_body(&mut self, button: MouseButton, state: ElementState, px: f32, py: f32, ui: &mut UiContext, host: Option<*mut (dyn WidgetHost + 'static)>, host_id: WidgetId) -> bool {
let _ = host_id;
if self.editing_key_idx.is_some() {
if button == MouseButton::Left && state == ElementState::Pressed {
@@ -690,7 +690,7 @@ impl Paint for TreeList {
true
}
- // Legacy TreeList kept the default Element focus/hover highlight overlay (the teal
+ // Legacy TreeList kept the default WidgetHost focus/hover highlight overlay (the teal
// wash over the focused tree, drawn by the old all_quads default) — opt back in
// (the 5q TextBox trap).
fn legacy_focus_highlight(&self) -> bool {
diff --git a/src/widget/core.rs b/src/widget/core.rs
index 4db482b..99153ae 100644
--- a/src/widget/core.rs
+++ b/src/widget/core.rs
@@ -1,7 +1,7 @@
-use crate::widget::{Element, Key};
+use crate::widget::{WidgetHost, Key};
pub mod focus {
- use super::Element;
+ use super::WidgetHost;
use crate::widget::WidgetId;
use std::cell::Cell;
@@ -23,7 +23,7 @@ pub mod focus {
}
}
- pub fn set_focused(w: &mut dyn Element, ctx: Option<&mut crate::context::UiContext>) {
+ pub fn set_focused(w: &mut dyn WidgetHost, ctx: Option<&mut crate::context::UiContext>) {
set_focused_id(w.base().id(), ctx);
}
@@ -39,7 +39,7 @@ pub mod focus {
}
}
- pub fn is_focused(w: &dyn Element) -> bool {
+ pub fn is_focused(w: &dyn WidgetHost) -> bool {
is_focused_id(w.base().id())
}
@@ -53,7 +53,7 @@ pub mod focus {
}
}
- pub fn clear_if_matches(w: &dyn Element) {
+ pub fn clear_if_matches(w: &dyn WidgetHost) {
clear_if_matches_id(w.base().id());
}
@@ -69,12 +69,12 @@ pub mod focus {
FOCUSED_WIDGET.with(|cell| cell.get().is_some())
}
- pub fn link_parent_child(parent: &mut dyn Element, child: &mut dyn Element, ctx: &mut crate::context::UiContext) {
+ pub fn link_parent_child(parent: &mut dyn WidgetHost, child: &mut dyn WidgetHost, ctx: &mut crate::context::UiContext) {
let parent_ptr = unsafe {
- std::mem::transmute::<*mut dyn Element, *mut (dyn Element + 'static)>(parent as *mut dyn Element)
+ std::mem::transmute::<*mut dyn WidgetHost, *mut (dyn WidgetHost + 'static)>(parent as *mut dyn WidgetHost)
};
let child_ptr = unsafe {
- std::mem::transmute::<*mut dyn Element, *mut (dyn Element + 'static)>(child as *mut dyn Element)
+ std::mem::transmute::<*mut dyn WidgetHost, *mut (dyn WidgetHost + 'static)>(child as *mut dyn WidgetHost)
};
let (p_id, c_id) = (parent.base().id(), child.base().id());
ctx.register_widget(p_id, parent_ptr);
@@ -578,7 +578,7 @@ pub mod context_menu {
CONTEXT_MENU.with(|m| m.borrow_mut().hide());
}
- pub fn clear_if_matches(w: &dyn Element) {
+ pub fn clear_if_matches(w: &dyn WidgetHost) {
let id = w.base().id();
CONTEXT_MENU.with(|m| {
let mut menu = m.borrow_mut();
@@ -697,7 +697,7 @@ impl Widget {
}
-pub fn clear_widget_references(w: &dyn Element) {
+pub fn clear_widget_references(w: &dyn WidgetHost) {
focus::clear_if_matches(w);
context_menu::clear_if_matches(w);
}
@@ -709,11 +709,11 @@ macro_rules! impl_widget_base {
fn base_mut(&mut self) -> &mut $crate::widget::Widget { &mut self.base }
fn as_any(&self) -> &dyn std::any::Any { self }
fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self }
- fn as_ptr(&self) -> *mut (dyn $crate::widget::Element + 'static) {
- self as *const Self as *mut Self as *mut (dyn $crate::widget::Element + 'static)
+ fn as_ptr(&self) -> *mut (dyn $crate::widget::WidgetHost + 'static) {
+ self as *const Self as *mut Self as *mut (dyn $crate::widget::WidgetHost + 'static)
}
- fn as_ptr_mut(&mut self) -> *mut (dyn $crate::widget::Element + 'static) {
- self as *mut Self as *mut (dyn $crate::widget::Element + 'static)
+ fn as_ptr_mut(&mut self) -> *mut (dyn $crate::widget::WidgetHost + 'static) {
+ self as *mut Self as *mut (dyn $crate::widget::WidgetHost + 'static)
}
};
}
diff --git a/src/widget/display/float3.rs b/src/widget/display/float3.rs
index 9c1746a..7a74186 100644
--- a/src/widget/display/float3.rs
+++ b/src/widget/display/float3.rs
@@ -1,6 +1,6 @@
//! Narrow-trait `Float3` (Phase 5t) — three labeled slider rows (X/Y/Z) with click-to-edit
//! numeric readouts, embedded by value inside `ParametersBg` (its only consumer), which drives
-//! it through direct `Element` calls and reads the pub value/edit fields through `Deref`. The
+//! it through direct `WidgetHost` calls and reads the pub value/edit fields through `Deref`. The
//! model caches its laid-out rect ([`Layout::rect_assigned`] — `get_row_rects` is pub API with
//! no rect parameter), draws everything in [`Paint::paint`], and keeps the legacy drag surface
//! on the `Input` drag hooks. The readout click's legacy `focus::set_focused(self)` rides
@@ -325,7 +325,7 @@ impl Input for Float3 {
mod tests {
use super::*;
use crate::context::UiContext;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
/// The ParametersBg drive pattern: readout click opens the edit, Enter/unfocus commits
/// back into the normalized value, track press starts a drag.
@@ -333,7 +333,7 @@ mod tests {
fn readout_edit_commits_on_unfocus() {
let mut ctx = UiContext::new();
let mut f = Float3::new().with_values([0.5, 0.5, 0.5]).with_range(0.0, 10.0);
- Element::set_rect(&mut f, 0.0, 0.0, 300.0, 108.0);
+ WidgetHost::set_rect(&mut f, 0.0, 0.0, 300.0, 108.0);
let rows = f.get_row_rects();
assert_eq!(rows.len(), 3);
@@ -345,17 +345,17 @@ mod tests {
assert_eq!(f.edit_buffer, "5.00");
f.edit_buffer = "7.5".to_string();
- Element::unfocus(&mut f);
+ WidgetHost::unfocus(&mut f);
assert_eq!(f.editing_idx, None);
assert!((f.values[1] - 0.75).abs() < 1e-4, "7.5 of 0..10 normalizes to 0.75");
// Track press starts a drag; drag_update moves the value; release ends it.
let track_y = rows[0].1 + 8.0;
assert!(f.mouse_input(MouseButton::Left, ElementState::Pressed, 150.0, track_y, &mut ctx));
- assert!(Element::is_dragging(&f));
- Element::drag_update(&mut f, 260.0, track_y);
+ assert!(WidgetHost::is_dragging(&f));
+ WidgetHost::drag_update(&mut f, 260.0, track_y);
assert!(f.values[0] > 0.5, "drag right raises the value");
- Element::drag_end(&mut f);
- assert!(!Element::is_dragging(&f));
+ WidgetHost::drag_end(&mut f);
+ assert!(!WidgetHost::is_dragging(&f));
}
}
diff --git a/src/widget/display/graph.rs b/src/widget/display/graph.rs
index 3d5677e..dbe2d90 100644
--- a/src/widget/display/graph.rs
+++ b/src/widget/display/graph.rs
@@ -43,7 +43,7 @@ pub struct GraphNode {
pub outputs: usize,
}
-/// The widget's own corner style: the legacy `Element` defaults it inherited
+/// The widget's own corner style: the legacy `WidgetHost` defaults it inherited
/// (`corner_radius` 12.0, bottom corners rounded).
const WIDGET_RADIUS: f32 = 12.0;
const WIDGET_CORNERS: (bool, bool, bool, bool) = (false, false, true, true);
@@ -1019,11 +1019,11 @@ impl GraphController for Graph {
mod tests {
use super::*;
use crate::context::UiContext;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
fn two_nodes() -> Adapted<Graph> {
let mut g = Graph::new();
- Element::set_rect(&mut g, 0.0, 0.0, 800.0, 600.0);
+ WidgetHost::set_rect(&mut g, 0.0, 0.0, 800.0, 600.0);
g.set_grid_sizes(80.0, 40.0);
g.set_skipped_sizes(20.0, 20.0);
g.set_grid_origin(100.0, 100.0);
@@ -1052,14 +1052,14 @@ mod tests {
// Node a occupies (100, 100, 80, 40). Press its body (away from ports/toggle).
assert!(g.mouse_input(MouseButton::Left, ElementState::Pressed, 110.0, 120.0, &mut ctx));
assert_eq!(g.selected_node(), Some(0));
- assert!(Element::is_dragging(&g) && Element::draggable(&g));
+ assert!(WidgetHost::is_dragging(&g) && WidgetHost::draggable(&g));
// Drag one grid step right (step_x = 100): snap puts the node at column 1, but cell
// (1, 0) is free so it lands there.
- Element::drag_begin(&mut g, 110.0, 120.0);
- assert!(Element::drag_update(&mut g, 210.0, 120.0));
+ WidgetHost::drag_begin(&mut g, 110.0, 120.0);
+ assert!(WidgetHost::drag_update(&mut g, 210.0, 120.0));
assert!(g.mouse_input(MouseButton::Left, ElementState::Released, 210.0, 120.0, &mut ctx));
- assert!(!Element::is_dragging(&g));
+ assert!(!WidgetHost::is_dragging(&g));
assert_eq!(g.get_nodes()[0].position, (1.0, 0.0));
// An empty-space press clears the selection and is NOT consumed (legacy contract).
@@ -1090,8 +1090,8 @@ mod tests {
// The plain view (designer path) and the rounded view (render_widget path) describe
// the same quads: the rounded view adds only the widget background entry up front.
- let plain = Element::extra_quads(&g);
- let rounded = Element::all_rounded_quads(&g, &ctx);
+ let plain = WidgetHost::extra_quads(&g);
+ let rounded = WidgetHost::all_rounded_quads(&g, &ctx);
assert!(!plain.is_empty());
assert_eq!(rounded.len(), plain.len() + 1);
for ((px, py, pw, ph, pc), (rx, ry, rw, rh, _, rc, _)) in plain.iter().zip(rounded.iter().skip(1)) {
@@ -1112,6 +1112,6 @@ mod tests {
// And `all_quads` stays empty so render_widget hosts (reading BOTH getters) never
// draw the geometry twice — the legacy Graph override's contract.
- assert!(Element::all_quads(&g, &ctx).is_empty());
+ assert!(WidgetHost::all_quads(&g, &ctx).is_empty());
}
}
diff --git a/src/widget/display/label.rs b/src/widget/display/label.rs
index d6fb942..35a2575 100644
--- a/src/widget/display/label.rs
+++ b/src/widget/display/label.rs
@@ -5,7 +5,7 @@ use crate::scene::paint::PaintCtx;
/// Narrow-trait text label (Phase 5f leaf sweep). The text lives on the model and is emitted by
/// `paint` as a `Text` prim, which the adapter's prim-derived `text_labels` bridge serves to
-/// every legacy text path; `set_text` sync comes from the adapter's generic `Element::set_text`
+/// every legacy text path; `set_text` sync comes from the adapter's generic `WidgetHost::set_text`
/// override via [`Paint::sync_label`].
#[derive(Debug, Clone)]
pub struct Label {
@@ -23,7 +23,7 @@ impl Label {
color: colors::control_label_color_u8(),
});
// Keep the base copy in step too (context menus, fallback machinery).
- Element::set_text(&mut l, text);
+ WidgetHost::set_text(&mut l, text);
l
}
@@ -91,11 +91,11 @@ mod tests {
use super::*;
/// Legacy `text_labels` parity through the prim bridge, and `set_text` staying in sync
- /// through the adapter's `Element::set_text` override (the trait method apps actually hit).
+ /// through the adapter's `WidgetHost::set_text` override (the trait method apps actually hit).
#[test]
fn text_flows_and_set_text_syncs() {
let mut l = Label::new("CPU: 3%").with_font_size(13.0).with_color([1, 2, 3]);
- Element::set_rect(&mut l, 10.0, 20.0, 100.0, 16.0);
+ WidgetHost::set_rect(&mut l, 10.0, 20.0, 100.0, 16.0);
let labels = l.own_text_labels();
assert_eq!(labels.len(), 1);
@@ -104,12 +104,12 @@ mod tests {
assert_eq!(labels[0].font_size, 13.0);
assert_eq!(labels[0].color, [1, 2, 3]);
- Element::set_text(&mut l, "CPU: 99%");
+ WidgetHost::set_text(&mut l, "CPU: 99%");
assert_eq!(l.own_text_labels()[0].text, "CPU: 99%", "set_text reaches the paint source");
let size = l.intrinsic_size().unwrap();
assert!(size.width > 0.0);
- assert!(!Element::blocks_backplate_drag(&l));
+ assert!(!WidgetHost::blocks_backplate_drag(&l));
}
}
diff --git a/src/widget/display/node.rs b/src/widget/display/node.rs
index 3c3409f..d86d644 100644
--- a/src/widget/display/node.rs
+++ b/src/widget/display/node.rs
@@ -1,7 +1,7 @@
//! Narrow-trait `Node` (Phase 5k) — a network-editor node box: draggable with grid snap
//! (self-moving, via [`Input::drag_reposition`]), a geometry-visibility toggle sub-zone, and
//! two controller capabilities ([`ParamController`] + [`GeomController`]) re-exposed through
-//! the `Input` hooks for the legacy `Element::as_*_controller` downcasts.
+//! the `Input` hooks for the legacy `WidgetHost::as_*_controller` downcasts.
use crate::colors;
use crate::scene::layout::Rect;
@@ -49,7 +49,7 @@ impl Node {
geom_toggled: false,
toggle_hovered: false,
});
- crate::widget::Element::set_rect(&mut node, x, y, w, h);
+ crate::widget::WidgetHost::set_rect(&mut node, x, y, w, h);
node
}
@@ -249,7 +249,7 @@ impl GeomController for Node {
mod tests {
use super::*;
use crate::context::UiContext;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
#[test]
fn toggle_click_flips_geom_and_press_starts_drag() {
@@ -267,11 +267,11 @@ mod tests {
// A press outside the toggle starts a drag; reposition snaps to the drag origin.
assert!(node.mouse_input(MouseButton::Left, ElementState::Pressed, 110.0, 110.0, &mut ctx));
- assert!(Element::is_dragging(&node));
- assert!(Element::drag_update(&mut node, 150.0, 130.0));
- assert_eq!(Element::rect(&node), (140.0, 120.0, 120.0, 40.0), "moved by the pointer delta");
+ assert!(WidgetHost::is_dragging(&node));
+ assert!(WidgetHost::drag_update(&mut node, 150.0, 130.0));
+ assert_eq!(WidgetHost::rect(&node), (140.0, 120.0, 120.0, 40.0), "moved by the pointer delta");
assert!(node.mouse_input(MouseButton::Left, ElementState::Released, 150.0, 130.0, &mut ctx));
- assert!(!Element::is_dragging(&node));
+ assert!(!WidgetHost::is_dragging(&node));
}
#[test]
diff --git a/src/widget/display/panel.rs b/src/widget/display/panel.rs
index 906bfa6..0ad1218 100644
--- a/src/widget/display/panel.rs
+++ b/src/widget/display/panel.rs
@@ -5,7 +5,7 @@
use crate::colors;
use crate::scene::layout::Rect;
use crate::scene::paint::PaintCtx;
-use crate::widget::{Adapted, Element, ElementState, Event, EventCtx, Input, Layout, MouseButton, Paint};
+use crate::widget::{Adapted, WidgetHost, ElementState, Event, EventCtx, Input, Layout, MouseButton, Paint};
pub struct Panel {
dragging: bool,
@@ -17,7 +17,7 @@ pub struct Panel {
impl Panel {
pub fn new(x: f32, y: f32, w: f32, h: f32) -> Adapted<Panel> {
let mut p = Adapted::new(Panel { dragging: false, drag_ox: 0.0, drag_oy: 0.0, bounds: None });
- Element::set_rect(&mut p, x, y, w, h);
+ WidgetHost::set_rect(&mut p, x, y, w, h);
p
}
diff --git a/src/widget/display/progress_bar.rs b/src/widget/display/progress_bar.rs
index c3c10aa..ce68e67 100644
--- a/src/widget/display/progress_bar.rs
+++ b/src/widget/display/progress_bar.rs
@@ -1,4 +1,4 @@
-//! The first widget migrated off `Element` onto the narrow traits (Phase 5c). `ProgressBar`
+//! The first widget migrated off `WidgetHost` onto the narrow traits (Phase 5c). `ProgressBar`
//! implements only [`Layout`] + [`Paint`] + [`Input`]; [`ProgressBar::new`] returns it already
//! wrapped in [`Adapted`], so construction sites (`Box::new(ProgressBar::new(0.65))`, optionally
//! `.with_label(..)`) are unchanged by the migration.
@@ -56,7 +56,7 @@ impl Input for ProgressBar {}
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::{Element, UiContext};
+ use crate::widget::{WidgetHost, UiContext};
/// The reverse bridge reproduces the legacy `all_rounded_quads` output: track quad at the
/// content rect, fill quad at `w * value` with the radius clamped to half the height.
@@ -64,9 +64,9 @@ mod tests {
fn reverse_bridge_matches_legacy_geometry() {
let ctx = UiContext::new();
let mut bar = ProgressBar::new(0.5);
- Element::set_rect(&mut bar, 10.0, 20.0, 100.0, 8.0);
+ WidgetHost::set_rect(&mut bar, 10.0, 20.0, 100.0, 8.0);
- let quads = Element::all_rounded_quads(&bar, &ctx);
+ let quads = WidgetHost::all_rounded_quads(&bar, &ctx);
let radius = crate::layout::slider_corner_radius();
assert_eq!(quads.len(), 2, "track + fill");
assert_eq!(quads[0], (10.0, 20.0, 100.0, 8.0, radius, colors::progress_bg(), (true, true, true, true)));
@@ -81,13 +81,13 @@ mod tests {
fn fill_clamps_to_track() {
let ctx = UiContext::new();
let mut over = ProgressBar::new(2.0);
- Element::set_rect(&mut over, 0.0, 0.0, 100.0, 8.0);
- let quads = Element::all_rounded_quads(&over, &ctx);
+ WidgetHost::set_rect(&mut over, 0.0, 0.0, 100.0, 8.0);
+ let quads = WidgetHost::all_rounded_quads(&over, &ctx);
assert_eq!(quads[1].2, 100.0, "over-1 value fills the whole track");
let mut empty = ProgressBar::new(0.0);
- Element::set_rect(&mut empty, 0.0, 0.0, 100.0, 8.0);
- assert_eq!(Element::all_rounded_quads(&empty, &ctx).len(), 1, "zero value emits track only");
+ WidgetHost::set_rect(&mut empty, 0.0, 0.0, 100.0, 8.0);
+ assert_eq!(WidgetHost::all_rounded_quads(&empty, &ctx).len(), 1, "zero value emits track only");
}
/// The detached-label convention survives the adapter: `set_rect` grows the widget by the
@@ -97,20 +97,20 @@ mod tests {
fn label_inflates_rect_and_insets_paint() {
let ctx = UiContext::new();
let mut bar = ProgressBar::new(0.5).with_label("Progress");
- Element::set_rect(&mut bar, 0.0, 10.0, 100.0, 8.0);
+ WidgetHost::set_rect(&mut bar, 0.0, 10.0, 100.0, 8.0);
- let (_, y, _, h) = Element::rect(&bar);
+ let (_, y, _, h) = WidgetHost::rect(&bar);
let offset = h - 8.0;
assert!(offset >= 0.0, "rect grew by the label offset");
assert_eq!(y, 10.0, "origin is unchanged");
- let quads = Element::all_rounded_quads(&bar, &ctx);
+ let quads = WidgetHost::all_rounded_quads(&bar, &ctx);
assert_eq!(quads[0].1, 10.0 + offset, "track is painted below the label region");
assert_eq!(quads[0].3, 8.0, "track keeps the assigned height");
// preferred_height forwards from the narrow intrinsic size.
- assert_eq!(Element::preferred_height(&bar), Some(crate::layout::progressbar_height()));
+ assert_eq!(WidgetHost::preferred_height(&bar), Some(crate::layout::progressbar_height()));
// Runtime type-name matching still sees "ProgressBar", not Adapted<..>.
- assert_eq!(Element::type_name(&bar), "ProgressBar");
+ assert_eq!(WidgetHost::type_name(&bar), "ProgressBar");
}
}
diff --git a/src/widget/display/separator.rs b/src/widget/display/separator.rs
index 5bb38cb..b5cb77d 100644
--- a/src/widget/display/separator.rs
+++ b/src/widget/display/separator.rs
@@ -3,7 +3,7 @@
//! callers position it via `set_rect`/`rect` (cce-status-interface's rotation loop was updated
//! accordingly).
-use crate::widget::{Adapted, Element, Input, Layout, Paint};
+use crate::widget::{Adapted, WidgetHost, Input, Layout, Paint};
#[derive(Debug, Clone)]
pub struct Separator {
@@ -13,7 +13,7 @@ pub struct Separator {
impl Separator {
pub fn new(x: f32, y: f32, w: f32, h: f32, color: [f32; 4]) -> Adapted<Separator> {
let mut sep = Adapted::new(Separator { color });
- Element::set_rect(&mut sep, x, y, w, h);
+ WidgetHost::set_rect(&mut sep, x, y, w, h);
sep
}
}
@@ -39,18 +39,18 @@ mod tests {
#[test]
fn constructor_places_the_rect_and_bridge_emits_it() {
let sep = Separator::new(100.0, 0.0, 1.0, 24.0, [0.3, 0.3, 0.3, 1.0]);
- assert_eq!(Element::rect(&sep), (100.0, 0.0, 1.0, 24.0));
- assert_eq!(Element::color(&sep), [0.3, 0.3, 0.3, 1.0]);
- assert_eq!(Element::extra_quads(&sep), vec![(100.0, 0.0, 1.0, 24.0, [0.3, 0.3, 0.3, 1.0])]);
- assert!(!Element::blocks_backplate_drag(&sep));
+ assert_eq!(WidgetHost::rect(&sep), (100.0, 0.0, 1.0, 24.0));
+ assert_eq!(WidgetHost::color(&sep), [0.3, 0.3, 0.3, 1.0]);
+ assert_eq!(WidgetHost::extra_quads(&sep), vec![(100.0, 0.0, 1.0, 24.0, [0.3, 0.3, 0.3, 1.0])]);
+ assert!(!WidgetHost::blocks_backplate_drag(&sep));
}
/// The status bar's vertical-rotation pattern, post-migration: transpose via rect/set_rect.
#[test]
fn rotation_via_set_rect() {
let mut sep = Separator::new(100.0, 0.0, 1.0, 24.0, [0.3, 0.3, 0.3, 1.0]);
- let (x, y, w, h) = Element::rect(&sep);
- Element::set_rect(&mut sep, y, x, h, w);
- assert_eq!(Element::rect(&sep), (0.0, 100.0, 24.0, 1.0));
+ let (x, y, w, h) = WidgetHost::rect(&sep);
+ WidgetHost::set_rect(&mut sep, y, x, h, w);
+ assert_eq!(WidgetHost::rect(&sep), (0.0, 100.0, 24.0, 1.0));
}
}
diff --git a/src/widget/display/serialize.rs b/src/widget/display/serialize.rs
index fc0f9d7..9447648 100644
--- a/src/widget/display/serialize.rs
+++ b/src/widget/display/serialize.rs
@@ -1,6 +1,6 @@
use crate::widget::*;
-fn serialize_single_widget(w: &dyn Element, json: &mut String) {
+fn serialize_single_widget(w: &dyn WidgetHost, json: &mut String) {
let (x, y, width, height) = w.rect();
let label = w.label().or_else(|| w.base().label.clone()).unwrap_or_default();
let focused = w.base().focused;
@@ -24,7 +24,7 @@ fn serialize_single_widget(w: &dyn Element, json: &mut String) {
let mut is_vertical = false;
let mut checked_states = Vec::new();
// Concrete capability lookup (Phase 6aw): the MenuController implementors a serialized
- // roster can hold are Adapted<MenuBar> and Adapted<Paginator> — Element's discovery
+ // roster can hold are Adapted<MenuBar> and Adapted<Paginator> — WidgetHost's discovery
// hooks are gone.
let mc: Option<&dyn MenuController> = w
.as_any()
@@ -84,7 +84,7 @@ fn serialize_single_widget(w: &dyn Element, json: &mut String) {
/// Serialize the visible widgets' menu state. Takes dyn refs (not boxes): the designer's
/// roster is concretely typed since the Phase 6bb retype and lends a per-slot dyn view.
-pub fn serialize_widgets(widgets: &[&dyn Element]) -> String {
+pub fn serialize_widgets(widgets: &[&dyn WidgetHost]) -> String {
let mut json = String::new();
json.push('[');
let mut first = true;
diff --git a/src/widget/display/sidebar.rs b/src/widget/display/sidebar.rs
index 858bc6b..e7605a9 100644
--- a/src/widget/display/sidebar.rs
+++ b/src/widget/display/sidebar.rs
@@ -2,14 +2,14 @@
//! x/y/w/h fields now live on the `Adapted` base.
use crate::colors;
-use crate::widget::{Adapted, Element, Input, Layout, Paint};
+use crate::widget::{Adapted, WidgetHost, Input, Layout, Paint};
pub struct Sidebar;
impl Sidebar {
pub fn new(w: f32) -> Adapted<Sidebar> {
let mut s = Adapted::new(Sidebar);
- Element::set_rect(&mut s, 0.0, 0.0, w, 0.0);
+ WidgetHost::set_rect(&mut s, 0.0, 0.0, w, 0.0);
s
}
}
diff --git a/src/widget/display/splitter.rs b/src/widget/display/splitter.rs
index 2f18997..0bb57fd 100644
--- a/src/widget/display/splitter.rs
+++ b/src/widget/display/splitter.rs
@@ -4,7 +4,7 @@
use crate::colors;
use crate::scene::layout::Rect;
-use crate::widget::{Adapted, Element, ElementState, Event, EventCtx, Input, Layout, MouseButton, Paint};
+use crate::widget::{Adapted, WidgetHost, ElementState, Event, EventCtx, Input, Layout, MouseButton, Paint};
pub struct Splitter {
hovered: bool,
@@ -15,7 +15,7 @@ pub struct Splitter {
impl Splitter {
pub fn new(w: f32) -> Adapted<Splitter> {
let mut s = Adapted::new(Splitter { hovered: false, dragging: false, drag_ox: 0.0 });
- Element::set_rect(&mut s, 0.0, 0.0, w, 0.0);
+ WidgetHost::set_rect(&mut s, 0.0, 0.0, w, 0.0);
s
}
}
diff --git a/src/widget/display/status_bar.rs b/src/widget/display/status_bar.rs
index 88b9c06..dac85c9 100644
--- a/src/widget/display/status_bar.rs
+++ b/src/widget/display/status_bar.rs
@@ -83,7 +83,7 @@ impl Adapted<StatusBar> {
impl Layout for StatusBar {
/// The status text draws inside the bar; the base label must never inflate the rect or
- /// emit a detached label (`Element::set_text` writes both the base copy and
+ /// emit a detached label (`WidgetHost::set_text` writes both the base copy and
/// [`Paint::sync_label`]).
fn inline_label(&self) -> bool {
true
@@ -107,7 +107,7 @@ impl Paint for StatusBar {
Some((0.0, (false, false, false, false)))
}
- /// `Element::set_text` lands here: swap the text and drop the shaped buffer so
+ /// `WidgetHost::set_text` lands here: swap the text and drop the shaped buffer so
/// `prepare_text` rebuilds it.
fn sync_label(&mut self, label: &str) {
if self.text != label {
@@ -159,7 +159,7 @@ impl Input for StatusBar {
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
/// The shaped-buffer lifecycle behind the old manual-host path: `set_text` drops the
/// buffer, `prepare_text` rebuilds it. (The `get_text_items` getter that served it is
@@ -168,23 +168,23 @@ mod tests {
fn manual_host_text_pipeline() {
let mut fs = glyphon::FontSystem::new();
let mut bar = StatusBar::new().with_text("hello").with_text_offset_x(15.0);
- Element::set_rect(&mut bar, 0.0, 570.0, 800.0, 30.0);
+ WidgetHost::set_rect(&mut bar, 0.0, 570.0, 800.0, 30.0);
assert!(bar.text_buf.is_none(), "no buffer before prepare_text");
- Element::prepare_text(&mut bar, &mut fs);
+ WidgetHost::prepare_text(&mut bar, &mut fs);
assert!(bar.text_buf.is_some(), "one shaped buffer");
// set_text drops the stale buffer; prepare_text reshapes.
- Element::set_text(&mut bar, "world");
+ WidgetHost::set_text(&mut bar, "world");
assert!(bar.text_buf.is_none(), "buffer dropped on text change");
- Element::prepare_text(&mut bar, &mut fs);
+ WidgetHost::prepare_text(&mut bar, &mut fs);
assert!(bar.text_buf.is_some());
assert_eq!(bar.text, "world");
// Parentless: cornerless plain bg through the plain-quad bridge, at STATUS_BG.
- let extra = Element::extra_quads(&bar);
+ let extra = WidgetHost::extra_quads(&bar);
assert_eq!(extra.len(), 1, "cornerless bg quad");
- assert_eq!(Element::corner_style(&bar).1, (false, false, false, false));
- assert!(!Element::blocks_backplate_drag(&bar));
+ assert_eq!(WidgetHost::corner_style(&bar).1, (false, false, false, false));
+ assert!(!WidgetHost::blocks_backplate_drag(&bar));
}
}
diff --git a/src/widget/display/status_dot.rs b/src/widget/display/status_dot.rs
index 77f0c64..ecf62bf 100644
--- a/src/widget/display/status_dot.rs
+++ b/src/widget/display/status_dot.rs
@@ -1,6 +1,6 @@
//! Narrow-trait status dot (Phase 5c leaf sweep).
//!
-//! **Deliberate behavior fix:** the legacy `Element` impl only set `color()` and never emitted
+//! **Deliberate behavior fix:** the legacy `WidgetHost` impl only set `color()` and never emitted
//! geometry on any render path (`all_quads` and `all_rounded_quads` were both empty for it, and
//! `render_widget` never reads `color()` directly), so the dot was **invisible** — a probe test
//! against the legacy widget confirmed zero rects emitted through `render_widget`. The narrow
@@ -56,18 +56,18 @@ impl Input for StatusDot {
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::{Element, UiContext};
+ use crate::widget::{WidgetHost, UiContext};
#[test]
fn emits_its_color_quad_through_the_bridge() {
let mut dot = StatusDot::new(DotStatus::Warning);
- Element::set_rect(&mut dot, 5.0, 6.0, 10.0, 10.0);
+ WidgetHost::set_rect(&mut dot, 5.0, 6.0, 10.0, 10.0);
assert_eq!(
- Element::extra_quads(&dot),
+ WidgetHost::extra_quads(&dot),
vec![(5.0, 6.0, 10.0, 10.0, [0.90, 0.60, 0.10, 1.0])],
);
// Drags pass through, as legacy declared.
- assert!(!Element::blocks_backplate_drag(&dot));
+ assert!(!WidgetHost::blocks_backplate_drag(&dot));
// State mutation through Deref, as call sites write it.
dot.set_status(DotStatus::Error);
assert_eq!(dot.status, DotStatus::Error);
diff --git a/src/widget/display/usage_bar.rs b/src/widget/display/usage_bar.rs
index e8c6071..eeca0ad 100644
--- a/src/widget/display/usage_bar.rs
+++ b/src/widget/display/usage_bar.rs
@@ -55,23 +55,23 @@ impl Input for UsageBar {}
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::Element;
+ use crate::widget::WidgetHost;
/// Byte-identical to the legacy `extra_quads` override: full-width bg quad, then a fill quad
/// scaled by the clamped value.
#[test]
fn bridge_matches_legacy_extra_quads() {
let mut bar = UsageBar::new(0.5).with_colors([0.1, 0.2, 0.3, 1.0], [0.4, 0.5, 0.6, 1.0]);
- Element::set_rect(&mut bar, 12.0, 30.0, 200.0, 8.0);
+ WidgetHost::set_rect(&mut bar, 12.0, 30.0, 200.0, 8.0);
assert_eq!(
- Element::extra_quads(&bar),
+ WidgetHost::extra_quads(&bar),
vec![
(12.0, 30.0, 200.0, 8.0, [0.4, 0.5, 0.6, 1.0]),
(12.0, 30.0, 100.0, 8.0, [0.1, 0.2, 0.3, 1.0]),
],
);
// Nothing leaks onto the rounded path (apps read both getters).
- assert!(Element::all_rounded_quads(&bar, &crate::widget::UiContext::new()).is_empty());
+ assert!(WidgetHost::all_rounded_quads(&bar, &crate::widget::UiContext::new()).is_empty());
}
#[test]
diff --git a/src/widget/input/button.rs b/src/widget/input/button.rs
index 2b635b7..8d6b8a5 100644
--- a/src/widget/input/button.rs
+++ b/src/widget/input/button.rs
@@ -8,7 +8,7 @@ use crate::colors;
use crate::scene::layout::{Rect, Size};
use crate::scene::paint::PaintCtx;
use crate::widget::{
- Adapted, Control, Element, ElementState, Event, EventCtx, Input, Justification, Layout,
+ Adapted, Control, WidgetHost, ElementState, Event, EventCtx, Input, Justification, Layout,
MouseButton, Paint,
};
@@ -68,7 +68,7 @@ impl Button {
fn adapted(kind: ButtonKind, x: f32, y: f32, w: f32, h: f32) -> Adapted<Button> {
let mut b = Adapted::new(Button::model(kind));
- Element::set_rect(&mut b, x, y, w, h);
+ WidgetHost::set_rect(&mut b, x, y, w, h);
b
}
@@ -404,13 +404,13 @@ mod tests {
// Press in, release in -> click.
assert!(ctx.propagate_event(&press(20.0, 20.0), ptr));
assert!(ctx.propagate_event(&release(25.0, 20.0), ptr), "release consumed (was pressed)");
- assert!(Element::take_click(&mut b));
+ assert!(WidgetHost::take_click(&mut b));
assert_eq!(fired.load(std::sync::atomic::Ordering::SeqCst), 1, "callback fired");
// Press in, release OUT -> cancelled, no click, but release still consumed.
assert!(ctx.propagate_event(&press(20.0, 20.0), ptr));
assert!(ctx.propagate_event(&release(500.0, 500.0), ptr), "cancelling release consumed");
- assert!(!Element::take_click(&mut b), "no click on out-of-rect release");
+ assert!(!WidgetHost::take_click(&mut b), "no click on out-of-rect release");
assert_eq!(fired.load(std::sync::atomic::Ordering::SeqCst), 1, "callback not re-fired");
// Release without a press is not consumed.
@@ -425,8 +425,8 @@ mod tests {
let b = Button::new(0.0, 0.0, 100.0, 24.0).with_label("Go");
let radius = crate::layout::button_corner_radius();
- let rounded = Element::all_rounded_quads(&b, &ctx);
- let plain = Element::extra_quads(&b);
+ let rounded = WidgetHost::all_rounded_quads(&b, &ctx);
+ let plain = WidgetHost::extra_quads(&b);
if radius > 0.0 {
assert!(!rounded.is_empty() && plain.is_empty(), "rounded config -> rounded path only");
assert_eq!(rounded[0].4, radius);
@@ -440,9 +440,9 @@ mod tests {
let est = b.label_width("Go");
assert_eq!(labels[0].x, (100.0 - est) / 2.0, "center-justified");
- // Selection state flows through the Element forward (list hosts push it).
+ // Selection state flows through the WidgetHost forward (list hosts push it).
let mut b = b;
- Element::set_selected(&mut b, true);
+ WidgetHost::set_selected(&mut b, true);
assert!(b.selected);
}
}
diff --git a/src/widget/input/checkbox.rs b/src/widget/input/checkbox.rs
index d5d5aa0..fb450f6 100644
--- a/src/widget/input/checkbox.rs
+++ b/src/widget/input/checkbox.rs
@@ -1,4 +1,4 @@
-//! Narrow-trait `Checkbox` and `Toggle` (Phase 5e — first interactive widgets off `Element`).
+//! Narrow-trait `Checkbox` and `Toggle` (Phase 5e — first interactive widgets off `WidgetHost`).
//!
//! Both are inline-label widgets: they paint their own label (with hover/focus-dependent color)
//! inside their rect, so they track `hovered`/`focused` themselves from the `MouseEnter`/
@@ -456,7 +456,7 @@ impl Control for Adapted<Toggle> {
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::{Element, UiContext};
+ use crate::widget::{WidgetHost, UiContext};
fn click_at(x: f32, y: f32) -> Event {
Event::MouseButton {
@@ -475,13 +475,13 @@ mod tests {
let mut cb = Checkbox::new();
let (id, ptr) = (cb.id(), cb.as_ptr_mut());
ctx.register_widget(id, ptr);
- Element::set_rect(&mut cb, 0.0, 0.0, 20.0, 20.0);
+ WidgetHost::set_rect(&mut cb, 0.0, 0.0, 20.0, 20.0);
assert!(ctx.propagate_event(&click_at(10.0, 10.0), ptr), "in-rect click consumed");
assert!(cb.checked(), "click checked it");
- assert!(Element::take_click(&mut cb), "take_click reads once");
- assert!(!Element::take_click(&mut cb), "...then clears");
- assert!(Element::take_change(&mut cb));
+ assert!(WidgetHost::take_click(&mut cb), "take_click reads once");
+ assert!(!WidgetHost::take_click(&mut cb), "...then clears");
+ assert!(WidgetHost::take_change(&mut cb));
assert!(!ctx.propagate_event(&click_at(100.0, 100.0), ptr), "miss is not consumed");
assert!(cb.checked(), "miss does not toggle");
@@ -490,13 +490,13 @@ mod tests {
#[test]
fn checkbox_value_string_round_trip() {
let mut cb = Checkbox::new();
- assert_eq!(Element::get_value_string(&cb), Some("false".to_string()));
- assert!(Element::set_value_string(&mut cb, "on"));
+ assert_eq!(WidgetHost::get_value_string(&cb), Some("false".to_string()));
+ assert!(WidgetHost::set_value_string(&mut cb, "on"));
assert!(cb.checked());
- assert_eq!(Element::value(&cb), 1);
- assert!(!Element::set_value_string(&mut cb, "on"), "unchanged value reports false");
- assert!(!Element::set_value_string(&mut cb, "junk"), "unparsable reports false");
- assert!(Element::take_change(&mut cb), "set_value_string marked the change");
+ assert_eq!(WidgetHost::value(&cb), 1);
+ assert!(!WidgetHost::set_value_string(&mut cb, "on"), "unchanged value reports false");
+ assert!(!WidgetHost::set_value_string(&mut cb, "junk"), "unparsable reports false");
+ assert!(WidgetHost::take_change(&mut cb), "set_value_string marked the change");
}
/// Wide (labeled) mode reproduces the legacy `extra_quads` geometry through the bridge:
@@ -506,9 +506,9 @@ mod tests {
fn checkbox_wide_mode_bridge_parity() {
let ctx = UiContext::new();
let mut cb = Checkbox::new().with_label("Enable");
- Element::set_rect(&mut cb, 0.0, 0.0, 200.0, 24.0);
+ WidgetHost::set_rect(&mut cb, 0.0, 0.0, 200.0, 24.0);
- let quads = Element::extra_quads(&cb);
+ let quads = WidgetHost::extra_quads(&cb);
// Unchecked: box bg + 4 border edges = 5 quads, at the legacy box position.
assert_eq!(quads.len(), 5);
let (box_x, box_y, box_size) = (200.0 - 18.0 - 8.0, (24.0 - 18.0) / 2.0, 18.0);
@@ -516,7 +516,7 @@ mod tests {
// Hover flips the box + border colors (tracked from MouseEnter, not base state).
cb.inner_mut().hovered = true;
- let quads = Element::extra_quads(&cb);
+ let quads = WidgetHost::extra_quads(&cb);
assert_eq!(quads[0].4, colors::checkbox_hover());
// Label text comes through the prim-derived text bridge at the legacy position.
@@ -526,7 +526,7 @@ mod tests {
assert_eq!(labels[0].x, 8.0);
// Inline label => no set_rect inflation.
- assert_eq!(Element::rect(&cb), (0.0, 0.0, 200.0, 24.0));
+ assert_eq!(WidgetHost::rect(&cb), (0.0, 0.0, 200.0, 24.0));
let _ = &ctx;
}
@@ -536,32 +536,32 @@ mod tests {
let mut t = Toggle::new();
let (id, ptr) = (t.id(), t.as_ptr_mut());
ctx.register_widget(id, ptr);
- Element::set_rect(&mut t, 0.0, 0.0, 60.0, 30.0);
+ WidgetHost::set_rect(&mut t, 0.0, 0.0, 60.0, 30.0);
// Geometry parity is config-dependent (rounded vs square toggle); assert the invariant
// that holds in both: the bordered half flips with the state.
- let before: Vec<_> = Element::all_rounded_quads(&t, &ctx);
- let before_quads = Element::extra_quads(&t);
+ let before: Vec<_> = WidgetHost::all_rounded_quads(&t, &ctx);
+ let before_quads = WidgetHost::extra_quads(&t);
assert!(ctx.propagate_event(&click_at(30.0, 15.0), ptr), "toggle consumed the click");
assert!(t.toggled());
- assert!(Element::take_click(&mut t));
+ assert!(WidgetHost::take_click(&mut t));
- let after: Vec<_> = Element::all_rounded_quads(&t, &ctx);
- let after_quads = Element::extra_quads(&t);
+ let after: Vec<_> = WidgetHost::all_rounded_quads(&t, &ctx);
+ let after_quads = WidgetHost::extra_quads(&t);
assert!(
before != after || before_quads != after_quads,
"toggling changes the emitted geometry (border switches halves)",
);
// preferred_height forwards the legacy toggle height.
- assert_eq!(Element::preferred_height(&t), Some(crate::layout::toggle_height()));
+ assert_eq!(WidgetHost::preferred_height(&t), Some(crate::layout::toggle_height()));
}
#[test]
fn toggle_set_label_via_deref_reaches_paint() {
let mut t = Toggle::new();
- Element::set_rect(&mut t, 0.0, 0.0, 60.0, 30.0);
+ WidgetHost::set_rect(&mut t, 0.0, 0.0, 60.0, 30.0);
t.set_label("ON"); // the network.rs pattern: live label updates through Deref
let labels = t.own_text_labels();
assert_eq!(labels.len(), 1);
diff --git a/src/widget/input/dropdown.rs b/src/widget/input/dropdown.rs
index bc917d4..388db80 100644
--- a/src/widget/input/dropdown.rs
+++ b/src/widget/input/dropdown.rs
@@ -5,7 +5,7 @@
//!
//! Parity notes (all legacy-faithful, verified against the pre-migration impl):
//! - `parent_snapshot` is the data form of the legacy public, direct-write-only `parent`
-//! pointer: legacy `set_parent` never wrote it (the Element default only touched the tree —
+//! pointer: legacy `set_parent` never wrote it (the WidgetHost default only touched the tree —
//! Ramp's dummy-ctx `set_parent` calls were silently discarded), so the Ramp popover clamp
//! and the fade-blend parent color activate only for callers that assign the field, exactly
//! as before — no production writer exists. The backplate-concentric corner walk it once
@@ -13,14 +13,14 @@
//! - The row-rect hit expansion (`base.row_x/row_w`) is dropped, consistent with every other
//! migrated control: `Input::hit` tests the widget rect plus the open popover.
//! - `Layout::intrinsic_measure_width` (new hook) preserves the `auto_width` measure behavior
-//! (cce-system-settings sizes its page dropdown from `Element::measure`).
+//! (cce-system-settings sizes its page dropdown from `WidgetHost::measure`).
use crate::colors;
use crate::scene::layout::{Rect, Size};
use crate::scene::paint::PaintCtx;
use crate::widget::model::{Adapted, EventCtx, Input, Layout, Paint};
use crate::widget::{
- Control, Element, ElementState, Event, Key, MouseButton, NamedKey,
+ Control, WidgetHost, ElementState, Event, Key, MouseButton, NamedKey,
};
/// Read-data stand-in for the legacy direct-write `parent` pointer (6bd — no stored widget
@@ -34,7 +34,7 @@ pub struct ParentSnapshot {
pub color: [f32; 4],
}
-/// Side-layout label inset — the legacy `Element::label_x_offset` default for non-exempt
+/// Side-layout label inset — the legacy `WidgetHost::label_x_offset` default for non-exempt
/// widgets (Dropdown was never in the exempt list).
fn side_offset(label: &Option<String>) -> f32 {
if crate::layout::control_label_layout() == "side" && label.is_some() {
@@ -519,7 +519,7 @@ impl Adapted<Dropdown> {
/// Popover geometry from the widget's laid-out rect — the legacy inherent
/// `get_popover_geom` shape, for callers that hold the wrapper.
pub fn get_popover_geom(&self) -> (f32, f32, f32, f32) {
- let (x, y, w, h) = Element::rect(self);
+ let (x, y, w, h) = WidgetHost::rect(self);
let top = self.inner().label_top();
self.inner().popover_geom(Rect { x, y: y + top, width: w, height: h - top })
}
@@ -936,9 +936,9 @@ mod tests {
// Link the dropdown to the Ramp's read-data (the legacy direct-write path)
dd.parent_snapshot = Some(ParentSnapshot {
- rect: crate::widget::Element::rect(&ramp),
+ rect: crate::widget::WidgetHost::rect(&ramp),
is_ramp: true,
- color: crate::widget::Element::color(&ramp),
+ color: crate::widget::WidgetHost::color(&ramp),
});
// Compute geometry
@@ -1008,7 +1008,7 @@ mod tests {
);
}
- /// Migration additions: popover routing through the adapter (`Element::popover_rect` /
+ /// Migration additions: popover routing through the adapter (`WidgetHost::popover_rect` /
/// `render_popover`), outside-press close, and Escape via routed key events.
#[test]
fn popover_reaches_hosts_through_the_adapter() {
@@ -1017,11 +1017,11 @@ mod tests {
let mut dd = Dropdown::new(options, 0);
dd.set_rect(10.0, 10.0, 100.0, 24.0);
- assert!(Element::popover_rect(&dd).is_none(), "closed dropdown registers no popover");
+ assert!(WidgetHost::popover_rect(&dd).is_none(), "closed dropdown registers no popover");
dd.mouse_input(MouseButton::Left, ElementState::Pressed, 50.0, 20.0, &mut dummy);
assert!(dd.open);
- let (rx, ry, rw, rh) = Element::popover_rect(&dd).expect("open dropdown registers its popover");
+ let (rx, ry, rw, rh) = WidgetHost::popover_rect(&dd).expect("open dropdown registers its popover");
assert_eq!((rx, ry), (10.0, 34.0), "popover opens under the trigger");
assert!(rw >= 100.0 && rh == 48.0);
diff --git a/src/widget/input/slider.rs b/src/widget/input/slider.rs
index e3bbdc7..99b4c1c 100644
--- a/src/widget/input/slider.rs
+++ b/src/widget/input/slider.rs
@@ -688,50 +688,50 @@ impl Control for Adapted<RangeSlider> {
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::{Element, UiContext};
+ use crate::widget::{WidgetHost, UiContext};
- /// The legacy rangeslider interaction test, driven through the Element drag forwards
+ /// The legacy rangeslider interaction test, driven through the WidgetHost drag forwards
/// (hosts call these directly): thumb selection by proximity, constrained updates.
#[test]
fn rangeslider_interaction() {
let mut rs = RangeSlider::new();
- Element::set_rect(&mut rs, 10.0, 10.0, 200.0, 20.0);
+ WidgetHost::set_rect(&mut rs, 10.0, 10.0, 200.0, 20.0);
assert_eq!(rs.values(), (0.2, 0.8));
// Thumb size 18, range 182; low center = 55.4.
- Element::drag_begin(&mut rs, 55.4, 20.0);
+ WidgetHost::drag_begin(&mut rs, 55.4, 20.0);
assert_eq!(rs.active_thumb, Some(ActiveThumb::Low));
- assert!(Element::drag_update(&mut rs, 100.9, 20.0));
+ assert!(WidgetHost::drag_update(&mut rs, 100.9, 20.0));
assert!((rs.values().0 - 0.45).abs() < 0.01);
assert_eq!(rs.values().1, 0.8);
- Element::drag_end(&mut rs);
+ WidgetHost::drag_end(&mut rs);
assert_eq!(rs.active_thumb, None);
// High thumb 0.8 -> 0.6.
- Element::drag_begin(&mut rs, 164.6, 20.0);
+ WidgetHost::drag_begin(&mut rs, 164.6, 20.0);
assert_eq!(rs.active_thumb, Some(ActiveThumb::High));
- assert!(Element::drag_update(&mut rs, 128.2, 20.0));
+ assert!(WidgetHost::drag_update(&mut rs, 128.2, 20.0));
assert!((rs.values().1 - 0.6).abs() < 0.01);
- Element::drag_end(&mut rs);
+ WidgetHost::drag_end(&mut rs);
}
#[test]
fn rangeslider_overlap_and_constraint() {
let mut rs = RangeSlider::new().with_values(0.5, 0.5);
- Element::set_rect(&mut rs, 10.0, 10.0, 200.0, 20.0);
+ WidgetHost::set_rect(&mut rs, 10.0, 10.0, 200.0, 20.0);
- Element::drag_begin(&mut rs, 109.0, 20.0);
+ WidgetHost::drag_begin(&mut rs, 109.0, 20.0);
assert_eq!(rs.active_thumb, Some(ActiveThumb::Low));
- Element::drag_end(&mut rs);
+ WidgetHost::drag_end(&mut rs);
- Element::drag_begin(&mut rs, 111.0, 20.0);
+ WidgetHost::drag_begin(&mut rs, 111.0, 20.0);
assert_eq!(rs.active_thumb, Some(ActiveThumb::High));
- Element::drag_end(&mut rs);
+ WidgetHost::drag_end(&mut rs);
- Element::drag_begin(&mut rs, 110.0, 20.0);
- Element::drag_update(&mut rs, 150.0, 20.0);
+ WidgetHost::drag_begin(&mut rs, 110.0, 20.0);
+ WidgetHost::drag_update(&mut rs, 150.0, 20.0);
assert_eq!(rs.values().0, 0.5, "low constrained to high");
- Element::drag_end(&mut rs);
+ WidgetHost::drag_end(&mut rs);
}
#[test]
@@ -740,10 +740,10 @@ fn probe_slider_bridge() {
let ctx = UiContext::new();
let mut sl = Slider::new().with_label("Slider");
- Element::set_rect(&mut sl, 20.0, 220.0, 200.0, 40.0);
- eprintln!("rect = {:?}", Element::rect(&sl));
- eprintln!("extra_quads = {:?}", Element::extra_quads(&sl));
- eprintln!("rounded = {:?}", Element::all_rounded_quads(&sl, &ctx));
+ WidgetHost::set_rect(&mut sl, 20.0, 220.0, 200.0, 40.0);
+ eprintln!("rect = {:?}", WidgetHost::rect(&sl));
+ eprintln!("extra_quads = {:?}", WidgetHost::extra_quads(&sl));
+ eprintln!("rounded = {:?}", WidgetHost::all_rounded_quads(&sl, &ctx));
eprintln!("labels = {:?}", sl.own_text_labels().iter().map(|l| l.text.clone()).collect::<Vec<_>>());
}
@@ -755,22 +755,22 @@ fn probe_slider_bridge() {
let mut sl = Slider::new().with_value(0.5);
let (id, ptr) = (sl.id(), sl.as_ptr_mut());
ctx.register_widget(id, ptr);
- Element::set_rect(&mut sl, 0.0, 0.0, 100.0, 20.0);
+ WidgetHost::set_rect(&mut sl, 0.0, 0.0, 100.0, 20.0);
// Press on the track grabs the thumb.
assert!(ctx.propagate_event(
&Event::MouseButton { button: MouseButton::Left, state: ElementState::Pressed, x: 50.0, y: 10.0, local_x: 50.0, local_y: 10.0 },
ptr,
));
- assert!(Element::is_dragging(&sl));
- assert!(Element::drag_update(&mut sl, 80.0, 10.0));
+ assert!(WidgetHost::is_dragging(&sl));
+ assert!(WidgetHost::drag_update(&mut sl, 80.0, 10.0));
assert!(sl.inner().value() > 0.5);
- Element::drag_end(&mut sl);
+ WidgetHost::drag_end(&mut sl);
// Wheel adjusts value when the gesture starts fresh.
ctx.scroll_gesture_new = true;
let before = sl.inner().value();
- assert!(Element::mouse_wheel(
+ assert!(WidgetHost::mouse_wheel(
&mut sl,
&MouseScrollDelta::LineDelta(0.0, 1.0),
50.0,
@@ -778,6 +778,6 @@ fn probe_slider_bridge() {
&mut ctx,
));
assert!(sl.inner().value() < before, "scroll up decreases value");
- assert!(Element::take_change(&mut sl));
+ assert!(WidgetHost::take_change(&mut sl));
}
}
diff --git a/src/widget/input/spinbox.rs b/src/widget/input/spinbox.rs
index 30549cf..023c254 100644
--- a/src/widget/input/spinbox.rs
+++ b/src/widget/input/spinbox.rs
@@ -440,7 +440,7 @@ impl Control for Adapted<Spinbox> {
#[cfg(test)]
mod tests {
use super::*;
- use crate::widget::{Element, UiContext};
+ use crate::widget::{WidgetHost, UiContext};
#[test]
fn spinbox_button_zones_step_the_value() {
@@ -448,24 +448,24 @@ mod tests {
let mut sb = Spinbox::new(0, -100, 100, 1);
let (id, ptr) = (sb.id(), sb.as_ptr_mut());
ctx.register_widget(id, ptr);
- Element::set_rect(&mut sb, 10.0, 20.0, 100.0, 26.0);
+ WidgetHost::set_rect(&mut sb, 10.0, 20.0, 100.0, 26.0);
// Legacy test: click at (75, 33) lands in the decrement zone.
- assert!(Element::mouse_input(&mut sb, MouseButton::Left, ElementState::Pressed, 75.0, 33.0, &mut ctx));
+ assert!(WidgetHost::mouse_input(&mut sb, MouseButton::Left, ElementState::Pressed, 75.0, 33.0, &mut ctx));
assert_eq!(sb.value, -1);
- assert!(Element::take_change(&mut sb));
+ assert!(WidgetHost::take_change(&mut sb));
// Increment zone (past 77.5% of the width).
- assert!(Element::mouse_input(&mut sb, MouseButton::Left, ElementState::Pressed, 92.0, 33.0, &mut ctx));
+ assert!(WidgetHost::mouse_input(&mut sb, MouseButton::Left, ElementState::Pressed, 92.0, 33.0, &mut ctx));
assert_eq!(sb.value, 0);
}
#[test]
fn spinbox_value_string_decimals_round_trip() {
let mut sb = Spinbox::new(150, 0, 1000, 5).with_decimals(2);
- assert_eq!(Element::get_value_string(&sb), Some("1.50".to_string()));
- assert!(Element::set_value_string(&mut sb, "2.75"));
+ assert_eq!(WidgetHost::get_value_string(&sb), Some("1.50".to_string()));
+ assert!(WidgetHost::set_value_string(&mut sb, "2.75"));
assert_eq!(sb.value, 275);
- assert_eq!(Element::value(&sb), 275);
+ assert_eq!(WidgetHost::value(&sb), 275);
}
}
diff --git a/src/widget/input/text_box.rs b/src/widget/input/text_box.rs
index 7b0987e..2963b98 100644
--- a/src/widget/input/text_box.rs
+++ b/src/widget/input/text_box.rs
@@ -1,6 +1,6 @@
//! Narrow-trait `TextBox` (Phase 5q). The widest-surface leaf so far: real selection-aware
//! clipboard (the new `Input` cut/copy/paste/select-all/clear hooks — their defaults replicate
-//! the whole-value `Element` defaults for everyone else), load-bearing glyph shaping through
+//! the whole-value `WidgetHost` defaults for everyone else), load-bearing glyph shaping through
//! `Paint::prepare_text` (cursor↔pixel mapping reads the measured advances), the row-hit
//! restoration (`Layout::hit_row_rect` — cce-files' save-name box relies on row hits), a
//! width/max-width clamp on both rect paths (`Layout::adjust_rect` + `adjust_row_rect`), the
@@ -35,7 +35,7 @@ pub fn get_font_db() -> &'static resvg::usvg::fontdb::Database {
})
}
-/// Side-layout label inset — the legacy `Element::label_x_offset` default for non-exempt
+/// Side-layout label inset — the legacy `WidgetHost::label_x_offset` default for non-exempt
/// widgets (TextBox was never in the exempt list).
fn side_offset(label: &Option<String>) -> f32 {
if crate::layout::control_label_layout() == "side" && label.is_some() {
@@ -1644,7 +1644,7 @@ mod tests {
tb.select_anchor = Some(7); // starts at "Line 2"
tb.cursor_idx = 13; // ends at end of "Line 2"
- let has_rounded = Element::corner_style(&tb).1 != (false, false, false, false);
+ let has_rounded = WidgetHost::corner_style(&tb).1 != (false, false, false, false);
let has_highlight = if has_rounded {
let rounded = tb.all_rounded_quads(&dummy);
println!("Rounded quads: {:?}", rounded);
@@ -1694,7 +1694,7 @@ mod tests {
assert!(opts.contains(&"Cear".to_string()));
// Simulate choosing the "Cear" option
- Element::context_action(&mut tb, crate::widget::ContextAction::ClearText);
+ WidgetHost::context_action(&mut tb, crate::widget::ContextAction::ClearText);
assert_eq!(tb.text, "");
assert_eq!(tb.edit_buffer, "");
}
diff --git a/src/widget/layout_helper.rs b/src/widget/layout_helper.rs
index 21b5629..d29eb08 100644
--- a/src/widget/layout_helper.rs
+++ b/src/widget/layout_helper.rs
@@ -1,4 +1,4 @@
-use crate::widget::Element;
+use crate::widget::WidgetHost;
pub struct ColumnLayout {
pub x: f32,
@@ -21,14 +21,14 @@ impl ColumnLayout {
}
}
- pub fn add_widget(&mut self, widget: &mut dyn Element, height: f32) {
+ pub fn add_widget(&mut self, widget: &mut dyn WidgetHost, height: f32) {
let label_off = widget.base().label_offset();
let total_h = height + label_off;
widget.set_rect(self.x + self.margin, self.current_y, self.width - 2.0 * self.margin, height);
self.current_y += total_h + self.gap;
}
- pub fn add_row(&mut self, widgets: &[*mut dyn Element], height: f32, gap: f32) {
+ pub fn add_row(&mut self, widgets: &[*mut dyn WidgetHost], height: f32, gap: f32) {
let count = widgets.len();
if count == 0 {
return;
@@ -81,7 +81,7 @@ impl RowLayout {
}
}
- pub fn add_widget(&mut self, widget: &mut dyn Element, width: f32) {
+ pub fn add_widget(&mut self, widget: &mut dyn WidgetHost, width: f32) {
widget.set_rect(self.current_x, self.y + self.margin, width, self.height - 2.0 * self.margin);
self.current_x += width + self.gap;
}
diff --git a/src/widget/mod.rs b/src/widget/mod.rs
index b13c842..9484c36 100644
--- a/src/widget/mod.rs
+++ b/src/widget/mod.rs
@@ -76,7 +76,7 @@ pub enum Justification {
}
/// A context-menu action dispatched on the menu's target widget (6bd phase 1: one enum
-/// replaces the 13 per-action `Element` methods). `ClearText` is the search-box "Cear" item.
+/// replaces the 13 per-action `WidgetHost` methods). `ClearText` is the search-box "Cear" item.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ContextAction {
Cut,
@@ -112,19 +112,19 @@ pub struct LayoutTree {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct WidgetPtr(pub *mut (dyn Element + 'static));
+pub struct WidgetPtr(pub *mut (dyn WidgetHost + 'static));
impl WidgetPtr {
pub fn is_null(&self) -> bool {
self.0.is_null()
}
- pub fn as_ptr(&self) -> *mut (dyn Element + 'static) {
+ pub fn as_ptr(&self) -> *mut (dyn WidgetHost + 'static) {
self.0
}
}
impl std::ops::Deref for WidgetPtr {
- type Target = dyn Element + 'static;
+ type Target = dyn WidgetHost + 'static;
fn deref(&self) -> &Self::Target {
assert!(!self.0.is_null(), "Attempted to dereference a null WidgetPtr!");
unsafe { &*self.0 }
@@ -187,7 +187,13 @@ pub struct Size {
pub height: f32,
}
-pub trait Element {
+/// The single host surface every widget presents to the machinery (context routing, the
+/// paint walk, the render loop, app dyn broadcasts). **Formerly `Element`**, the ~125-method
+/// god-trait — renamed at the 6bd flip once census-driven shrink batches brought it down to
+/// the measured blueprint. `Adapted<W>` is the one production implementor; concrete behavior
+/// lives on the narrow `Layout`/`Paint`/`Input` traits it wraps. The direct-dispatch and
+/// value blocks shrink further as apps move to routed events / concrete slots.
+pub trait WidgetHost {
/// The widget's shared base state — GUARANTEED (the flip): the `Option` escape hatch
/// and its `WidgetId(0)` sentinel class are gone. `Adapted` (the one production
/// implementor) always owns a base; test shims carry one via `impl_widget_base!`.
@@ -214,8 +220,8 @@ pub trait Element {
// stand-ins nothing could legitimately use. `impl_widget_base!` provides all four.
fn as_any(&self) -> &dyn std::any::Any;
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
- fn as_ptr(&self) -> *mut (dyn Element + 'static);
- fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static);
+ fn as_ptr(&self) -> *mut (dyn WidgetHost + 'static);
+ fn as_ptr_mut(&mut self) -> *mut (dyn WidgetHost + 'static);
fn handle_event(&mut self, event: &Event, ctx: &mut UiContext) -> bool {
match event {
@@ -518,7 +524,7 @@ pub trait Element {
fn is_child_visible(&self, _child_id: WidgetId) -> bool { true }
fn set_modifiers(&mut self, _ctrl: bool, _shift: bool, _alt: bool) {}
- fn parent(&self, ctx: &UiContext) -> Option<*mut (dyn Element + 'static)> {
+ fn parent(&self, ctx: &UiContext) -> Option<*mut (dyn WidgetHost + 'static)> {
ctx.tree.parent_ptr(self.base().id())
}
@@ -527,7 +533,7 @@ pub trait Element {
// operation — concrete callers ride the inherent `Adapted` methods, dyn callers go
// through `focus::link_parent_child` or `ctx.tree` directly.
- fn children(&self, ctx: &UiContext) -> Vec<*mut (dyn Element + 'static)> {
+ fn children(&self, ctx: &UiContext) -> Vec<*mut (dyn WidgetHost + 'static)> {
ctx.tree.children_ptrs(self.base().id())
}
@@ -554,7 +560,7 @@ pub trait Element {
}
}
-pub trait Control: Element {
+pub trait Control: WidgetHost {
fn set_label(&mut self, label: &str) {
self.base_mut().label = Some(label.to_string());
}
@@ -690,7 +696,7 @@ pub trait GeomController {
fn take_geom_toggle(&mut self) -> bool;
}
-pub fn label_offset(w: &dyn Element) -> f32 {
+pub fn label_offset(w: &dyn WidgetHost) -> f32 {
let name = w.type_name();
if name == "Label" || name == "Button" || name == "Checkbox" || name == "Toggle" {
return 0.0;
diff --git a/src/widget/model.rs b/src/widget/model.rs
index 7e5708b..22a14d7 100644
--- a/src/widget/model.rs
+++ b/src/widget/model.rs
@@ -1,26 +1,26 @@
-//! Narrow, single-concern widget traits + an adapter into the legacy `Element` tree — Phase 5 of
+//! Narrow, single-concern widget traits + an adapter into the legacy `WidgetHost` tree — Phase 5 of
//! the core rebuild (see `docs/rfc-core-rebuild.md` §3.5 and §5).
//!
-//! Phase 5 replaces the ~123-method [`Element`] god-trait with small traits, one per concern. A
-//! *non-breaking supertrait carve-out* of `Element` is not possible in Rust, for two reasons found
+//! Phase 5 replaces the ~123-method [`WidgetHost`] god-trait with small traits, one per concern. A
+//! *non-breaking supertrait carve-out* of `WidgetHost` is not possible in Rust, for two reasons found
//! by experiment:
//!
//! 1. The structural methods the layout/paint passes need (`rect`, `children`, `set_rect`, …) are
//! overridden in dozens of widgets across cce-ui **and** the app crates. Moving them off
-//! `Element` breaks every override; merely *declaring* them on a supertrait breaks every call
+//! `WidgetHost` breaks every override; merely *declaring* them on a supertrait breaks every call
//! site too, because a supertrait method is always in scope on the subtrait — `elem.children()`
-//! on a `&dyn Element` becomes ambiguous.
+//! on a `&dyn WidgetHost` becomes ambiguous.
//! 2. Trait-object coercion does not offer a way around it: a blanket "view" impl
-//! `impl<T: Element> Paint for T` does **not** let `&dyn Element` coerce to `&dyn Paint`
+//! `impl<T: WidgetHost> Paint for T` does **not** let `&dyn WidgetHost` coerce to `&dyn Paint`
//! (that coercion only exists for real supertraits).
//!
//! So we take the RFC's recommended **adapter** path. The traits here — [`Layout`] and [`Paint`] —
-//! are *independent* of `Element` (no super/sub relationship). A widget written against them is
-//! placed into the existing `*mut dyn Element` tree by wrapping it in [`Adapted`], whose `Element`
+//! are *independent* of `WidgetHost` (no super/sub relationship). A widget written against them is
+//! placed into the existing `*mut dyn WidgetHost` tree by wrapping it in [`Adapted`], whose `WidgetHost`
//! impl forwards each legacy method to the matching narrow-trait method and supplies the
-//! [`Widget`] base that `Element`'s rect/id/dirty machinery reads. Existing `impl Element` widgets
+//! [`Widget`] base that `WidgetHost`'s rect/id/dirty machinery reads. Existing `impl WidgetHost` widgets
//! are untouched; new or migrated widgets implement only the concern traits they need; both kinds
-//! coexist in one tree. When the last widget is migrated, `Element` and this adapter are deleted.
+//! coexist in one tree. When the last widget is migrated, `WidgetHost` and this adapter are deleted.
//!
//! This commit lands the two concerns the scene passes already consume: [`Layout`] drives
//! [`crate::scene::bridge`] and [`Paint`] drives [`crate::scene::painter`]. The input/event
@@ -29,7 +29,7 @@
use crate::scene::layout::{Rect, Size};
use crate::scene::paint::{PaintCtx, Prim};
use crate::widget::{
- Element, Event, TextLabel, UiContext, Widget, WidgetId,
+ WidgetHost, Event, TextLabel, UiContext, Widget, WidgetId,
};
/// Layout inputs for the scene layout engine — the RFC's `Widget` concern, named `Layout` here to
@@ -63,24 +63,24 @@ pub trait Layout {
0.0
}
- /// Whether `Element::measure` should prefer [`intrinsic_size`](Layout::intrinsic_size)'s
+ /// Whether `WidgetHost::measure` should prefer [`intrinsic_size`](Layout::intrinsic_size)'s
/// width over the current rect width (Dropdown's `auto_width` measure override — hosts size
/// it from `measure`, e.g. cce-system-settings' page dropdown). Default: keep the legacy
- /// `Element::measure` width (the current rect's).
+ /// `WidgetHost::measure` width (the current rect's).
fn intrinsic_measure_width(&self) -> bool {
false
}
/// Whether the adapter's hit test substitutes the base row rect (`row_x`/`row_w`, pushed in
/// by row-layout hosts via `set_row_rect`) plus the side-label inset — the legacy
- /// `Element::hit_test` default geometry. Migrated controls so far dropped it (accepted
+ /// `WidgetHost::hit_test` default geometry. Migrated controls so far dropped it (accepted
/// drift); TextBox restores it (cce-files' save-name box relies on row hits). Default: off,
/// keeping the other migrated widgets exactly as they shipped.
fn hit_row_rect(&self) -> bool {
false
}
- /// Adjust a row-rect assignment before it lands on the base (`Element::set_row_rect` —
+ /// Adjust a row-rect assignment before it lands on the base (`WidgetHost::set_row_rect` —
/// TextBox clamps the row width to its `width`/`max_width`). Default: identity.
fn adjust_row_rect(&self, x: f32, w: f32) -> (f32, f32) {
(x, w)
@@ -92,14 +92,14 @@ pub trait Layout {
/// re-clamps its scroll, the legacy `set_rect` side effect. Default: ignore.
fn rect_assigned(&mut self, _rect: Rect) {}
- // --- Container concern (transitional). Legacy containers own `Vec<*mut dyn Element>`
+ // --- Container concern (transitional). Legacy containers own `Vec<*mut dyn WidgetHost>`
// children (child-arranging `set_rect` has no ctx to reach the tree) and every one
// hand-copies the same subtree plumbing: geometry/text aggregation, tick/popover/text-item
// recursion, hit-through-children. A migrated container keeps the pointer Vec in its model
// (exposed through these hooks) and the ADAPTER does the shared plumbing once, filtered by
// `child_visible`. What stays per-widget: child arrangement (`arrange_children` /
// `layout_children_ctx`) and any event proxying (in `on_event`, via `EventCtx::ui`).
- // Dies with `Element`: the arena owns the tree and the scene walk owns recursion.
+ // Dies with `WidgetHost`: the arena owns the tree and the scene walk owns recursion.
/// Whether this widget is a container serving
/// [`container_children`](Layout::container_children). Cheap gate, checked per getter.
@@ -108,7 +108,7 @@ pub trait Layout {
}
/// The container's child pointers, in stacking order.
- fn container_children(&self) -> Vec<*mut (dyn Element + 'static)> {
+ fn container_children(&self) -> Vec<*mut (dyn WidgetHost + 'static)> {
Vec::new()
}
@@ -120,17 +120,17 @@ pub trait Layout {
/// Position children after a `set_rect` (no ctx available — use the owned pointers).
/// Called only while the widget is visible, matching the legacy overrides. `host` is the
- /// adapter's `*mut dyn Element` — widgets that embed a legacy child (MenuBar's
+ /// adapter's `*mut dyn WidgetHost` — widgets that embed a legacy child (MenuBar's
/// ButtonStrip) parent it back to the host so legacy parent-chain styling walks work.
- fn arrange_children(&mut self, _rect: Rect, _host: *mut (dyn Element + 'static)) {}
+ fn arrange_children(&mut self, _rect: Rect, _host: *mut (dyn WidgetHost + 'static)) {}
/// Per-child visibility policy for the adapter's subtree plumbing (Switcher exposes only
/// the active child). Default: every child.
- fn child_visible(&self, _child: *mut (dyn Element + 'static)) -> bool {
+ fn child_visible(&self, _child: *mut (dyn WidgetHost + 'static)) -> bool {
true
}
- /// Legacy `Element::z_index` (host render ordering; MenuBar's dropdowns layer at 100+).
+ /// Legacy `WidgetHost::z_index` (host render ordering; MenuBar's dropdowns layer at 100+).
fn z_order(&self) -> i32 {
0
}
@@ -141,13 +141,13 @@ pub trait Layout {
/// `Vec` reallocation) — and the registration is load-bearing: the spatial grid is rebuilt
/// from registered widgets, and it is the registered ButtonStrip (whose
/// `blocks_backplate_drag` is true) that makes the sidebar block backplate drags. The
- /// adapter calls this from `Element::tick` and `Element::layout`, mirroring the legacy
+ /// adapter calls this from `WidgetHost::tick` and `WidgetHost::layout`, mirroring the legacy
/// cadence. `host_id` is the adapter's id, for `link_ids`. Default: nothing embedded.
fn register_embedded_children(&mut self, _host_id: WidgetId, _ctx: &mut UiContext) {}
}
/// The paint concern — a widget's fill color, its own (non-recursive) geometry emission, and
-/// whether it clips its children. Mirrors `Element::color` / `paint_self` / `clips_children`, but
+/// whether it clips its children. Mirrors `WidgetHost::color` / `paint_self` / `clips_children`, but
/// [`paint`](Paint::paint) receives the laid-out `rect` as a parameter (the RFC shape) rather than
/// reading a stored rect, so a narrow widget carries no base of its own.
pub trait Paint {
@@ -175,7 +175,7 @@ pub trait Paint {
/// laid-out rect (MenuBar's corners depend on where it sits against its parent's edges).
/// **Transitional:** this exists only for legacy render paths that draw widget backgrounds
/// themselves from style properties (`widget_vertices` / `push_widget_vertices` readers of
- /// `Element::corner_radius` + `rounded_corners`) — the widget's real geometry is whatever
+ /// `WidgetHost::corner_radius` + `rounded_corners`) — the widget's real geometry is whatever
/// [`paint`](Paint::paint) emits. Dies with those paths. Default: sharp corners.
fn corner_style(&self, _rect: Rect) -> Option<(f32, (bool, bool, bool, bool))> {
None
@@ -188,7 +188,7 @@ pub trait Paint {
None
}
- /// Draw this widget's own popover (legacy `Element::render_popover`).
+ /// Draw this widget's own popover (legacy `WidgetHost::render_popover`).
fn draw_popover(&self, _rect: Rect, _pc: &mut dyn crate::layout::RenderTarget) {}
/// Solid border `(color, thickness)` of the widget's background quad. **Transitional**, like
@@ -199,7 +199,7 @@ pub trait Paint {
}
/// Font for this widget's text on legacy text paths (`render_widget` reads
- /// `Element::widget_font`). **Transitional.**
+ /// `WidgetHost::widget_font`). **Transitional.**
fn widget_font(&self) -> Option<String> {
None
}
@@ -228,7 +228,7 @@ pub trait Paint {
// getters. A migrated widget emits the rounded view from `paint`; when it also serves a
// plain view, the adapter returns it verbatim from `extra_quads` and empties `all_quads`
// (mirroring legacy Graph's highlight-only override) so render_widget-style hosts that
- // read BOTH getters never draw the geometry twice. Dies with `Element`.
+ // read BOTH getters never draw the geometry twice. Dies with `WidgetHost`.
/// Whether this widget serves [`legacy_plain_quads`](Paint::legacy_plain_quads).
fn serves_legacy_plain_quads(&self) -> bool {
@@ -248,7 +248,7 @@ pub trait Paint {
None
}
- /// Per-frame text shaping against the app's `FontSystem` (legacy `Element::prepare_text`
+ /// Per-frame text shaping against the app's `FontSystem` (legacy `WidgetHost::prepare_text`
/// overrides). TextBox measures its glyph advances here — load-bearing for cursor↔pixel
/// mapping, not just a render cache. Receives the laid-out content rect. Default: nothing
/// to shape.
@@ -256,7 +256,7 @@ pub trait Paint {
/// Whether [`paint`](Paint::paint) emits the widget's ENTIRE subtree, so the paint walk
/// must not also descend into its (ctx-linked) children — the legacy
- /// `Element::renders_own_subtree` contract. TreeList: its field widgets stay ctx-linked
+ /// `WidgetHost::renders_own_subtree` contract. TreeList: its field widgets stay ctx-linked
/// for event propagation, but their pixels come from `paint`'s own child pass (which
/// gates the add-key popover box on the popover actually being open).
fn paints_own_subtree(&self) -> bool {
@@ -265,7 +265,7 @@ pub trait Paint {
/// Whether the adapter re-enables the legacy shared focus/hover highlight overlay
- /// (`Element::highlight_quad`'s default) for this widget. The adapter suppresses it for
+ /// (`WidgetHost::highlight_quad`'s default) for this widget. The adapter suppresses it for
/// migrated widgets — matching the `None` overrides most legacy controls carried — but
/// legacy TextBox kept the default: the focused editor gets the primary-highlight tint
/// over its background (data-editor's teal editing wash). Default: suppressed.
@@ -284,7 +284,7 @@ pub trait Paint {
false
}
- /// Forward the legacy `Element::highlight_quad` to somewhere else entirely — Paginator
+ /// Forward the legacy `WidgetHost::highlight_quad` to somewhere else entirely — Paginator
/// served its ButtonStrip's highlight (the hovered-tab tint cce-layout-interface draws by
/// calling `highlight_quad` directly). Outer `Some` replaces the adapter's highlight logic
/// with the inner value; `None` (default) keeps the standard behavior
@@ -332,7 +332,7 @@ pub struct EventCtx<'a> {
/// The routing context, when routed. **Transitional** — narrow widgets should only touch the
/// legacy shared fields (scroll gesture state) until those get typed helpers here.
pub ui: Option<&'a mut UiContext>,
- self_ptr: Option<*mut (dyn Element + 'static)>,
+ self_ptr: Option<*mut (dyn WidgetHost + 'static)>,
}
impl EventCtx<'_> {
@@ -365,14 +365,14 @@ impl EventCtx<'_> {
/// The adapter's pointer, for legacy sites that must hand it onward — TreeList makes
/// itself the focus target (`set_focused_ptr`) and the context-menu target
/// (`show_context_menu`) with the pointer hosts registered. Transitional; dies with
- /// `Element`. None outside a routed path.
- pub(crate) fn host_ptr(&self) -> Option<*mut (dyn Element + 'static)> {
+ /// `WidgetHost`. None outside a routed path.
+ pub(crate) fn host_ptr(&self) -> Option<*mut (dyn WidgetHost + 'static)> {
self.self_ptr
}
}
/// The input concern — hit-testing and event handling against the laid-out rect. Mirrors the
-/// legacy `Element::hit_test` / `handle_event` pair, but with the RFC's centralizations: the
+/// legacy `WidgetHost::hit_test` / `handle_event` pair, but with the RFC's centralizations: the
/// default hit is plain rect containment (no per-widget address hacks), and pointer-positioned
/// events are hit-gated by the adapter *before* they reach [`on_event`](Input::on_event), so a
/// narrow widget never re-implements the "am I actually under the cursor?" boilerplate that every
@@ -396,7 +396,7 @@ pub trait Input {
/// Whether pressing on this widget blocks dragging the movable backplate under it. Passive
/// display widgets (separators, status dots) return `false` so drags pass through them.
- /// Default: `true`, matching the legacy `Element` default.
+ /// Default: `true`, matching the legacy `WidgetHost` default.
fn blocks_backplate_drag(&self) -> bool {
true
}
@@ -447,13 +447,13 @@ pub trait Input {
false
}
- /// The widget's value as an integer (legacy `Element::value`).
+ /// The widget's value as an integer (legacy `WidgetHost::value`).
fn value(&self) -> i32 {
0
}
// --- Clipboard/selection surface (the context menu's Cut/Copy/Paste/Select-All actions
- // call these on their target Element). The defaults replicate the `Element` defaults
+ // call these on their target WidgetHost). The defaults replicate the `WidgetHost` defaults
// byte-for-byte (whole-value copy through the value-string pair), so widgets migrated
// before these hooks existed keep their exact behavior; TextBox overrides with real
// selection-aware implementations.
@@ -495,7 +495,7 @@ pub trait Input {
true
}
- /// Selection state pushed in by list/row hosts (legacy `Element::set_selected`).
+ /// Selection state pushed in by list/row hosts (legacy `WidgetHost::set_selected`).
fn set_selected(&mut self, _selected: bool) {}
// --- Drag surface: legacy hosts (designer, control_panel, parameters_bg, graph, audio…)
@@ -523,7 +523,7 @@ pub trait Input {
/// Movement bounds pushed in by hosts (reached via the inherent `Adapted::set_drag_bounds`).
fn set_drag_bounds(&mut self, _bx: f32, _by: f32, _bw: f32, _bh: f32) {}
- // --- Tick surface: hosts broadcast `Element::tick(dt)` every frame (the designer's render
+ // --- Tick surface: hosts broadcast `WidgetHost::tick(dt)` every frame (the designer's render
// loop) to advance time-based widget state — inertial scroll velocity, here. Transitional:
// §3.6 `Animated<T>` + arena-driven frame requests replace hand-ticked state.
@@ -542,35 +542,35 @@ pub trait Input {
}
/// Whether this widget wants `tick` calls from tick-gating hosts (legacy
- /// `Element::wants_tick`; the designer ticks unconditionally and ignores this).
+ /// `WidgetHost::wants_tick`; the designer ticks unconditionally and ignores this).
fn wants_tick(&self) -> bool {
false
}
- /// Whether this widget consumes scroll gestures (legacy `Element::is_scrollable`, read by
+ /// Whether this widget consumes scroll gestures (legacy `WidgetHost::is_scrollable`, read by
/// the router's scroll-gesture gating).
fn scrollable(&self) -> bool {
false
}
// --- Controller capabilities (transitional, like the polling surface above). The legacy
- // tree reaches a widget's typed API through the `Element::as_*_controller` downcast pairs;
- // `Element` is implemented exactly once (for `Adapted<W>`), so a migrated controller widget
+ // tree reaches a widget's typed API through the `WidgetHost::as_*_controller` downcast pairs;
+ // `WidgetHost` is implemented exactly once (for `Adapted<W>`), so a migrated controller widget
// re-exposes its controller impl through these hooks instead — `Some(self)` when `W`
- // implements the trait. Dies with `Element`: the end state reaches a controller through the
+ // implements the trait. Dies with `WidgetHost`: the end state reaches a controller through the
// concrete `Adapted<W>` (or a `&dyn XController` held directly), per RFC §3.5.
/// Keyboard modifier state pushed in by hosts before dispatch (legacy
- /// `Element::set_modifiers`).
+ /// `WidgetHost::set_modifiers`).
fn set_modifiers(&mut self, _ctrl: bool, _shift: bool, _alt: bool) {}
- /// The widget's visibility flag changed through `Element::set_visible` (the adapter owns
+ /// The widget's visibility flag changed through `WidgetHost::set_visible` (the adapter owns
/// the flag) — legacy hideable widgets used the setter for side effects (MenuBar closes
/// its dropdowns and invalidates layout).
fn visibility_changed(&mut self, _visible: bool) {}
- /// The widget's `Element::focused` answer, given the base flag — MenuBar reports focused
+ /// The widget's `WidgetHost::focused` answer, given the base flag — MenuBar reports focused
/// while any of its dropdowns is open, beyond the flag itself. Default: the flag.
fn is_focused(&self, base_focused: bool) -> bool {
base_focused
@@ -578,20 +578,20 @@ pub trait Input {
}
-/// Wraps a narrow-trait widget `W` so it lives in the legacy `*mut dyn Element` tree. Carries the
-/// [`Widget`] base that `Element`'s rect / id / dirty machinery needs, and forwards the concern
+/// Wraps a narrow-trait widget `W` so it lives in the legacy `*mut dyn WidgetHost` tree. Carries the
+/// [`Widget`] base that `WidgetHost`'s rect / id / dirty machinery needs, and forwards the concern
/// methods to `W`. See the module docs for why this bridge exists rather than a supertrait split.
///
-/// The bounds live on the struct (not just the `Element` impl) so `Drop` can clear the global
-/// focus / context-menu references through `&dyn Element` — the same guard legacy widgets with
+/// The bounds live on the struct (not just the `WidgetHost` impl) so `Drop` can clear the global
+/// focus / context-menu references through `&dyn WidgetHost` — the same guard legacy widgets with
/// `Drop` impls (e.g. the old `Checkbox`) carried.
#[derive(Debug, Clone)]
pub struct Adapted<W: Layout + Paint + Input + 'static> {
base: Widget,
- /// The [`Widget`] base carries no visibility, and the legacy `Element` defaults are a no-op
+ /// The [`Widget`] base carries no visibility, and the legacy `WidgetHost` defaults are a no-op
/// `set_visible` + always-true `visible()` — every hideable legacy widget stores its own
/// flag. The adapter owns it once for all migrated widgets: hosts toggle panes through
- /// `Element::set_visible` (the designer), and the hit-test/render bridges gate on it.
+ /// `WidgetHost::set_visible` (the designer), and the hit-test/render bridges gate on it.
visible: bool,
inner: W,
}
@@ -677,22 +677,22 @@ impl<W: Layout + Paint + Input + 'static> Adapted<W> {
}
impl<W: Layout + Paint + Input + 'static> Adapted<W> {
- /// Movement bounds pushed in by hosts (off the `Element` trait since 6bd — the one
+ /// Movement bounds pushed in by hosts (off the `WidgetHost` trait since 6bd — the one
/// production caller is concrete: designer's network panel).
pub fn set_drag_bounds(&mut self, bx: f32, by: f32, bw: f32, bh: f32) {
Input::set_drag_bounds(&mut self.inner, bx, by, bw, bh)
}
- /// Unlink all tree children (off `Element` in 6bd batch 2 — every caller is a concrete
+ /// Unlink all tree children (off `WidgetHost` in 6bd batch 2 — every caller is a concrete
/// `Adapted` field).
pub fn clear_children(&mut self, ctx: &mut UiContext) {
ctx.clear_children_ids(self.base.id());
}
- /// Register + link a child under this widget (off `Element` in 6bd batch 4; dyn callers
+ /// Register + link a child under this widget (off `WidgetHost` in 6bd batch 4; dyn callers
/// went to `focus::link_parent_child`/tree ops).
- pub fn add_child(&mut self, child: *mut (dyn Element + 'static), ctx: &mut UiContext) {
- // The old Element default's tree link…
+ pub fn add_child(&mut self, child: *mut (dyn WidgetHost + 'static), ctx: &mut UiContext) {
+ // The old WidgetHost default's tree link…
let c_id = unsafe { (*child).base().id() };
let p_id = self.base.id();
let self_ptr = self.as_ptr();
@@ -709,9 +709,9 @@ impl<W: Layout + Paint + Input + 'static> Adapted<W> {
}
}
- /// Register + (un)link this widget under a parent (off `Element` in 6bd batch 4).
- pub fn set_parent(&mut self, parent: Option<*mut (dyn Element + 'static)>, ctx: &mut UiContext) {
- // Replica of the old Element default: symmetric tree link.
+ /// Register + (un)link this widget under a parent (off `WidgetHost` in 6bd batch 4).
+ pub fn set_parent(&mut self, parent: Option<*mut (dyn WidgetHost + 'static)>, ctx: &mut UiContext) {
+ // Replica of the old WidgetHost default: symmetric tree link.
let id = self.base.id();
if let Some(p_ptr) = parent {
let p_id = unsafe { (*p_ptr).base().id() };
@@ -724,7 +724,7 @@ impl<W: Layout + Paint + Input + 'static> Adapted<W> {
}
}
- /// The model's intrinsic content size (off the `Element` trait since 6bd — the concrete
+ /// The model's intrinsic content size (off the `WidgetHost` trait since 6bd — the concrete
/// callers are fonts'/graph's hand-laid button/dropdown sizing).
pub fn intrinsic_size(&self) -> Option<Size> {
Layout::intrinsic_size(&self.inner)
@@ -756,7 +756,7 @@ impl<W: Layout + Paint + Input + 'static> Adapted<W> {
/// The container's children that pass the [`Layout::child_visible`] policy — the set the
/// adapter's subtree plumbing (aggregation, recursion, hit-through) operates on. Empty for
/// non-containers.
- fn visible_children(&self) -> Vec<*mut (dyn Element + 'static)> {
+ fn visible_children(&self) -> Vec<*mut (dyn WidgetHost + 'static)> {
if !Layout::has_container_children(&self.inner) {
return Vec::new();
}
@@ -830,14 +830,14 @@ impl<W: Layout + Paint + Input + 'static> Adapted<W> {
}
/// The base-label text of a *detached*-label widget — a replica of the legacy default
- /// `Element::text_labels` body (which an overriding impl can no longer call).
+ /// `WidgetHost::text_labels` body (which an overriding impl can no longer call).
fn base_label_fallback(&self) -> Vec<TextLabel> {
let b = &self.base;
if let Some(ref label) = b.label {
let (_, font_size) = crate::layout::control_label_font_detached_parsed();
let color = crate::colors::control_label_color_detached_for_state(b.hovered, b.focused);
if crate::layout::control_label_layout() == "side" {
- let label_x = Element::label_x_offset(self);
+ let label_x = WidgetHost::label_x_offset(self);
if label_x > 0.0 {
let y_pos = crate::layout::align_text_y(b.y, b.h, font_size, 0.0);
return vec![TextLabel { text: label.clone(), x: b.x + 4.0, y: y_pos, font_size, color }];
@@ -867,7 +867,7 @@ impl<W: Layout + Paint + Input + 'static> std::ops::DerefMut for Adapted<W> {
}
}
-impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
+impl<W: Layout + Paint + Input + 'static> WidgetHost for Adapted<W> {
fn base(&self) -> &Widget {
&self.base
}
@@ -882,11 +882,11 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
&mut self.inner
}
- fn as_ptr(&self) -> *mut (dyn Element + 'static) {
- self as *const Self as *mut Self as *mut (dyn Element + 'static)
+ fn as_ptr(&self) -> *mut (dyn WidgetHost + 'static) {
+ self as *const Self as *mut Self as *mut (dyn WidgetHost + 'static)
}
- fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
- self as *mut Self as *mut (dyn Element + 'static)
+ fn as_ptr_mut(&mut self) -> *mut (dyn WidgetHost + 'static) {
+ self as *mut Self as *mut (dyn WidgetHost + 'static)
}
fn set_visible(&mut self, visible: bool) {
@@ -900,11 +900,11 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
}
// --- Container concern: tree lifecycle, child layout, and subtree recursion. The tree
- // itself stays in `ctx.tree` (the Element defaults' store); a container model additionally
+ // itself stays in `ctx.tree` (the WidgetHost defaults' store); a container model additionally
// keeps its own pointer Vec via the `Layout` hooks, because `set_rect`-time arrangement
// has no ctx to reach the tree.
- fn children(&self, ctx: &UiContext) -> Vec<*mut (dyn Element + 'static)> {
+ fn children(&self, ctx: &UiContext) -> Vec<*mut (dyn WidgetHost + 'static)> {
if Layout::has_container_children(&self.inner) {
return Layout::container_children(&self.inner);
}
@@ -927,7 +927,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
Layout::z_order(&self.inner)
}
- fn parent(&self, ctx: &UiContext) -> Option<*mut (dyn Element + 'static)> {
+ fn parent(&self, ctx: &UiContext) -> Option<*mut (dyn WidgetHost + 'static)> {
ctx.tree.parent_ptr(self.base.id())
}
@@ -941,7 +941,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
fn layout(&mut self, origin: crate::widget::Point, constraints: crate::widget::LayoutConstraints, ctx: &mut UiContext) {
- // The Element default (measure + set_rect), plus recursive child layout for visible
+ // The WidgetHost default (measure + set_rect), plus recursive child layout for visible
// containers — the ctx-carrying half of the arrangement the model can't do in
// `arrange_children`.
let size = self.measure(constraints, ctx);
@@ -1012,7 +1012,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
Layout::intrinsic_size(&self.inner).map(|s| s.height)
}
- /// The `Element::measure` default, except the width consults the intrinsic size when the
+ /// The `WidgetHost::measure` default, except the width consults the intrinsic size when the
/// widget opts in ([`Layout::intrinsic_measure_width`] — Dropdown's `auto_width`).
fn measure(&self, constraints: crate::widget::LayoutConstraints, _ctx: &UiContext) -> crate::widget::Size {
let (_, _, w, h) = self.rect();
@@ -1032,7 +1032,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
/// hover-highlight overlay is suppressed (matching what most control widgets' `None`
/// overrides do today) — unless the widget opts back in
/// ([`Paint::legacy_focus_highlight`], TextBox), in which case this replicates the
- /// `Element` default byte-for-byte: primary tint when ctx-focused (or active), secondary
+ /// `WidgetHost` default byte-for-byte: primary tint when ctx-focused (or active), secondary
/// when hovered, over the row-substituted, side-label-inset span.
fn highlight_quad(&self, ctx: &UiContext) -> Option<(f32, f32, f32, f32, [f32; 4])> {
// A forwarding widget (Paginator → its ButtonStrip) serves the forwarded value here —
@@ -1052,7 +1052,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
} else {
return None;
};
- let label_x = Element::label_x_offset(self);
+ let label_x = WidgetHost::label_x_offset(self);
let hx = if self.base.row_w > 0.0 { self.base.row_x } else { self.base.x } + label_x;
let hw = if self.base.row_w > 0.0 { self.base.row_w } else { self.base.w } - label_x;
Some((hx, self.base.y, hw, self.base.h, hc))
@@ -1064,7 +1064,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
std::any::type_name::<W>().split("::").last().unwrap_or("Widget")
}
- /// Text-content mutation (legacy `Element::set_text` wrote only `base.label`): keep the base
+ /// Text-content mutation (legacy `WidgetHost::set_text` wrote only `base.label`): keep the base
/// copy and the widget's own copy ([`Paint::sync_label`]) in step, like `set_label`.
fn set_text(&mut self, text: &str) {
self.base.label = Some(text.to_string());
@@ -1079,7 +1079,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
Paint::clips_children(&self.inner)
}
fn corner_style(&self) -> (f32, (bool, bool, bool, bool)) {
- // 12.0 / all-off mirrors the `Element` default for widgets without a corner style.
+ // 12.0 / all-off mirrors the `WidgetHost` default for widgets without a corner style.
Paint::corner_style(&self.inner, self.content_rect())
.unwrap_or((12.0, (false, false, false, false)))
}
@@ -1125,7 +1125,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
// highlight — replicate for opt-in widgets, over the background (same draw order).
// Forwarded highlights stay out: the paint walk reaches the owning child itself.
if Paint::legacy_focus_highlight(&self.inner) {
- if let Some((hx, hy, hw, hh, hc)) = Element::highlight_quad(self, ui) {
+ if let Some((hx, hy, hw, hh, hc)) = WidgetHost::highlight_quad(self, ui) {
if hc != crate::colors::HIGHLIGHT_SECONDARY {
ctx.quad(Rect { x: hx, y: hy, width: hw, height: hh }, hc);
}
@@ -1148,7 +1148,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
}
}
- // The legacy per-widget text getters are deleted from `Element`: this adapter's text
+ // The legacy per-widget text getters are deleted from `WidgetHost`: this adapter's text
// reaches the frame through `paint_self` above (prim-derived own labels + the
// detached base label), and composites that need a concrete Adapted child's labels
// call `own_labels_with_font_and_bounds` directly (pub(crate)).
@@ -1175,7 +1175,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
_ => None,
})
.collect();
- // Containers recurse, matching the `Element` default this override replaces.
+ // Containers recurse, matching the `WidgetHost` default this override replaces.
for child in self.visible_children() {
out.extend(unsafe { &*child }.all_rounded_quads(ctx));
}
@@ -1204,7 +1204,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
/// When the widget serves a legacy plain-quad view, its geometry reaches
/// `render_widget`-style hosts (which read BOTH quad getters) through `all_rounded_quads`
/// only — `all_quads` must stay empty or they draw it twice. Mirrors legacy Graph's
- /// highlight-only `all_quads` override. Otherwise: the `Element` default minus the shared
+ /// highlight-only `all_quads` override. Otherwise: the `WidgetHost` default minus the shared
/// highlight (suppressed for all adapted widgets via `highlight_quad -> None`).
fn all_quads(&self, ctx: &UiContext) -> Vec<(f32, f32, f32, f32, [f32; 4])> {
if Paint::serves_legacy_plain_quads(&self.inner) {
@@ -1213,12 +1213,12 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
// Own prims directly (NOT `extra_quads`, which may serve the child aggregation — those
// children arrive once, through the recursion below).
let mut quads = if self.visible() { self.own_plain_quads() } else { Vec::new() };
- // The `Element` default's highlight inclusion (secondary/hover tint excluded), live
+ // The `WidgetHost` default's highlight inclusion (secondary/hover tint excluded), live
// only for widgets that opt into the legacy overlay. A forwarded highlight
// ([`Paint::forwarded_highlight`]) is deliberately excluded: its owner's aggregation
// already carries it, matching the legacy container `all_quads` overrides.
if Paint::legacy_focus_highlight(&self.inner) {
- if let Some(hq) = Element::highlight_quad(self, ctx) {
+ if let Some(hq) = WidgetHost::highlight_quad(self, ctx) {
if hq.4 != crate::colors::HIGHLIGHT_SECONDARY {
quads.push(hq);
}
@@ -1303,7 +1303,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
}
/// Row-rect assignment (row-layout hosts): apply the widget's clamp
/// ([`Layout::adjust_row_rect`] — TextBox's `width`/`max_width`), then the base write the
- /// `Element` default does.
+ /// `WidgetHost` default does.
fn set_row_rect(&mut self, x: f32, w: f32) {
let (rx, rw) = Layout::adjust_row_rect(&self.inner, x, w);
self.base.row_x = rx;
@@ -1358,7 +1358,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
}
// --- Legacy direct-dispatch entry points. Hosts (treelist's add-key button, parameters_bg's
// checkboxes, app pages) call these ON the widget instead of routing an Event through
- // `propagate_event`; without these overrides they'd hit the inert Element defaults and the
+ // `propagate_event`; without these overrides they'd hit the inert WidgetHost defaults and the
// widget would go deaf on those paths. Route them into `handle_event` so the hit-gating /
// context-menu / on_event pipeline applies identically on both paths.
@@ -1400,7 +1400,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
if Input::on_event(&mut self.inner, &event, &mut ectx) {
return true;
}
- // The legacy default `Element::on_cursor_moved` body: base hover flag + synthesized
+ // The legacy default `WidgetHost::on_cursor_moved` body: base hover flag + synthesized
// MouseEnter/MouseLeave (which re-enter `handle_event` and reach `on_event`).
let was = self.base.hovered;
let is_hit = self.hit_test(px, py, ctx);
@@ -1465,7 +1465,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
return false;
}
let (mut hx, mut hw) = if self.base.row_w > 0.0 { (self.base.row_x, self.base.row_w) } else { (x, w) };
- let label_x = Element::label_x_offset(self);
+ let label_x = WidgetHost::label_x_offset(self);
hx += label_x;
hw -= label_x;
return Input::hit(&self.inner, Rect { x: hx, y, width: hw, height: h }, px, py);
@@ -1484,7 +1484,7 @@ impl<W: Layout + Paint + Input + 'static> Element for Adapted<W> {
}
match event {
// A hit right-press on a context-menu widget routes to the shared config menu —
- // `on_event` can't (that policy needs the target's Element pointer), so the adapter
+ // `on_event` can't (that policy needs the target's WidgetHost pointer), so the adapter
// owns it.
Event::MouseButton {
button: crate::widget::MouseButton::Right,
@@ -1546,7 +1546,7 @@ mod tests {
use crate::scene::painter::paint_tree;
use crate::widget::UiContext;
- /// A leaf that only knows the two narrow concerns — no `Element` in sight: it reports an
+ /// A leaf that only knows the two narrow concerns — no `WidgetHost` in sight: it reports an
/// intrinsic size ([`Layout`]) and a color ([`Paint`]).
struct Dot {
color: [f32; 4],
@@ -1574,7 +1574,7 @@ mod tests {
}
impl Input for Col {}
- fn rect_of(ptr: *mut (dyn Element + 'static)) -> Rect {
+ fn rect_of(ptr: *mut (dyn WidgetHost + 'static)) -> Rect {
let (x, y, w, h) = unsafe { (*ptr).rect() };
Rect { x, y, width: w, height: h }
}
@@ -1583,7 +1583,7 @@ mod tests {
fn narrow_widget_lays_out_and_paints_through_the_adapter() {
// A pure narrow-trait widget tree (Col + two Dots), wrapped in `Adapted`, is laid out by
// the existing bridge and painted by the existing painter — proving a widget that never
- // touches `Element` participates in both live passes.
+ // touches `WidgetHost` participates in both live passes.
let mut ctx = UiContext::new();
let mut root = Box::new(Adapted::new(Col));
let mut a = Box::new(Adapted::new(Dot { color: [1.0, 0.0, 0.0, 1.0], size: Size::new(10.0, 10.0) }));
@@ -1629,7 +1629,7 @@ mod tests {
}
/// A narrow interactive widget: counts left-clicks and records hover transitions — all
- /// through [`Input::on_event`], never touching `Element`.
+ /// through [`Input::on_event`], never touching `WidgetHost`.
struct Clicker {
clicks: u32,
entered: u32,
@@ -1697,7 +1697,7 @@ mod tests {
}
/// A narrow widget that is also a controller: the controller trait is reached through the
- /// concrete `Adapted<W>` by deref (Phase 6aw -- the `Element::as_*_controller` discovery
+ /// concrete `Adapted<W>` by deref (Phase 6aw -- the `WidgetHost::as_*_controller` discovery
/// hooks are deleted).
struct Crumbs {
segs: Vec<String>,