From 197398fe4ec21651ca5d2d84f3ff591e2e12ff76 Mon Sep 17 00:00:00 2001 From: Dominic Gerhauser Date: Thu, 29 Feb 2024 03:46:14 +0100 Subject: [PATCH] refactor sorting --- src/tab.rs | 155 ++++++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/src/tab.rs b/src/tab.rs index 0f4b655..1ba9e85 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -542,15 +542,15 @@ pub struct Tab { pub history_i: usize, pub history: Vec, pub config: TabConfig, - //TODO: this no longer needs to be a map - sort_map: HashMap, + sort_name: HeadingOptions, + sort_direction: bool, } impl Tab { pub fn new(location: Location, config: TabConfig) -> Self { let history = vec![location.clone()]; - let mut sort_map = HashMap::new(); - sort_map.insert(HeadingOptions::Name, true); + let sort_name = HeadingOptions::Name; + let sort_direction = true; Self { location, context_menu: None, @@ -564,7 +564,8 @@ impl Tab { history_i: 0, history, config, - sort_map, + sort_name, + sort_direction, } } @@ -840,69 +841,13 @@ impl Tab { self.view = view; } Message::ToggleSort(heading_option) => { - let heading_sort = !self.sort_map.get(&heading_option).unwrap_or(&false); - self.sort_map.clear(); - self.sort_map.insert(heading_option, heading_sort); - let check_reverse = |ord: Ordering, sort: bool| { - if sort { - ord - } else { - ord.reverse() - } + let heading_sort = if self.sort_name == heading_option { + !self.sort_direction + } else { + true }; - if let Some(item) = &mut self.items_opt { - match heading_option { - HeadingOptions::Size => { - item.sort_by(|a, b| { - // entries take precedence over size - let get_size = |x: &Item| match &x.metadata { - ItemMetadata::Path { metadata, children } => { - if metadata.is_dir() { - (true, *children as u64) - } else { - (false, metadata.len()) - } - } - ItemMetadata::Trash { metadata, .. } => match metadata.size { - trash::TrashItemSize::Entries(entries) => { - (true, entries as u64) - } - trash::TrashItemSize::Bytes(bytes) => (false, bytes), - }, - }; - let (a_is_entry, a_size) = get_size(a); - let (b_is_entry, b_size) = get_size(b); - - let ord = match (a_is_entry, b_is_entry) { - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - _ => a_size.cmp(&b_size), - }; - check_reverse(ord, heading_sort) - }) - } - HeadingOptions::Name => item.sort_by(|a, b| { - let ord = match (a.path.is_dir(), b.path.is_dir()) { - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - _ => lexical_sort::natural_lexical_cmp(&a.name, &b.name), - }; - check_reverse(ord, heading_sort) - }), - HeadingOptions::Modified => { - item.sort_by(|a, b| { - let get_modified = |x: &Item| match &x.metadata { - ItemMetadata::Path { metadata, .. } => metadata.modified().ok(), - ItemMetadata::Trash { .. } => None, - }; - - let a = get_modified(a); - let b = get_modified(b); - check_reverse(a.cmp(&b), heading_sort) - }); - } - } - } + self.sort_direction = heading_sort; + self.sort_name = heading_option; } } if let Some(location) = cd { @@ -927,6 +872,68 @@ impl Tab { commands } + fn column_sort(&self) -> Option> { + let check_reverse = |ord: Ordering, sort: bool| { + if sort { + ord + } else { + ord.reverse() + } + }; + let mut item = self.items_opt.clone()?; + let heading_sort = self.sort_direction; + match self.sort_name { + HeadingOptions::Size => { + item.sort_by(|a, b| { + // entries take precedence over size + let get_size = |x: &Item| match &x.metadata { + ItemMetadata::Path { metadata, children } => { + if metadata.is_dir() { + (true, *children as u64) + } else { + (false, metadata.len()) + } + } + ItemMetadata::Trash { metadata, .. } => match metadata.size { + trash::TrashItemSize::Entries(entries) => (true, entries as u64), + trash::TrashItemSize::Bytes(bytes) => (false, bytes), + }, + }; + let (a_is_entry, a_size) = get_size(a); + let (b_is_entry, b_size) = get_size(b); + + let ord = match (a_is_entry, b_is_entry) { + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + _ => a_size.cmp(&b_size), + }; + check_reverse(ord, heading_sort) + }) + } + HeadingOptions::Name => item.sort_by(|a, b| { + let ord = match (a.path.is_dir(), b.path.is_dir()) { + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + _ => lexical_sort::natural_lexical_cmp(&a.name, &b.name), + }; + check_reverse(ord, heading_sort) + }), + HeadingOptions::Modified => { + item.sort_by(|a, b| { + let get_modified = |x: &Item| match &x.metadata { + ItemMetadata::Path { metadata, .. } => metadata.modified().ok(), + ItemMetadata::Trash { .. } => None, + }; + + let a = get_modified(a); + let b = get_modified(b); + check_reverse(a.cmp(&b), heading_sort) + }); + } + } + Some(item) + } + pub fn location_view(&self, core: &Core) -> Element { let cosmic_theme::Spacing { space_xxxs, @@ -1168,11 +1175,13 @@ impl Tab { ($name: literal, $width: expr, $msg: expr) => { widget::row::with_children(vec![ widget::text::heading(fl!($name)).into(), - widget::button(widget::icon::from_name(match self.sort_map.get(&$msg) { - Some(true) => "go-down-symbolic", - Some(false) => "go-up-symbolic", - None => "list-remove-symbolic", - })) + widget::button(widget::icon::from_name( + match (self.sort_name == $msg, self.sort_direction) { + (true, true) => "go-down-symbolic", + (true, false) => "go-up-symbolic", + _ => "list-remove-symbolic", + }, + )) .on_press(Message::ToggleSort($msg)) .style(cosmic::style::Button::Icon) .into(), @@ -1200,7 +1209,7 @@ impl Tab { children.push(horizontal_rule(1).into()); - if let Some(ref items) = self.items_opt { + if let Some(ref items) = self.column_sort() { let mut count = 0; let mut hidden = 0; let TabConfig {