From abf95c0189a6a037c95b2f2402097a74d4274dd5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 6 Feb 2025 09:26:20 -0700 Subject: [PATCH] Add icon size and grid spacing for desktop, fixes #751 --- i18n/en/cosmic_files.ftl | 1 + src/app.rs | 28 +++++++++++++++++++--------- src/config.rs | 22 ++++++++++++++++------ src/tab.rs | 22 +++++++++++++++------- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index ea05939..7d36216 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -19,6 +19,7 @@ mounted-drives = Mounted drives trash-folder-icon = Trash folder icon icon-size-and-spacing = Icon size and spacing icon-size = Icon size +grid-spacing = Grid spacing # List view name = Name diff --git a/src/app.rs b/src/app.rs index df56ebd..6cd4596 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1315,19 +1315,30 @@ impl App { ); children.push(section.into()); - /*TODO: Desktop icon size and spacing let mut section = widget::settings::section().title(fl!("icon-size-and-spacing")); - let grid: u16 = config.icon_sizes.grid.into(); + let icon_size: u16 = config.icon_size.into(); section = section.add( widget::settings::item::builder(fl!("icon-size")) - .description(format!("{}%", grid)) + .description(format!("{}%", icon_size)) .control( - widget::slider(50..=500, grid, move |grid| { + widget::slider(50..=500, icon_size, move |icon_size| { Message::DesktopConfig(DesktopConfig { - icon_sizes: IconSizes { - grid: NonZeroU16::new(grid).unwrap(), - ..config.icon_sizes - }, + icon_size: NonZeroU16::new(icon_size).unwrap(), + ..config + }) + }) + .step(25u16), + ), + ); + + let grid_spacing: u16 = config.grid_spacing.into(); + section = section.add( + widget::settings::item::builder(fl!("grid-spacing")) + .description(format!("{}%", grid_spacing)) + .control( + widget::slider(50..=500, grid_spacing, move |grid_spacing| { + Message::DesktopConfig(DesktopConfig { + grid_spacing: NonZeroU16::new(grid_spacing).unwrap(), ..config }) }) @@ -1335,7 +1346,6 @@ impl App { ), ); children.push(section.into()); - */ widget::column::with_children(children) .padding([0, space_l, space_l, space_l]) diff --git a/src/config.rs b/src/config.rs index 50dfcba..9b6aa0c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,6 +20,12 @@ pub const ICON_SIZE_GRID: u16 = 64; // TODO: 5 is an arbitrary number. Maybe there's a better icon size max pub const ICON_SCALE_MAX: u16 = 5; +macro_rules! percent { + ($perc:expr, $pixel:ident) => { + (($perc.get() as f32 * $pixel as f32) / 100.).clamp(1., ($pixel * ICON_SCALE_MAX) as _) + }; +} + #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum AppTheme { Dark, @@ -151,6 +157,8 @@ impl Default for Config { #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, CosmicConfigEntry, Deserialize, Serialize)] #[serde(default)] pub struct DesktopConfig { + pub grid_spacing: NonZeroU16, + pub icon_size: NonZeroU16, pub show_content: bool, pub show_mounted_drives: bool, pub show_trash: bool, @@ -159,6 +167,8 @@ pub struct DesktopConfig { impl Default for DesktopConfig { fn default() -> Self { Self { + grid_spacing: 100.try_into().unwrap(), + icon_size: 100.try_into().unwrap(), show_content: true, show_mounted_drives: false, show_trash: false, @@ -166,6 +176,12 @@ impl Default for DesktopConfig { } } +impl DesktopConfig { + pub fn grid_spacing_for(&self, space: u16) -> u16 { + percent!(self.grid_spacing, space) as _ + } +} + /// Global and local [`crate::tab::Tab`] config. /// /// [`TabConfig`] contains options that are passed to each instance of [`crate::tab::Tab`]. @@ -194,12 +210,6 @@ impl Default for TabConfig { } } -macro_rules! percent { - ($perc:expr, $pixel:ident) => { - (($perc.get() as f32 * $pixel as f32) / 100.).clamp(1., ($pixel * ICON_SCALE_MAX) as _) - }; -} - #[derive(Clone, Copy, Debug, Eq, PartialEq, CosmicConfigEntry, Deserialize, Serialize)] #[serde(default)] pub struct IconSizes { diff --git a/src/tab.rs b/src/tab.rs index 7613109..c73ef3f 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -822,8 +822,10 @@ pub fn scan_desktop( tab_path: &PathBuf, _display: &str, desktop_config: DesktopConfig, - sizes: IconSizes, + mut sizes: IconSizes, ) -> Vec { + sizes.grid = desktop_config.icon_size; + let mut items = Vec::new(); if desktop_config.show_content { @@ -3637,10 +3639,16 @@ impl Tab { let TabConfig { show_hidden, - icon_sizes, + mut icon_sizes, .. } = self.config; + let mut grid_spacing = space_xxs; + if let Location::Desktop(_path, _output, desktop_config) = &self.location { + icon_sizes.grid = desktop_config.icon_size; + grid_spacing = desktop_config.grid_spacing_for(space_xxs); + }; + let text_height = 3 * 20; // 3 lines of text let item_width = (3 * space_xxs + icon_sizes.grid() + 3 * space_xxs) as usize; let item_height = @@ -3658,7 +3666,7 @@ impl Tab { let (cols, column_spacing) = { let width_m1 = width.saturating_sub(item_width); - let cols_m1 = width_m1 / (item_width + space_xxs as usize); + let cols_m1 = width_m1 / (item_width + grid_spacing as usize); let cols = cols_m1 + 1; let spacing = width_m1 .checked_div(cols_m1) @@ -3669,13 +3677,13 @@ impl Tab { let rows = { let height_m1 = height.saturating_sub(item_height); - let rows_m1 = height_m1 / (item_height + space_xxs as usize); + let rows_m1 = height_m1 / (item_height + grid_spacing as usize); rows_m1 + 1 }; let mut grid = widget::grid() .column_spacing(column_spacing) - .row_spacing(space_xxs) + .row_spacing(grid_spacing) .padding(space_xxs.into()); let mut dnd_items: Vec<(usize, (usize, usize), &Item)> = Vec::new(); let mut drag_w_i = usize::MAX; @@ -3703,7 +3711,7 @@ impl Tab { item.rect_opt.set(Some(Rectangle::new( Point::new( (col * (item_width + column_spacing as usize) + space_m as usize) as f32, - (row * (item_height + space_xxs as usize)) as f32, + (row * (item_height + grid_spacing as usize)) as f32, ), Size::new(item_width as f32, item_height as f32), ))); @@ -3853,7 +3861,7 @@ impl Tab { (!dnd_items.is_empty()).then(|| { let mut dnd_grid = widget::grid() .column_spacing(column_spacing) - .row_spacing(space_xxs) + .row_spacing(grid_spacing) .padding(space_xxs.into()); let mut dnd_item_i = 0;