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

commit6f42714a0fc2be18262958851ade459c0d8f26cc
parentaf7857f5de
authorLucas Galante <[email protected]>
date2026-06-16 16:49
layout: make button size dependent on text length in ButtonStrip

 src/widget/input/button_strip.rs | 61 ++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/src/widget/input/button_strip.rs b/src/widget/input/button_strip.rs
index bcb9e38..1c856ad 100644
--- a/src/widget/input/button_strip.rs
+++ b/src/widget/input/button_strip.rs
@@ -176,18 +176,61 @@ impl ButtonStrip {
         }
         let n = self.buttons.len() as f32;
         let (x, y, w, h) = self.rect();
+
+        let get_button_weight = |i: usize| -> f32 {
+            let label = &self.buttons[i];
+            let trimmed = label.trim();
+            if self.vertical {
+                let has_icon = trimmed.find(' ').is_some();
+                let label_text = if let Some(space_idx) = trimmed.find(' ') {
+                    trimmed.split_at(space_idx).1.trim()
+                } else {
+                    trimmed
+                };
+                let padding_y = crate::layout::paginator_tab_padding_y();
+                let y_offset = if has_icon { 2.0 * padding_y + 12.0 } else { 0.0 };
+                let text_w = TextLabel::estimate_width(label_text, 12.0);
+                (text_w + y_offset).max(1.0)
+            } else {
+                let text_w = TextLabel::estimate_width(label, 12.0);
+                text_w.max(1.0)
+            }
+        };
+
+        let mut weights = Vec::new();
+        let mut total_weight = 0.0;
+        for i in 0..self.buttons.len() {
+            let wt = get_button_weight(i);
+            weights.push(wt);
+            total_weight += wt;
+        }
+
         if self.vertical {
             let spacing = 8.0;
-            let max_btn_h = if n > 1.0 {
-                (h - spacing * (n - 1.0)) / n
-            } else {
-                h
-            };
-            let btn_h = max_btn_h.min(144.0).max(0.0);
-            (x, y + idx as f32 * (btn_h + spacing), w, btn_h)
+            let total_spacing = spacing * (n - 1.0);
+            let available_h = (h - total_spacing).max(0.0);
+            
+            let mut current_y = y;
+            let mut btn_h = 0.0;
+            for i in 0..=idx {
+                let share = if total_weight > 0.0 { weights[i] / total_weight } else { 1.0 / n };
+                btn_h = share * available_h;
+                if i < idx {
+                    current_y += btn_h + spacing;
+                }
+            }
+            (x, current_y, w, btn_h)
         } else {
-            let btn_w = w / n;
-            (x + idx as f32 * btn_w, y, btn_w, h)
+            let mut current_x = x;
+            let mut btn_w = 0.0;
+            for i in 0..=idx {
+                let share = if total_weight > 0.0 { weights[i] / total_weight } else { 1.0 / n };
+                btn_w = share * w;
+                if i < idx {
+                    current_x += btn_w;
+                }
+            }
+            (current_x, y, btn_w, h)
         }
     }
 }