gardesk/garfield / 7de21be

Browse files

app picker: increase item height, fix description truncation to fit width

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
7de21be3fe9a57c292d486fb7cd6aeaf2309d015
Parents
67f51e9
Tree
9a441c8

1 changed file

StatusFile+-
M garfield/src/ui/app_picker.rs 53 14
garfield/src/ui/app_picker.rsmodified
@@ -16,7 +16,7 @@ use std::path::PathBuf;
1616
 const MAX_VISIBLE_ITEMS: usize = 8;
1717
 
1818
 /// Item height in pixels (name + description + padding).
19
-const ITEM_HEIGHT: u32 = 48;
19
+const ITEM_HEIGHT: u32 = 54;
2020
 
2121
 /// Input field height.
2222
 const INPUT_HEIGHT: u32 = 36;
@@ -109,6 +109,46 @@ fn clean_exec_command(exec: &str) -> String {
109109
     result.trim().to_string()
110110
 }
111111
 
112
+/// Truncate text to fit within a given pixel width, adding ellipsis if needed.
113
+fn truncate_to_width(text: &str, max_width: f64, style: &TextStyle, renderer: &Renderer) -> String {
114
+    let max_width = max_width as u32;
115
+
116
+    // First check if it fits
117
+    if let Ok(metrics) = renderer.measure_text(text, style) {
118
+        if metrics.width <= max_width {
119
+            return text.to_string();
120
+        }
121
+    }
122
+
123
+    // Binary search for the right length
124
+    let ellipsis = "...";
125
+    let ellipsis_width = renderer.measure_text(ellipsis, style)
126
+        .map(|m| m.width)
127
+        .unwrap_or(20);
128
+
129
+    if max_width <= ellipsis_width {
130
+        return ellipsis.to_string();
131
+    }
132
+
133
+    let target_width = max_width - ellipsis_width;
134
+
135
+    // Start from full text and shrink
136
+    let chars: Vec<char> = text.chars().collect();
137
+    let mut end = chars.len();
138
+
139
+    while end > 0 {
140
+        let substr: String = chars[..end].iter().collect();
141
+        if let Ok(metrics) = renderer.measure_text(&substr, style) {
142
+            if metrics.width <= target_width {
143
+                return format!("{}{}", substr, ellipsis);
144
+            }
145
+        }
146
+        end -= 1;
147
+    }
148
+
149
+    ellipsis.to_string()
150
+}
151
+
112152
 /// Get XDG application directories to scan.
113153
 fn get_app_directories() -> Vec<PathBuf> {
114154
     let mut dirs = Vec::new();
@@ -643,29 +683,28 @@ impl AppPickerDialog {
643683
                 renderer.fill_rounded_rect(item_rect, 4.0, theme.item_hover_background)?;
644684
             }
645685
 
646
-            // App name (positioned near top of item)
647
-            let name_y = item_y + 10;
686
+            // Available width for text (with padding on both sides)
687
+            let text_x = item_rect.x + 12;
688
+            let available_width = (item_rect.width as i32 - 24) as f64;
689
+
690
+            // App name (positioned near top of item with more padding)
691
+            let name_y = item_y + 12;
648692
             renderer.text(
649693
                 &app.name,
650
-                (item_rect.x + 12) as f64,
694
+                text_x as f64,
651695
                 name_y as f64,
652696
                 &name_style,
653697
             )?;
654698
 
655699
             // App description (if any, positioned below name with gap)
656700
             if let Some(desc) = &app.description {
657
-                // Truncate long descriptions
658
-                let max_desc_len = 70;
659
-                let truncated = if desc.len() > max_desc_len {
660
-                    format!("{}...", &desc[..max_desc_len])
661
-                } else {
662
-                    desc.clone()
663
-                };
664
-
665
-                let desc_y = name_y + (theme.font_size as i32) + 6;
701
+                // Truncate description to fit available width
702
+                let truncated = truncate_to_width(desc, available_width, &desc_style, renderer);
703
+
704
+                let desc_y = name_y + (theme.font_size as i32) + 8;
666705
                 renderer.text(
667706
                     &truncated,
668
-                    (item_rect.x + 12) as f64,
707
+                    text_x as f64,
669708
                     desc_y as f64,
670709
                     &desc_style,
671710
                 )?;