GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Refactor ControlPanel layout to use ColumnLayout and fix status bar font parsing and text alignment
src/widget/container/control_panel.rs | 123 ++++++++++++----------------------
src/widget/display/status_bar.rs | 17 +++--
2 files changed, 55 insertions(+), 85 deletions(-)
diff --git a/src/widget/container/control_panel.rs b/src/widget/container/control_panel.rs
index ddf2971..4489f20 100644
--- a/src/widget/container/control_panel.rs
+++ b/src/widget/container/control_panel.rs
@@ -96,8 +96,8 @@ impl Element for ControlPanel {
let self_ptr_option = Some(self_ptr);
let padding = 16.0;
- let mut curr_y = padding;
- let content_w = w - 2.0 * padding - 12.0; // 12px reserved for scrollbar track
+ let gap = 16.0;
+ let mut col = ColumnLayout::new(x, y, w - 12.0, gap, padding); // 12px reserved for scrollbar track
unsafe {
let mut create_btn: Option<*mut dyn Element> = None;
@@ -107,14 +107,13 @@ impl Element for ControlPanel {
let mut slider_label: Option<*mut dyn Element> = None;
let mut type_dd: Option<*mut dyn Element> = None;
let mut shape_dd: Option<*mut dyn Element> = None;
- let mut border_toggle: Option<*mut dyn Element> = None;
+ let mut border_style_dd: Option<*mut dyn Element> = None;
let mut width_spin: Option<*mut dyn Element> = None;
let mut height_spin: Option<*mut dyn Element> = None;
let mut backplate_toggle: Option<*mut dyn Element> = None;
let mut menubar_toggle: Option<*mut dyn Element> = None;
let mut statusbar_toggle: Option<*mut dyn Element> = None;
let mut border_sec: Option<*mut dyn Element> = None;
- let mut bevel_toggle: Option<*mut dyn Element> = None;
let mut border_width_spin: Option<*mut dyn Element> = None;
let mut bevel_depth_spin: Option<*mut dyn Element> = None;
let mut win_sec: Option<*mut dyn Element> = None;
@@ -133,13 +132,12 @@ impl Element for ControlPanel {
"Window Elements" => win_sec = Some(child_ptr),
"Window Type" => type_dd = Some(child_ptr),
"Window Shape" => shape_dd = Some(child_ptr),
- "Enable" => border_toggle = Some(child_ptr),
+ "Border Style" => border_style_dd = Some(child_ptr),
"Width" => width_spin = Some(child_ptr),
"Height" => height_spin = Some(child_ptr),
"Backplate" => backplate_toggle = Some(child_ptr),
"MenuBar" => menubar_toggle = Some(child_ptr),
"StatusBar" => statusbar_toggle = Some(child_ptr),
- "Bevel" => bevel_toggle = Some(child_ptr),
"Border Width" => border_width_spin = Some(child_ptr),
"Bevel Depth" => bevel_depth_spin = Some(child_ptr),
"Bevel Shape..." => bevel_shape_btn = Some(child_ptr),
@@ -151,100 +149,63 @@ impl Element for ControlPanel {
}
}
- // --- SECTION 1: Window Actions ---
- if let (Some(c), Some(t)) = (create_btn, tile_btn) {
- let btn_w = (content_w - 12.0) / 2.0;
- (*c).set_rect(x + padding, y + curr_y, btn_w, 28.0);
- (*t).set_rect(x + padding + btn_w + 12.0, y + curr_y, btn_w, 28.0);
- curr_y += 28.0 + 24.0;
+ if let Some(c) = create_btn {
+ col.add_widget(&mut *c, 28.0);
}
-
- // --- SECTION 2: Dimensions ---
- if let (Some(w_sp), Some(h_sp)) = (width_spin, height_spin) {
- let spin_w = (content_w - 12.0) / 2.0;
- (*w_sp).set_rect(x + padding, y + curr_y, spin_w, 20.0);
- (*h_sp).set_rect(x + padding + spin_w + 12.0, y + curr_y, spin_w, 20.0);
- curr_y += 20.0 + 24.0;
+ if let Some(t) = tile_btn {
+ col.add_widget(&mut *t, 28.0);
+ }
+ if let Some(w_sp) = width_spin {
+ col.add_widget(&mut *w_sp, 20.0);
+ }
+ if let Some(h_sp) = height_spin {
+ col.add_widget(&mut *h_sp, 20.0);
}
-
- // --- SECTION 3: Window Type & Shape ---
- let mut has_dd = false;
if let Some(t_dd) = type_dd {
- (*t_dd).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 16.0;
- has_dd = true;
+ col.add_widget(&mut *t_dd, 20.0);
}
if let Some(s_dd) = shape_dd {
- (*s_dd).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 24.0;
- has_dd = true;
- }
- if !has_dd {
- // Keep spacing consistent
+ col.add_widget(&mut *s_dd, 20.0);
}
-
- // --- SECTION 4: Opacity & Transparency ---
if let Some(op_t) = opacity_toggle {
- (*op_t).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 16.0;
+ col.add_widget(&mut *op_t, 20.0);
}
if let Some(sl_lbl) = slider_label {
- (*sl_lbl).set_rect(x + padding, y + curr_y, content_w, 12.0);
- curr_y += 12.0 + 4.0;
+ col.add_widget(&mut *sl_lbl, 12.0);
}
if let Some(sl) = slider {
- (*sl).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 24.0;
+ col.add_widget(&mut *sl, 20.0);
}
-
- // --- SECTION 5: Window Elements ---
if let Some(w_s) = win_sec {
- (*w_s).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 16.0;
- }
- let toggles = [backplate_toggle, menubar_toggle, statusbar_toggle];
- let active_toggles: Vec<*mut dyn Element> = toggles.iter().filter_map(|&t| t).collect();
- if !active_toggles.is_empty() {
- let t_w = (content_w - (active_toggles.len() as f32 - 1.0) * 10.0) / active_toggles.len() as f32;
- for (idx, &t) in active_toggles.iter().enumerate() {
- (*t).set_rect(x + padding + idx as f32 * (t_w + 10.0), y + curr_y, t_w, 20.0);
- }
- curr_y += 20.0 + 24.0;
+ col.add_widget(&mut *w_s, 20.0);
+ }
+ if let Some(bp_t) = backplate_toggle {
+ col.add_widget(&mut *bp_t, 20.0);
+ }
+ if let Some(mb_t) = menubar_toggle {
+ col.add_widget(&mut *mb_t, 20.0);
+ }
+ if let Some(sb_t) = statusbar_toggle {
+ col.add_widget(&mut *sb_t, 20.0);
}
-
- // --- SECTION 6: Border & Bevel ---
if let Some(b_s) = border_sec {
- (*b_s).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 16.0;
- }
- if let (Some(b_tg), Some(bev_tg)) = (border_toggle, bevel_toggle) {
- let tg_w = (content_w - 12.0) / 2.0;
- (*b_tg).set_rect(x + padding, y + curr_y, tg_w, 20.0);
- (*bev_tg).set_rect(x + padding + tg_w + 12.0, y + curr_y, tg_w, 20.0);
- curr_y += 20.0 + 16.0;
- }
- if let (Some(bw_sp), Some(bd_sp)) = (border_width_spin, bevel_depth_spin) {
- let spin_w = (content_w - 12.0) / 2.0;
- (*bw_sp).set_rect(x + padding, y + curr_y, spin_w, 20.0);
- (*bd_sp).set_rect(x + padding + spin_w + 12.0, y + curr_y, spin_w, 20.0);
- curr_y += 20.0 + 16.0;
- } else {
- if let Some(bw_sp) = border_width_spin {
- (*bw_sp).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 16.0;
- }
- if let Some(bd_sp) = bevel_depth_spin {
- (*bd_sp).set_rect(x + padding, y + curr_y, content_w, 20.0);
- curr_y += 20.0 + 16.0;
- }
+ col.add_widget(&mut *b_s, 20.0);
+ }
+ if let Some(bs_dd) = border_style_dd {
+ col.add_widget(&mut *bs_dd, 20.0);
+ }
+ if let Some(bw_sp) = border_width_spin {
+ col.add_widget(&mut *bw_sp, 20.0);
+ }
+ if let Some(bd_sp) = bevel_depth_spin {
+ col.add_widget(&mut *bd_sp, 20.0);
}
if let Some(bs_btn) = bevel_shape_btn {
- (*bs_btn).set_rect(x + padding, y + curr_y, content_w, 28.0);
- curr_y += 28.0;
+ col.add_widget(&mut *bs_btn, 28.0);
}
- curr_y += padding;
- self.scroll_box.update_bounds(curr_y, y, h);
+ let total_h = col.current_y();
+ self.scroll_box.update_bounds(total_h, y, h);
}
}
diff --git a/src/widget/display/status_bar.rs b/src/widget/display/status_bar.rs
index be9f562..fa5ca32 100644
--- a/src/widget/display/status_bar.rs
+++ b/src/widget/display/status_bar.rs
@@ -158,7 +158,10 @@ impl Element for StatusBar {
}
fn prepare_text(&mut self, fs: &mut glyphon::FontSystem) {
if !self.text.is_empty() && self.text_buf.is_none() {
- self.text_buf = Some(make_widget_text_buffer(fs, &self.text, 12.0, "Outfit"));
+ let (font_fam, font_size) = crate::layout::statusbar_font_parsed();
+ let size = if font_size > 0.0 { font_size } else { 12.0 };
+ let fam = if font_fam.is_empty() { "Outfit".to_string() } else { font_fam };
+ self.text_buf = Some(make_widget_text_buffer(fs, &self.text, size, &fam));
}
}
fn get_text_items(&self) -> Vec<(&glyphon::Buffer, f32, f32, glyphon::Color)> {
@@ -170,7 +173,10 @@ impl Element for StatusBar {
(c[1] * 255.0) as u8,
(c[2] * 255.0) as u8,
);
- vec![(text_buf, self.x + offset_x, self.y + 4.0, color)]
+ let (_, font_size) = crate::layout::statusbar_font_parsed();
+ let size = if font_size > 0.0 { font_size } else { 12.0 };
+ let text_y = crate::layout::align_text_y(self.y, self.h, size, 0.0);
+ vec![(text_buf, self.x + offset_x, text_y, color)]
} else {
Vec::new()
}
@@ -184,11 +190,14 @@ impl Element for StatusBar {
(c[1] * 255.0) as u8,
(c[2] * 255.0) as u8,
];
+ let (_, font_size) = crate::layout::statusbar_font_parsed();
+ let size = if font_size > 0.0 { font_size } else { 12.0 };
+ let text_y = crate::layout::align_text_y(self.y, self.h, size, 0.0);
vec![TextLabel {
text: self.text.clone(),
x: self.x + offset_x,
- y: self.y + 4.0,
- font_size: 12.0,
+ y: text_y,
+ font_size: size,
color,
}]
} else {