git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit1b689bc08c547e52fe005746f4685da5b71d9030
parent1dcf041414
authorLucas Galante <[email protected]>
date2026-07-12 06:51
refactor(widget)!: DELETE Header, VBox, HBox, Svg — zero constructors (Phase 6ax)

Raw-Element census after the capability deletion: four more widgets
have no constructor anywhere in the workspace. Header/VBox/HBox were
export-only; Svg additionally rode Button as an Option<Svg> payload
that no caller ever set (with_svg and all three Svg constructors have
zero call sites), so Button's icon branches were statically dead and
go too (paint's centered-SVG tail, intrinsic_size's square-icon case).

Raw `impl Element` in cce-ui is down to: JsonLayoutWidget (cloud's
host), Canvas (designer + preview), ButtonStrip (ctx-registered embed
of MenuBar/Paginator — load-bearing in the tree, not demotable like
ScrollBox), Container (dm/settings/TI), Viewport3D (designer).

168 tests pass; full workspace builds. No runtime surface: none of the
deleted code was reachable.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018u7qTwzX95dd5ysAkaSCLk

 src/widget/container/hbox.rs   | 69 ------------------------------
 src/widget/container/header.rs | 25 -----------
 src/widget/container/mod.rs    |  6 ---
 src/widget/container/vbox.rs   | 66 -----------------------------
 src/widget/display/mod.rs      |  2 -
 src/widget/display/svg.rs      | 96 ------------------------------------------
 src/widget/input/button.rs     | 21 +--------
 src/widget/mod.rs              |  4 +-
 8 files changed, 3 insertions(+), 286 deletions(-)

