diff --git a/src/app/file_list.rs b/src/app/file_list.rs index 4110247..6d8e744 100644 --- a/src/app/file_list.rs +++ b/src/app/file_list.rs @@ -4,6 +4,9 @@ use super::*; +/// Maximum number of characters to display for a file/folder name. +const MAX_DISPLAY_NAME_LEN: usize = 30; + /// Convert a manuscript folder path to its corresponding outline file path. /// /// For the snowflake template: @@ -40,6 +43,23 @@ fn outline_path_for_folder(folder_path: &str) -> Option { /// Horizontal indent per folder level, in points. const INDENT: f32 = 12.0; +/// Truncate a display name to the maximum length, adding ellipsis if needed. +fn truncate_display_name(name: &str) -> String { + if name.chars().count() <= MAX_DISPLAY_NAME_LEN { + name.to_string() + } else { + let mut s = String::new(); + for (i, c) in name.chars().enumerate() { + if i >= MAX_DISPLAY_NAME_LEN - 3 { + s.push_str("…"); + break; + } + s.push(c); + } + s + } +} + /// One drawn line of the file tree. pub(super) struct Row { /// Workspace-relative path: the folder for a folder row, the file for a @@ -255,7 +275,7 @@ impl App { let arrow = if open { "⏷" } else { "⏵" }; let label = format!( "{arrow} 🗀 {}", - base_name(&row.path) + truncate_display_name(base_name(&row.path)) ); let text = egui::RichText::new(label); let text = if in_book { @@ -384,7 +404,8 @@ impl App { - HANDLE_W - reserve) .max(24.0); - let text = egui::RichText::new(base_name(&name)); + let display_name = truncate_display_name(base_name(&name)); + let text = egui::RichText::new(display_name); let text = if in_book { text } else { text.weak() }; let mut label = ui.add_sized( [label_w, 20.0], @@ -613,7 +634,7 @@ impl FileAction { /// The right-click menu on a file row, offering the same operations as the /// buttons under the list without having to select the file first. fn file_context_menu(ui: &mut egui::Ui, name: &str, idx: usize, action: &mut Option) { - ui.label(egui::RichText::new(base_name(name)).strong()); + ui.label(egui::RichText::new(truncate_display_name(base_name(name))).strong()); ui.separator(); let mut pick = |ui: &mut egui::Ui, label: &str, hover: &str, chosen: FileAction| { if ui.button(label).on_hover_text(hover).clicked() {