Find selected list item by id instead of by index
This commit is contained in:
parent
3cbf7dd341
commit
d8aa3cf267
@ -10,6 +10,10 @@ pub struct DesktopEntry {
|
||||
}
|
||||
|
||||
impl LauncherListItem for DesktopEntry {
|
||||
fn id(&self) -> String {
|
||||
self.id.clone()
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
return self.name.to_owned();
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ pub struct WaycastLauncher {
|
||||
plugins_show_always: Vec<Arc<dyn LauncherPlugin>>,
|
||||
plugins_by_prefix: HashMap<String, Arc<dyn LauncherPlugin>>,
|
||||
current_results: Vec<Box<dyn LauncherListItem>>,
|
||||
current_results_by_id: HashMap<String, usize>,
|
||||
}
|
||||
|
||||
impl WaycastLauncher {
|
||||
@ -16,6 +17,7 @@ impl WaycastLauncher {
|
||||
plugins_show_always: Vec::new(),
|
||||
plugins_by_prefix: HashMap::new(),
|
||||
current_results: Vec::new(),
|
||||
current_results_by_id: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,23 +49,39 @@ impl WaycastLauncher {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_default_results(&mut self) -> &Vec<Box<dyn LauncherListItem>> {
|
||||
self.current_results.clear();
|
||||
for plugin in &self.plugins_show_always {
|
||||
for entry in plugin.default_list() {
|
||||
self.current_results.push(entry);
|
||||
fn add_current_item(&mut self, item: Box<dyn LauncherListItem>) {
|
||||
let id = item.id();
|
||||
let index = self.current_results.len();
|
||||
self.current_results.push(item);
|
||||
self.current_results_by_id.insert(id, index);
|
||||
}
|
||||
|
||||
fn clear_current_results(&mut self) {
|
||||
self.current_results.clear();
|
||||
self.current_results_by_id.clear();
|
||||
}
|
||||
|
||||
pub fn get_default_results(&mut self) -> &Vec<Box<dyn LauncherListItem>> {
|
||||
self.clear_current_results();
|
||||
let mut all_entries = Vec::new();
|
||||
for plugin in &self.plugins_show_always {
|
||||
all_entries.extend(plugin.default_list());
|
||||
}
|
||||
for entry in all_entries {
|
||||
self.add_current_item(entry);
|
||||
}
|
||||
&self.current_results
|
||||
}
|
||||
|
||||
pub fn search(&mut self, query: &str) -> &Vec<Box<dyn LauncherListItem>> {
|
||||
self.current_results.clear();
|
||||
self.clear_current_results();
|
||||
|
||||
let mut all_entries = Vec::new();
|
||||
for plugin in &self.plugins {
|
||||
for entry in plugin.filter(query) {
|
||||
self.current_results.push(entry);
|
||||
all_entries.extend(plugin.filter(query));
|
||||
}
|
||||
for entry in all_entries {
|
||||
self.add_current_item(entry);
|
||||
}
|
||||
|
||||
&self.current_results
|
||||
@ -77,6 +95,18 @@ impl WaycastLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_item_by_id(&self, id: &str) -> Result<(), crate::LaunchError> {
|
||||
if let Some(&index) = self.current_results_by_id.get(id) {
|
||||
if let Some(item) = self.current_results.get(index) {
|
||||
item.execute()
|
||||
} else {
|
||||
Err(crate::LaunchError::CouldNotLaunch("Item index out of bounds".into()))
|
||||
}
|
||||
} else {
|
||||
Err(crate::LaunchError::CouldNotLaunch("Item not found".into()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_results(&self) -> &Vec<Box<dyn LauncherListItem>> {
|
||||
&self.current_results
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ pub enum LaunchError {
|
||||
}
|
||||
|
||||
pub trait LauncherListItem {
|
||||
fn id(&self) -> String;
|
||||
fn title(&self) -> String;
|
||||
fn description(&self) -> Option<String>;
|
||||
fn execute(&self) -> Result<(), LaunchError>;
|
||||
|
@ -11,6 +11,10 @@ pub struct DesktopEntry {
|
||||
}
|
||||
|
||||
impl LauncherListItem for DesktopEntry {
|
||||
fn id(&self) -> String {
|
||||
self.id.clone()
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
return self.name.to_owned();
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ impl FileEntry {
|
||||
}
|
||||
|
||||
impl LauncherListItem for FileEntry {
|
||||
fn id(&self) -> String {
|
||||
self.path.to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
return String::from(self.path.file_name().unwrap().to_string_lossy());
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ mod imp {
|
||||
pub title: RefCell<String>,
|
||||
pub description: RefCell<Option<String>>,
|
||||
pub icon: RefCell<String>,
|
||||
pub index: RefCell<usize>, // Store index to access original entry
|
||||
pub id: RefCell<String>, // Store id to access original entry
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
@ -44,7 +44,7 @@ glib::wrapper! {
|
||||
}
|
||||
|
||||
impl LauncherItemObject {
|
||||
pub fn new(title: String, description: Option<String>, icon: String, index: usize) -> Self {
|
||||
pub fn new(title: String, description: Option<String>, icon: String, id: String) -> Self {
|
||||
let obj: Self = glib::Object::new();
|
||||
let imp = obj.imp();
|
||||
|
||||
@ -52,7 +52,7 @@ impl LauncherItemObject {
|
||||
*imp.title.borrow_mut() = title;
|
||||
*imp.description.borrow_mut() = description;
|
||||
*imp.icon.borrow_mut() = icon;
|
||||
*imp.index.borrow_mut() = index;
|
||||
*imp.id.borrow_mut() = id;
|
||||
|
||||
obj
|
||||
}
|
||||
@ -69,8 +69,8 @@ impl LauncherItemObject {
|
||||
self.imp().description.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn index(&self) -> usize {
|
||||
*self.imp().index.borrow()
|
||||
pub fn id(&self) -> String {
|
||||
self.imp().id.borrow().clone()
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,12 +234,12 @@ impl GtkLauncherUI {
|
||||
|
||||
// Update the list store
|
||||
list_store_for_search.remove_all();
|
||||
for (index, entry) in results.iter().enumerate() {
|
||||
for entry in results.iter() {
|
||||
let item_obj = LauncherItemObject::new(
|
||||
entry.title(),
|
||||
entry.description(),
|
||||
entry.icon(),
|
||||
index,
|
||||
entry.id(),
|
||||
);
|
||||
list_store_for_search.append(&item_obj);
|
||||
}
|
||||
@ -252,8 +252,8 @@ impl GtkLauncherUI {
|
||||
search_input.connect_activate(move |_| {
|
||||
if let Some(selected_item) = selection_for_enter.selected_item() {
|
||||
if let Some(item_obj) = selected_item.downcast_ref::<LauncherItemObject>() {
|
||||
let index = item_obj.index();
|
||||
match launcher_for_enter.borrow().execute_item(index) {
|
||||
let id = item_obj.id();
|
||||
match launcher_for_enter.borrow().execute_item_by_id(&id) {
|
||||
Ok(_) => app_for_enter.quit(),
|
||||
Err(e) => eprintln!("Failed to launch app: {:?}", e),
|
||||
}
|
||||
@ -304,22 +304,25 @@ impl GtkLauncherUI {
|
||||
// Connect list activation signal
|
||||
let launcher_for_activate = launcher.clone();
|
||||
let app_for_activate = app.clone();
|
||||
let list_store_for_activate = list_store.clone();
|
||||
list_view.connect_activate(move |_, position| {
|
||||
match launcher_for_activate
|
||||
.borrow()
|
||||
.execute_item(position as usize)
|
||||
{
|
||||
if let Some(obj) = list_store_for_activate.item(position) {
|
||||
if let Some(item_obj) = obj.downcast_ref::<LauncherItemObject>() {
|
||||
let id = item_obj.id();
|
||||
match launcher_for_activate.borrow().execute_item_by_id(&id) {
|
||||
Ok(_) => app_for_activate.quit(),
|
||||
Err(e) => eprintln!("Failed to launch app: {:?}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize with default results
|
||||
let mut launcher_ref = launcher.borrow_mut();
|
||||
let results = launcher_ref.get_default_results();
|
||||
for (index, entry) in results.iter().enumerate() {
|
||||
for entry in results.iter() {
|
||||
let item_obj =
|
||||
LauncherItemObject::new(entry.title(), entry.description(), entry.icon(), index);
|
||||
LauncherItemObject::new(entry.title(), entry.description(), entry.icon(), entry.id());
|
||||
list_store.append(&item_obj);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user