ui: Limit file name display length and ensure left alignment in file list

- Add MAX_DISPLAY_NAME_LEN constant (30 characters)
- Add truncate_display_name helper to truncate with ellipsis
- Apply truncation to folder names and file names
- Apply truncation to context menu file names
- Maintain left alignment through existing layout

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-09-14 16:13:43 -05:00
parent f64536ee9e
commit fbccad3a86
+24 -3
View File
@@ -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<String> {
/// 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<FileAction>) {
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() {