diff --git a/src/widget/container/hbox.rs b/src/widget/container/hbox.rs
deleted file mode 100644
index 42823bf..0000000
--- a/src/widget/container/hbox.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use crate::widget::*;
-
-pub struct HBox {
-    pub base: Widget,
-    pub children: Vec<*mut (dyn Element + 'static)>,
-    pub parent: Option<*mut (dyn Element + 'static)>,
-    pub gap: f32,
-    pub margin: f32,
-}
-
-impl HBox {
-    pub fn new(gap: f32, margin: f32) -> Self {
-        Self {
-            base: Widget::new(),
-            children: Vec::new(),
-            parent: None,
-            gap,
-            margin,
-        }
-    }
-
-    pub fn add_child(&mut self, child: *mut (dyn Element + 'static)) {
-        self.children.push(child);
-    }
-}
-
-impl Element for HBox {
-    crate::impl_widget_base!(HBox);
-
-    fn color(&self) -> [f32; 4] {
-        [0.0, 0.0, 0.0, 0.0]
-    }
-
-    fn children(&self, _ctx: &UiContext) -> Vec<*mut (dyn Element + 'static)> {
-        self.children.clone()
-    }
-
-    fn parent(&self, _ctx: &UiContext) -> Option<*mut (dyn Element + 'static)> {
-        self.parent
-    }
-
-    fn set_parent(&mut self, parent: Option<*mut (dyn Element + 'static)>, _ctx: &mut UiContext) {
-        self.parent = parent;
-    }
-
-    fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) {
-        self.base.x = x;
-        self.base.y = y;
-        self.base.w = w;
-        self.base.h = h;
-
-        let count = self.children.len();
-        if count == 0 {
-            return;
-        }
-
-        let total_w = w - 2.0 * self.margin;
-        let child_w = (total_w - (count as f32 - 1.0) * self.gap) / count as f32;
-        let child_h = h - 2.0 * self.margin;
-        let mut current_x = x + self.margin;
-
-        for &child_ptr in &self.children {
-            unsafe {
-                (*child_ptr).set_rect(current_x, y + self.margin, child_w, child_h);
-                current_x += child_w + self.gap;
-            }
-        }
-    }
-}
diff --git a/src/widget/container/header.rs b/src/widget/container/header.rs
deleted file mode 100644
index cc28ab8..0000000
--- a/src/widget/container/header.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use crate::colors;
-use crate::widget::*;
-
-pub struct Header {
-    x: f32, y: f32, w: f32, h: f32,
-    hovered: bool,
-}
-
-impl Header {
-    pub fn new() -> Self { Self { x: 0.0, y: 0.0, w: 0.0, h: 0.0, hovered: false } }
-}
-
-impl Element for Header {
-    fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
-    fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) { self.x = x; self.y = y; self.w = w; self.h = h; }
-    fn color(&self) -> [f32; 4] { colors::HEADER_BG }
-    fn as_ptr(&self) -> *mut (dyn Element + 'static) {
-        self as *const Self as *mut Self as *mut (dyn Element + 'static)
-    }
-    fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
-        self as *mut Self as *mut (dyn Element + 'static)
-    }
-    fn set_hovered(&mut self, v: bool) { self.hovered = v; }
-    fn hovered(&self) -> bool { self.hovered }
-}
diff --git a/src/widget/container/mod.rs b/src/widget/container/mod.rs
index acba67b..6ffeacd 100644
--- a/src/widget/container/mod.rs
+++ b/src/widget/container/mod.rs
@@ -1,6 +1,5 @@
 pub mod container;
 pub mod container_layout;
-pub mod header;
 pub mod content_bg;
 pub mod parameters_bg;
 pub mod menu;
@@ -9,12 +8,9 @@ pub mod spreadsheet;
 pub mod scroll_box;
 pub mod paginator;
 pub mod treelist;
-pub mod vbox;
-pub mod hbox;
 
 pub use container::Container;
 pub use container_layout::{ContainerLayout, OverlayLayout, ManualLayout, VerticalLayout, GridLayout, AdaptiveGridLayout, ColumnsLayout, MosaicLayout, ReverseMosaicLayout};
-pub use header::Header;
 pub use content_bg::ContentBg;
 pub use parameters_bg::ParametersBg;
 pub use menu::MenuBar;
@@ -23,5 +19,3 @@ pub use spreadsheet::Spreadsheet;
 pub use scroll_box::ScrollBox;
 pub use paginator::Paginator;
 pub use treelist::{TreeList, TreeElement};
-pub use vbox::VBox;
-pub use hbox::HBox;
diff --git a/src/widget/container/vbox.rs b/src/widget/container/vbox.rs
deleted file mode 100644
index d218ab0..0000000
--- a/src/widget/container/vbox.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-use crate::widget::*;
-
-pub struct VBox {
-    pub base: Widget,
-    pub children: Vec<*mut (dyn Element + 'static)>,
-    pub parent: Option<*mut (dyn Element + 'static)>,
-    pub gap: f32,
-    pub margin: f32,
-}
-
-impl VBox {
-    pub fn new(gap: f32, margin: f32) -> Self {
-        Self {
-            base: Widget::new(),
-            children: Vec::new(),
-            parent: None,
-            gap,
-            margin,
-        }
-    }
-
-    pub fn add_child(&mut self, child: *mut (dyn Element + 'static)) {
-        self.children.push(child);
-    }
-}
-
-impl Element for VBox {
-    crate::impl_widget_base!(VBox);
-
-    fn color(&self) -> [f32; 4] {
-        [0.0, 0.0, 0.0, 0.0]
-    }
-
-    fn children(&self, _ctx: &UiContext) -> Vec<*mut (dyn Element + 'static)> {
-        self.children.clone()
-    }
-
-    fn parent(&self, _ctx: &UiContext) -> Option<*mut (dyn Element + 'static)> {
-        self.parent
-    }
-
-    fn set_parent(&mut self, parent: Option<*mut (dyn Element + 'static)>, _ctx: &mut UiContext) {
-        self.parent = parent;
-    }
-
-    fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) {
-        self.base.x = x;
-        self.base.y = y;
-        self.base.w = w;
-        self.base.h = h;
-
-        let mut current_y = y + self.margin;
-        let child_w = w - 2.0 * self.margin;
-
-        for &child_ptr in &self.children {
-            unsafe {
-                let preferred_h = (*child_ptr).preferred_height().unwrap_or(24.0);
-                let label_off = (*child_ptr).base().map_or(0.0, |b| b.label_offset());
-                let total_h = preferred_h + label_off;
-                
-                (*child_ptr).set_rect(x + self.margin, current_y, child_w, preferred_h);
-                current_y += total_h + self.gap;
-            }
-        }
-    }
-}
diff --git a/src/widget/display/mod.rs b/src/widget/display/mod.rs
index 052c41c..33bfa7e 100644
--- a/src/widget/display/mod.rs
+++ b/src/widget/display/mod.rs
@@ -3,7 +3,6 @@ pub mod sidebar;
 pub mod panel;
 pub mod node;
 pub mod label;
-pub mod svg;
 pub mod float3;
 pub mod progress_bar;
 pub mod status_bar;
@@ -26,7 +25,6 @@ pub use self::sidebar::Sidebar;
 pub use self::panel::Panel;
 pub use self::node::Node;
 pub use self::label::{Label, StyledLabel, LabelPrim};
-pub use self::svg::Svg;
 pub use self::float3::Float3;
 pub use self::progress_bar::ProgressBar;
 pub use self::status_bar::StatusBar;
diff --git a/src/widget/display/svg.rs b/src/widget/display/svg.rs
deleted file mode 100644
index e8c26b6..0000000
--- a/src/widget/display/svg.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-use crate::widget::*;
-
-#[derive(Debug, Clone)]
-pub struct Svg {
-    pub x: f32,
-    pub y: f32,
-    pub w: f32,
-    pub h: f32,
-    pub quads: Vec<(f32, f32, f32, f32, [f32; 4])>,
-}
-
-impl Svg {
-    pub fn new(svg_data: &[u8], x: f32, y: f32, w: f32, h: f32) -> Option<Self> {
-        let opt = resvg::usvg::Options::default();
-        let fontdb = resvg::usvg::fontdb::Database::new();
-        let tree = resvg::usvg::Tree::from_data(svg_data, &opt, &fontdb).ok()?;
-        
-        let target_w = w as u32;
-        let target_h = h as u32;
-        if target_w == 0 || target_h == 0 {
-            return None;
-        }
-        let mut pixmap = resvg::tiny_skia::Pixmap::new(target_w, target_h)?;
-        
-        let orig_w = tree.size().width();
-        let orig_h = tree.size().height();
-        let sx = target_w as f32 / orig_w;
-        let sy = target_h as f32 / orig_h;
-        let transform = resvg::tiny_skia::Transform::from_scale(sx, sy);
-        
-        resvg::render(&tree, transform, &mut pixmap.as_mut());
-        
-        let mut quads = Vec::new();
-        let pixels = pixmap.data();
-        for row in 0..target_h {
-            for col in 0..target_w {
-                let idx = ((row * target_w + col) * 4) as usize;
-                if idx + 3 < pixels.len() {
-                    let a = pixels[idx + 3] as f32 / 255.0;
-                    if a > 0.0 {
-                        let r = pixels[idx] as f32 / 255.0;
-                        let g = pixels[idx + 1] as f32 / 255.0;
-                        let b = pixels[idx + 2] as f32 / 255.0;
-                        quads.push((
-                            x + col as f32,
-                            y + row as f32,
-                            1.0,
-                            1.0,
-                            [r, g, b, a],
-                        ));
-                    }
-                }
-            }
-        }
-        
-        Some(Self { x, y, w, h, quads })
-    }
-
-    pub fn from_file<P: AsRef<std::path::Path>>(path: P, x: f32, y: f32, w: f32, h: f32) -> Option<Self> {
-        let data = std::fs::read(path).ok()?;
-        Self::new(&data, x, y, w, h)
-    }
-
-    pub fn from_str(svg_str: &str, x: f32, y: f32, w: f32, h: f32) -> Option<Self> {
-        Self::new(svg_str.as_bytes(), x, y, w, h)
-    }
-}
-
-impl Element for Svg {
-    fn rect(&self) -> (f32, f32, f32, f32) { (self.x, self.y, self.w, self.h) }
-    fn as_ptr(&self) -> *mut (dyn Element + 'static) {
-        self as *const Self as *mut Self as *mut (dyn Element + 'static)
-    }
-    fn as_ptr_mut(&mut self) -> *mut (dyn Element + 'static) {
-        self as *mut Self as *mut (dyn Element + 'static)
-    }
-    
-    fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) {
-        let dx = x - self.x;
-        let dy = y - self.y;
-        for quad in &mut self.quads {
-            quad.0 += dx;
-            quad.1 += dy;
-        }
-        self.x = x;
-        self.y = y;
-        self.w = w;
-        self.h = h;
-    }
-    
-    fn color(&self) -> [f32; 4] { [0.0, 0.0, 0.0, 0.0] }
-    
-    fn extra_quads(&self) -> Vec<(f32, f32, f32, f32, [f32; 4])> {
-        self.quads.clone()
-    }
-}
diff --git a/src/widget/input/button.rs b/src/widget/input/button.rs
index d104222..4fc522b 100644
--- a/src/widget/input/button.rs
+++ b/src/widget/input/button.rs
@@ -9,7 +9,7 @@ use crate::scene::layout::{Rect, Size};
 use crate::scene::paint::PaintCtx;
 use crate::widget::{
     Adapted, Control, Element, ElementState, Event, EventCtx, Input, Justification, Layout,
-    MouseButton, Paint, Svg,
+    MouseButton, Paint,
 };
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -31,7 +31,6 @@ pub struct Button {
     pub hover_bg: Option<[f32; 4]>,
     pub label_color: Option<[f32; 4]>,
     pub justify: Justification,
-    pub svg: Option<Svg>,
     label: Option<String>,
     hovered: bool,
 }
@@ -62,7 +61,6 @@ impl Button {
             hover_bg: None,
             label_color: None,
             justify: Justification::Center,
-            svg: None,
             label: None,
             hovered: false,
         }
@@ -122,10 +120,6 @@ impl Button {
 /// The by-value builder chain, mirrored on the wrapped type (`with_label` comes from the generic
 /// `Adapted::with_label`, which syncs the model's copy via `Paint::sync_label`).
 impl Adapted<Button> {
-    pub fn with_svg(mut self, svg: Svg) -> Self {
-        self.svg = Some(svg);
-        self
-    }
 
     pub fn with_selected(mut self, selected: bool) -> Self {
         self.selected = selected;
@@ -178,9 +172,6 @@ impl Layout for Button {
     /// square at that height.
     fn intrinsic_size(&self) -> Option<Size> {
         let height = crate::layout::button_height();
-        if self.svg.is_some() {
-            return Some(Size::new(height, height));
-        }
         let label = self.label.as_deref().unwrap_or("");
         Some(Size::new(self.label_width(label) + 16.0, height))
     }
@@ -288,16 +279,6 @@ impl Paint for Button {
             }
         }
 
-        // Centered SVG icon (legacy `extra_quads` tail).
-        if let Some(ref svg) = self.svg {
-            let dx = x + (w - svg.w) / 2.0 - svg.x;
-            let dy = y + (h - svg.h) / 2.0 - svg.y;
-            for q in &svg.quads {
-                ctx.quad(Rect { x: q.0 + dx, y: q.1 + dy, width: q.2, height: q.3 }, q.4);
-            }
-            return; // legacy: an SVG button draws no label text
-        }
-
         // Label, with per-kind justification/color (legacy `text_labels`).
         if let Some(ref label) = self.label {
             let (_, font_size) = self.font();
diff --git a/src/widget/mod.rs b/src/widget/mod.rs
index 66ad217..f7444f0 100644
--- a/src/widget/mod.rs
+++ b/src/widget/mod.rs
@@ -725,12 +725,12 @@ pub use self::input::{
 pub use self::container::{
     Container, ContainerLayout, OverlayLayout, ManualLayout, VerticalLayout, GridLayout, AdaptiveGridLayout,
     ColumnsLayout, MosaicLayout, ReverseMosaicLayout,
-    Header, ContentBg, ParametersBg,
+    ContentBg, ParametersBg,
     ScrollBox, MenuBar, Spreadsheet, Breadcrumb,
     Paginator, TreeList, TreeElement
 };
 pub use self::display::{
-    TextLabel, Label, StyledLabel, LabelPrim, TextItem, Svg, UsageBar,
+    TextLabel, Label, StyledLabel, LabelPrim, TextItem, UsageBar,
     LayoutPreview, FontPreview, InfoBox, StatusDot, InteractiveListItem,
     GraphNode, Graph, Float3, ProgressBar, StatusBar, Splitter, Node, Separator,
     DotStatus, PreviewLayoutMode, Sidebar, Panel, PreviewState, ImagePreviewData, serialize_widgets,