filter non existing items before building the ui

This commit is contained in:
Alexander Mohr 2025-04-23 21:03:57 +02:00
parent a8f2917c20
commit 652f2218e6
2 changed files with 34 additions and 32 deletions

View file

@ -83,8 +83,9 @@ pub struct MenuItem<T: Clone> {
pub action: Option<String>, pub action: Option<String>,
pub sub_elements: Vec<MenuItem<T>>, pub sub_elements: Vec<MenuItem<T>>,
pub working_dir: Option<String>, pub working_dir: Option<String>,
pub initial_sort_score: i64, pub initial_sort_score: i64, // todo make this f64
pub search_sort_score: f64, pub search_sort_score: f64, // todo make this private
pub visible: bool, // todo make this private
/// Allows to store arbitrary additional information /// Allows to store arbitrary additional information
pub data: Option<T>, pub data: Option<T>,
@ -213,11 +214,6 @@ fn build_ui<T, P>(
let list_items: ArcMenuMap<T> = Arc::new(Mutex::new(HashMap::new())); let list_items: ArcMenuMap<T> = Arc::new(Mutex::new(HashMap::new()));
// let icon_cache: IconCache = Default::default(); // let icon_cache: IconCache = Default::default();
let elements = item_provider.lock().unwrap().get_elements(None); let elements = item_provider.lock().unwrap().get_elements(None);
// for e in elements {
// tokio::spawn(async move {
// lookup_icon(e, config);
// });
// }
build_ui_from_menu_items( build_ui_from_menu_items(
&elements, &elements,
@ -296,10 +292,12 @@ fn build_ui_from_menu_items<T: Clone + 'static>(
let cleared_box = Instant::now(); let cleared_box = Instant::now();
for entry in items { for entry in items {
arc_lock.insert( if entry.visible {
add_menu_item(inner_box, entry, config, sender, list_items, app, window), arc_lock.insert(
(*entry).clone(), add_menu_item(inner_box, entry, config, sender, list_items, app, window),
); (*entry).clone(),
);
}
} }
let created_ui = Instant::now(); let created_ui = Instant::now();
@ -359,7 +357,8 @@ fn handle_key_press<T: Clone + 'static>(
window_clone: &ApplicationWindow, window_clone: &ApplicationWindow,
keyboard_key: Key, keyboard_key: Key,
) -> Propagation { ) -> Propagation {
let update_view = |query: &String, items: Vec<MenuItem<T>>| { let update_view = |query: &String, items: &mut Vec<MenuItem<T>>| {
set_menu_visibility_for_search(query, items, config);
build_ui_from_menu_items( build_ui_from_menu_items(
&items, &items,
list_items, list_items,
@ -369,13 +368,12 @@ fn handle_key_press<T: Clone + 'static>(
app, app,
window_clone, window_clone,
); );
filter_widgets(query, list_items, config, inner_box);
select_first_visible_child(list_items, inner_box); select_first_visible_child(list_items, inner_box);
}; };
let update_view_from_provider = |query: &String| { let update_view_from_provider = |query: &String| {
let filtered_list = item_provider.lock().unwrap().get_elements(Some(query)); let mut filtered_list = item_provider.lock().unwrap().get_elements(Some(query));
update_view(query, filtered_list); update_view(query, &mut filtered_list);
}; };
match keyboard_key { match keyboard_key {
@ -415,14 +413,14 @@ fn handle_key_press<T: Clone + 'static>(
let lock = list_items.lock().unwrap(); let lock = list_items.lock().unwrap();
let menu_item = lock.get(fb); let menu_item = lock.get(fb);
if let Some(menu_item) = menu_item { if let Some(menu_item) = menu_item {
if let Some(new_items) = if let Some(mut new_items) =
item_provider.lock().unwrap().get_sub_elements(menu_item) item_provider.lock().unwrap().get_sub_elements(menu_item)
{ {
let query = menu_item.label.clone(); let query = menu_item.label.clone();
drop(lock); drop(lock);
search_entry.set_text(&query); search_entry.set_text(&query);
update_view(&query, new_items); update_view(&query, &mut new_items);
} }
} }
} }
@ -461,7 +459,7 @@ fn sort_menu_items_by_score<T: std::clone::Clone>(
match (m1, m2) { match (m1, m2) {
(Some(menu1), Some(menu2)) => { (Some(menu1), Some(menu2)) => {
if menu1.search_sort_score != 0.0 || menu2.search_sort_score != 0.0 { if menu1.search_sort_score > 0.0 || menu2.search_sort_score > 0.0 {
if menu1.search_sort_score < menu2.search_sort_score { if menu1.search_sort_score < menu2.search_sort_score {
Ordering::Smaller Ordering::Smaller
} else { } else {
@ -503,8 +501,7 @@ fn animate_window_show(config: &Config, window: ApplicationWindow, outer_box: gt
config.show_animation_time.unwrap_or(0), config.show_animation_time.unwrap_or(0),
target_height, target_height,
target_width, target_width,
move || { move || {},
},
); );
} }
} }
@ -925,22 +922,21 @@ fn lookup_icon<T: Clone>(menu_item: &MenuItem<T>, config: &Config) -> Option<Ima
} }
} }
fn filter_widgets<T: Clone>( fn set_menu_visibility_for_search<T: Clone>(
query: &str, query: &str,
item_arc: &ArcMenuMap<T>, items: &mut Vec<MenuItem<T>>,
config: &Config, config: &Config,
inner_box: &FlowBox,
) { ) {
{ {
let mut items = item_arc.lock().unwrap();
if query.is_empty() { if query.is_empty() {
for (flowbox_child, menu_item) in items.iter_mut() { for menu_item in items.iter_mut() {
flowbox_child.set_visible(true); // todo make initial score and search score both follow same logic.
menu_item.search_sort_score = -1.0; menu_item.search_sort_score = -menu_item.initial_sort_score as f64;
menu_item.visible = true;
} }
} else { } else {
let query = query.to_owned().to_lowercase(); // todo match case senstive according to conf let query = query.to_owned().to_lowercase(); // todo match case senstive according to conf
for (flowbox_child, menu_item) in items.iter_mut() { for menu_item in items.iter_mut() {
let menu_item_search = format!( let menu_item_search = format!(
"{} {}", "{} {}",
menu_item menu_item
@ -990,13 +986,13 @@ fn filter_widgets<T: Clone>(
} }
}; };
menu_item.search_sort_score = search_sort_score; // todo turn initial score init f64
flowbox_child.set_visible(visible); menu_item.search_sort_score =
search_sort_score - menu_item.initial_sort_score as f64;
menu_item.visible = visible;
} }
} }
} }
inner_box.invalidate_sort();
} }
fn select_first_visible_child<T: Clone>(lock: &ArcMenuMap<T>, inner_box: &FlowBox) { fn select_first_visible_child<T: Clone>(lock: &ArcMenuMap<T>, inner_box: &FlowBox) {

View file

@ -115,6 +115,7 @@ impl<T: Clone> DRunProvider<T> {
initial_sort_score: -(*sort_score), initial_sort_score: -(*sort_score),
search_sort_score: 0.0, search_sort_score: 0.0,
data: Some(menu_item_data.clone()), data: Some(menu_item_data.clone()),
visible: true,
}; };
file.actions.iter().for_each(|(_, action)| { file.actions.iter().for_each(|(_, action)| {
@ -140,6 +141,7 @@ impl<T: Clone> DRunProvider<T> {
initial_sort_score: 0, // subitems are never sorted right now. initial_sort_score: 0, // subitems are never sorted right now.
search_sort_score: 0.0, search_sort_score: 0.0,
data: None, data: None,
visible: true,
}; };
entry.sub_elements.push(sub_entry); entry.sub_elements.push(sub_entry);
} }
@ -280,6 +282,7 @@ impl<T: Clone> ItemProvider<T> for FileItemProvider<T> {
initial_sort_score: 0, initial_sort_score: 0,
search_sort_score: 0.0, search_sort_score: 0.0,
data: Some(self.menu_item_data.clone()), data: Some(self.menu_item_data.clone()),
visible: true,
}); });
} }
} }
@ -297,6 +300,7 @@ impl<T: Clone> ItemProvider<T> for FileItemProvider<T> {
initial_sort_score: 0, initial_sort_score: 0,
search_sort_score: 0.0, search_sort_score: 0.0,
data: Some(self.menu_item_data.clone()), data: Some(self.menu_item_data.clone()),
visible: true,
} }
}); });
} }
@ -353,6 +357,7 @@ impl<T: Clone> ItemProvider<T> for MathProvider<T> {
initial_sort_score: 0, initial_sort_score: 0,
search_sort_score: 0.0, search_sort_score: 0.0,
data: Some(self.menu_item_data.clone()), data: Some(self.menu_item_data.clone()),
visible: true,
}; };
vec![item] vec![item]
@ -390,6 +395,7 @@ impl DMenuProvider {
initial_sort_score: 0, initial_sort_score: 0,
search_sort_score: 0.0, search_sort_score: 0.0,
data: None, data: None,
visible: true,
}) })
.collect(); .collect();