From d31e103f65b7b9077ae8e88a5bddc2c9a2b043a7 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 9 Jul 2024 11:16:14 -0600 Subject: [PATCH] Ellipsize breadcrumbs that do not fit, fixes #189 --- Cargo.lock | 66 ++++++++++++++--------------- Cargo.toml | 1 - src/tab.rs | 122 +++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 128 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58bb73a..f056f6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -851,9 +851,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.106" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" +checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" dependencies = [ "jobserver", "libc", @@ -1132,7 +1132,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1151,7 +1151,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "quote", "syn 1.0.109", @@ -1240,7 +1240,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "almost", "cosmic-config", @@ -1362,9 +1362,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -1372,9 +1372,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", @@ -1386,9 +1386,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", @@ -2655,7 +2655,7 @@ dependencies = [ [[package]] name = "iced" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "dnd", "iced_accessibility", @@ -2674,7 +2674,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "accesskit", "accesskit_unix", @@ -2684,7 +2684,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "bitflags 2.6.0", "dnd", @@ -2706,7 +2706,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "futures", "iced_core", @@ -2719,7 +2719,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "bitflags 2.6.0", "bytemuck", @@ -2743,7 +2743,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2755,7 +2755,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "dnd", "iced_accessibility", @@ -2769,7 +2769,7 @@ dependencies = [ [[package]] name = "iced_sctk" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "enum-repr", "float-cmp", @@ -2796,7 +2796,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "iced_core", "once_cell", @@ -2806,7 +2806,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "bytemuck", "cosmic-text", @@ -2823,7 +2823,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "bitflags 2.6.0", "bytemuck", @@ -2849,7 +2849,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "dnd", "iced_accessibility", @@ -2867,7 +2867,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "dnd", "iced_accessibility", @@ -3615,7 +3615,7 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git?branch=text-wrap#e0776c2fc6067cac939d21e9b83aaf6fc64a6e4a" +source = "git+https://github.com/pop-os/libcosmic.git#c9a2265ab192af4d1270e96b0d73cb06163ece96" dependencies = [ "apply", "ashpd", @@ -5003,9 +5003,9 @@ checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" [[package]] name = "rust-embed" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" +checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -5014,9 +5014,9 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4" +checksum = "6125dbc8867951125eec87294137f4e9c2c96566e61bf72c45095a7c77761478" dependencies = [ "proc-macro2", "quote", @@ -5027,9 +5027,9 @@ dependencies = [ [[package]] name = "rust-embed-utils" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32" +checksum = "2e5347777e9aacb56039b0e1f28785929a8a3b709e87482e7442c72e7c12529d" dependencies = [ "sha2", "walkdir", @@ -6253,9 +6253,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vergen" -version = "8.3.1" +version = "8.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" +checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" dependencies = [ "anyhow", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 2a991c9..d5976e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,6 @@ slotmap = "1.0.7" [dependencies.libcosmic] git = "https://github.com/pop-os/libcosmic.git" -branch = "text-wrap" default-features = false features = ["a11y", "multi-window", "tokio"] diff --git a/src/tab.rs b/src/tab.rs index d4e8905..d38f54c 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -5,9 +5,12 @@ use cosmic::widget::menu::action::MenuAction; use cosmic::widget::menu::key_bind::KeyBind; use cosmic::widget::{vertical_space, Id, Widget}; use cosmic::{ - cosmic_theme, + cosmic_theme, font, iced::{ - advanced::text, + advanced::{ + graphics, + text::{self, Paragraph}, + }, alignment::{Horizontal, Vertical}, futures::SinkExt, keyboard::Modifiers, @@ -1858,14 +1861,46 @@ impl Tab { } pub fn location_view(&self) -> Element { + //TODO: responsiveness is done in a hacky way, potentially move this to a custom widget? + fn text_width<'a>( + content: &'a str, + font: font::Font, + font_size: f32, + line_height: f32, + ) -> f32 { + let text: text::Text<'a, font::Font> = text::Text { + content, + bounds: Size::INFINITY, + size: font_size.into(), + line_height: text::LineHeight::Absolute(line_height.into()), + font, + horizontal_alignment: Horizontal::Left, + vertical_alignment: Vertical::Top, + shaping: text::Shaping::default(), + wrap: text::Wrap::None, + }; + graphics::text::Paragraph::with_text(text) + .min_bounds() + .width + } + fn text_width_body<'a>(content: &'a str) -> f32 { + //TODO: should libcosmic set the font when using widget::text::body? + text_width(content, font::Font::DEFAULT, 14.0, 20.0) + } + fn text_width_heading<'a>(content: &'a str) -> f32 { + text_width(content, font::FONT_SEMIBOLD, 14.0, 20.0) + } + let cosmic_theme::Spacing { space_xxxs, space_xxs, space_s, .. } = theme::active().cosmic().spacing; + let size = self.size_opt.get().unwrap_or(Size::new(0.0, 0.0)); let mut row = widget::row::with_capacity(5).align_items(Alignment::Center); + let mut w = 0.0; let mut prev_button = widget::button(widget::icon::from_name("go-previous-symbolic").size(16)) @@ -1875,6 +1910,7 @@ impl Tab { prev_button = prev_button.on_press(Message::GoPrevious); } row = row.push(prev_button); + w += 16.0 + 2.0 * space_xxs as f32; let mut next_button = widget::button(widget::icon::from_name("go-next-symbolic").size(16)) .padding(space_xxs) @@ -1883,8 +1919,10 @@ impl Tab { next_button = next_button.on_press(Message::GoNext); } row = row.push(next_button); + w += 16.0 + 2.0 * space_xxs as f32; row = row.push(widget::horizontal_space(Length::Fixed(space_s.into()))); + w += space_s as f32; if let Some(location) = &self.edit_location { match location { @@ -1919,6 +1957,7 @@ impl Tab { .on_press(move |_| Message::EditLocation(Some(self.location.clone()))) .on_middle_press(move |_| Message::OpenInNewTab(path.clone())), ); + w += 16.0 + 2.0 * space_xxs as f32; } else if let Location::Search(_, term) = &self.location { row = row.push( widget::button( @@ -1926,53 +1965,56 @@ impl Tab { widget::icon::from_name("system-search-symbolic") .size(16) .into(), - widget::text(term).into(), + widget::text::body(term).wrap(text::Wrap::None).into(), ]) .spacing(space_xxs), ) .padding(space_xxs) .style(theme::Button::Icon), ); + w += text_width_body(term) + 16.0 + 3.0 * space_xxs as f32; } let mut children: Vec> = Vec::new(); match &self.location { Location::Path(path) | Location::Search(path, ..) => { let home_dir = crate::home_dir(); + let excess_str = "..."; + let excess_width = text_width_body(excess_str); for (index, ancestor) in path.ancestors().enumerate() { let mut found_home = false; - let mut row = widget::row::with_capacity(2) - .align_items(Alignment::Center) - .spacing(space_xxxs); - - let name = match ancestor.file_name() { + let (name, icon_opt) = match ancestor.file_name() { Some(name) => { if ancestor == home_dir { - row = row.push( - widget::icon::icon(folder_icon_symbolic( - &ancestor.to_path_buf(), - 16, - )) - .size(16), - ); + let icon = widget::icon::icon(folder_icon_symbolic( + &ancestor.to_path_buf(), + 16, + )) + .size(16); found_home = true; - fl!("home") + (fl!("home"), Some(icon)) } else { - name.to_string_lossy().to_string() + (name.to_string_lossy().to_string(), None) } } None => { - row = row.push( - widget::icon::from_name("drive-harddisk-system-symbolic") - .size(16) - .icon(), - ); - fl!("filesystem") + let icon = widget::icon::from_name("drive-harddisk-system-symbolic") + .size(16) + .icon(); + (fl!("filesystem"), Some(icon)) } }; + let icon_width = if icon_opt.is_some() { + 16.0 + space_xxxs as f32 + } else { + 0.0 + }; - if children.is_empty() { - row = row.push(widget::text::heading(name).wrap(text::Wrap::None)); + let (name_width, name_text) = if children.is_empty() { + ( + text_width_heading(&name), + widget::text::heading(name).wrap(text::Wrap::None), + ) } else { children.push( widget::icon::from_name("go-next-symbolic") @@ -1980,7 +2022,33 @@ impl Tab { .icon() .into(), ); - row = row.push(widget::text::body(name).wrap(text::Wrap::None)); + w += 16.0; + ( + text_width_body(&name), + widget::text::body(name).wrap(text::Wrap::None), + ) + }; + + // Add padding for mouse area + w += 2.0 * space_xxxs as f32; + + let mut row = widget::row::with_capacity(2) + .align_items(Alignment::Center) + .spacing(space_xxxs); + //TODO: figure out why this hardcoded offset is needed after the first item is ellipsed + let overflow_offset = if icon_opt.is_some() { 0.0 } else { 32.0 }; + let overflow = + w + icon_width + name_width + overflow_offset > size.width && index > 0; + if overflow { + row = row.push(widget::text::body(excess_str)); + w += excess_width; + } else { + if let Some(icon) = icon_opt { + row = row.push(icon); + w += icon_width; + } + row = row.push(name_text); + w += name_width; } let mut mouse_area = crate::mouse_area::MouseArea::new( @@ -2017,7 +2085,7 @@ impl Tab { children.push(mouse_area.into()); - if found_home { + if found_home || overflow { break; } }