From b18a44fd47e8635f0911db97449852c0d94cb533 Mon Sep 17 00:00:00 2001 From: Alexander Mohr Date: Fri, 25 Apr 2025 21:21:32 +0200 Subject: [PATCH] add constructor for menu item --- src/lib/gui.rs | 55 +++++++++++++++-------- src/lib/mode.rs | 117 +++++++++++++++++++----------------------------- 2 files changed, 84 insertions(+), 88 deletions(-) diff --git a/src/lib/gui.rs b/src/lib/gui.rs index b709f0d..e82479a 100644 --- a/src/lib/gui.rs +++ b/src/lib/gui.rs @@ -84,12 +84,37 @@ pub struct MenuItem { pub action: Option, pub sub_elements: Vec>, pub working_dir: Option, - pub initial_sort_score: i64, // todo make this f64 - pub search_sort_score: f64, // todo make this private - pub visible: bool, // todo make this private + pub initial_sort_score: f64, /// Allows to store arbitrary additional information pub data: Option, + + search_sort_score: f64, + visible: bool, +} + +impl MenuItem { + pub fn new( + label: String, + icon_path: Option, + action: Option, + sub_elements: Vec>, + working_dir: Option, + initial_sort_score: f64, + data: Option, + ) -> Self { + MenuItem { + label, + icon_path, + action, + sub_elements, + working_dir, + initial_sort_score, + data, + search_sort_score: 0.0, + visible: true, + } + } } impl AsRef> for MenuItem { @@ -671,7 +696,7 @@ where action: None, sub_elements: Vec::new(), working_dir: None, - initial_sort_score: 0, + initial_sort_score: 0.0, search_sort_score: 0.0, data: None, visible: true, @@ -776,9 +801,9 @@ fn create_menu_row( row.set_halign(Align::Fill); row.set_widget_name("row"); + let config_clone = config.clone(); let click = GestureClick::new(); click.set_button(gdk::BUTTON_PRIMARY); - let config_clone = config.clone(); click.connect_pressed(move |_gesture, n_press, _x, _y| { if n_press == 2 { if let Err(e) = handle_selected_item( @@ -795,7 +820,6 @@ fn create_menu_row( } } }); - row.add_controller(click); let row_box = gtk4::Box::new( @@ -880,8 +904,7 @@ fn set_menu_visibility_for_search( { if query.is_empty() { for menu_item in items.iter_mut() { - // todo make initial score and search score both follow same logic. - menu_item.search_sort_score = menu_item.initial_sort_score as f64; + menu_item.search_sort_score = menu_item.initial_sort_score; menu_item.visible = true; } } else { @@ -936,9 +959,7 @@ fn set_menu_visibility_for_search( } }; - // todo turn initial score init f64 - menu_item.search_sort_score = - search_sort_score + menu_item.initial_sort_score as f64; + menu_item.search_sort_score = search_sort_score + menu_item.initial_sort_score; menu_item.visible = visible; } } @@ -979,17 +1000,15 @@ fn percent_or_absolute(value: Option<&String>, base_value: i32) -> Option { // highly unlikely that we are dealing with > i64 items #[allow(clippy::cast_possible_wrap)] -pub fn sort_menu_items_alphabetically_honor_initial_score( - items: &mut [MenuItem], -) { - let special_score = items.len() as i64; - let mut regular_score = 0; +pub fn sort_menu_items_alphabetically_honor_initial_score(items: &mut [MenuItem]) { + let special_score = items.len() as f64; + let mut regular_score = 0.0; items.sort_by(|l, r| l.label.cmp(&r.label)); for item in items.iter_mut() { - if item.initial_sort_score == 0 { + if item.initial_sort_score == 0.0 { item.initial_sort_score += regular_score; - regular_score += 1; + regular_score += 1.0; } else { item.initial_sort_score += special_score; } diff --git a/src/lib/mode.rs b/src/lib/mode.rs index 91eeed0..8bb6721 100644 --- a/src/lib/mode.rs +++ b/src/lib/mode.rs @@ -108,19 +108,17 @@ impl DRunProvider { .map(|s| s.content.clone()) .or(Some(default_icon.clone())); - let sort_score = *self.cache.get(&name).unwrap_or(&0); + let sort_score = *self.cache.get(&name).unwrap_or(&0) as f64; - let mut entry = MenuItem { - label: name.clone(), - icon_path: icon.clone(), - action: action.clone(), - sub_elements: Vec::new(), - working_dir: working_dir.clone(), - initial_sort_score: sort_score, - search_sort_score: 0.0, - data: Some(self.data.clone()), - visible: true, - }; + let mut entry = MenuItem::new( + name.clone(), + icon.clone(), + action.clone(), + Vec::new(), + working_dir.clone(), + sort_score, + Some(self.data.clone()), + ); for (_, action) in &file.actions { if let Some(action_name) = lookup_name_with_locale( @@ -136,17 +134,15 @@ impl DRunProvider { .unwrap_or("application-x-executable".to_string()); - entry.sub_elements.push(MenuItem { - label: action_name, - icon_path: Some(action_icon), - action: action.exec.clone(), - sub_elements: Vec::new(), - working_dir: working_dir.clone(), - initial_sort_score: 0, - search_sort_score: 0.0, - data: Some(self.data.clone()), - visible: true, - }); + entry.sub_elements.push(MenuItem::new( + action_name, + Some(action_icon), + action.exec.clone(), + Vec::new(), + working_dir.clone(), + 0.0, + Some(self.data.clone()), + )); } } @@ -279,37 +275,31 @@ impl ItemProvider for FileItemProvider { path_str.push('/'); } - items.push(MenuItem { - label: path_str.clone(), - icon_path: Some(FileItemProvider::::resolve_icon_for_name( - &entry.path(), - )), - action: Some(format!("xdg-open {path_str}")), - sub_elements: vec![], - working_dir: None, - initial_sort_score: 0, - search_sort_score: 0.0, - data: Some(self.menu_item_data.clone()), - visible: true, - }); + items.push(MenuItem::new( + path_str.clone(), + Some(FileItemProvider::::resolve_icon_for_name(&entry.path())), + Some(format!("xdg-open {path_str}")), + vec![], + None, + 0.0, + Some(self.menu_item_data.clone()), + )); } } } } else { items.push({ - MenuItem { - label: trimmed_search.clone(), - icon_path: Some(FileItemProvider::::resolve_icon_for_name( + MenuItem::new( + trimmed_search.clone(), + Some(FileItemProvider::::resolve_icon_for_name( &PathBuf::from(&trimmed_search), )), - action: Some(format!("xdg-open {trimmed_search}")), - sub_elements: vec![], - working_dir: None, - initial_sort_score: 0, - search_sort_score: 0.0, - data: Some(self.menu_item_data.clone()), - visible: true, - } + Some(format!("xdg-open {trimmed_search}")), + vec![], + None, + 0.0, + Some(self.menu_item_data.clone()), + ) }); } @@ -356,18 +346,15 @@ impl ItemProvider for MathProvider { Err(e) => format!("failed to calculate {e:?}"), }; - let item = MenuItem { - label: result, - icon_path: None, - action: search.map(String::from), - sub_elements: vec![], - working_dir: None, - initial_sort_score: 0, - search_sort_score: 0.0, - data: Some(self.menu_item_data.clone()), - visible: true, - }; - + let item = MenuItem::new( + result, + None, + search.map(String::from), + vec![], + None, + 0.0, + Some(self.menu_item_data.clone()), + ); vec![item] } else { vec![] @@ -394,17 +381,7 @@ impl DMenuProvider { let items: Vec> = input .lines() .map(String::from) - .map(|s| MenuItem { - label: s, - icon_path: None, - action: None, - sub_elements: vec![], - working_dir: None, - initial_sort_score: 0, - search_sort_score: 0.0, - data: None, - visible: true, - }) + .map(|s| MenuItem::new(s.clone(), None, None, vec![], None, 0.0, None)) .collect(); Ok(Self { items })