GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
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,