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