GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat: left-align button and toggle labels in the params pane
The rows form one column, but centered labels started each row's text at a
different x. Button already carried a `justify`, so its rows just opt in;
Toggle's label was hardcoded to centered, so it gains the same field and the
same `with_left_align`/`with_justify` builders, down to Button's 8px inset.
Set at the panel's construction sites rather than in the widgets: both are
shared across the DE, and menus, dialogs and cce-system-settings still center
their labels. Only the params pane opts in.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
src/widget/container/parameters_bg.rs | 6 ++++--
src/widget/input/checkbox.rs | 27 +++++++++++++++++++++++++--
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index 62f0520..35d777c 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -1882,7 +1882,9 @@ impl ParamController for ParametersBg {
}).collect();
self.buttons = self.display_params.iter().map(|p| {
if p.2 == "button" {
- Some(Button::new(0.0, 0.0, 0.0, 0.0).with_label(&p.0))
+ // Left-aligned, like the toggles below: the rows form one column, and
+ // centered labels made each row's text start at a different x.
+ Some(Button::new(0.0, 0.0, 0.0, 0.0).with_label(&p.0).with_left_align(true))
} else {
None
}
@@ -1907,7 +1909,7 @@ impl ParamController for ParametersBg {
self.toggles = self.display_params.iter().map(|p| {
if p.2 == "toggle" || p.2 == "checkbox" {
let on = p.1.trim().to_lowercase() == "true";
- let mut t = Toggle::new().with_label(&p.0);
+ let mut t = Toggle::new().with_label(&p.0).with_left_align(true);
t.set_toggled(on);
Some(t)
} else {
diff --git a/src/widget/input/checkbox.rs b/src/widget/input/checkbox.rs
index d9b530d..0dd87aa 100644
--- a/src/widget/input/checkbox.rs
+++ b/src/widget/input/checkbox.rs
@@ -12,7 +12,9 @@
use crate::colors;
use crate::scene::layout::Rect;
use crate::scene::paint::PaintCtx;
-use crate::widget::{Adapted, ElementState, Event, EventCtx, Input, Layout, MouseButton, Paint};
+use crate::widget::{
+ Adapted, ElementState, Event, EventCtx, Input, Justification, Layout, MouseButton, Paint,
+};
fn parse_bool(val: &str) -> Option<bool> {
match val.trim().to_lowercase().as_str() {
@@ -221,6 +223,9 @@ pub struct Toggle {
label: Option<String>,
hovered: bool,
focused: bool,
+ /// Where the label sits across the pill. Mirrors `Button::justify` — same enum, same
+ /// 8px edge inset — so the two read as one control set wherever they share a column.
+ justify: Justification,
}
impl Toggle {
@@ -231,6 +236,7 @@ impl Toggle {
label: None,
hovered: false,
focused: false,
+ justify: Justification::Center,
})
}
@@ -255,6 +261,18 @@ impl Toggle {
}
}
+impl Adapted<Toggle> {
+ pub fn with_left_align(mut self, left_align: bool) -> Self {
+ self.justify = if left_align { Justification::Left } else { Justification::Center };
+ self
+ }
+
+ pub fn with_justify(mut self, justify: Justification) -> Self {
+ self.justify = justify;
+ self
+ }
+}
+
impl Layout for Toggle {
fn inline_label(&self) -> bool {
true
@@ -340,9 +358,14 @@ impl Paint for Toggle {
if let Some(ref label) = self.label {
let (font_fam, font_size) = crate::layout::control_label_font_parsed();
let est_w = crate::widget::display::measure_text_width(label, &font_fam, font_size);
+ let tx = match self.justify {
+ Justification::Left => x + 8.0,
+ Justification::Right => x + w - est_w - 8.0,
+ Justification::Center => x + (w - est_w) / 2.0,
+ };
ctx.text(
label.clone(),
- x + (w - est_w) / 2.0,
+ tx,
crate::layout::align_text_y(y, h, font_size, 0.0),
font_size,
colors::control_label_color_for_state(self.hovered, self.focused),