filter non existing items before building the ui
This commit is contained in:
parent
a8f2917c20
commit
652f2218e6
2 changed files with 34 additions and 32 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue