Start organizing plugins internally for faster retrieval

This commit is contained in:
Javier Feliz 2025-09-04 00:20:14 -04:00
parent 7b367e5ba8
commit 13fa1e932f
2 changed files with 63 additions and 23 deletions

View File

@ -0,0 +1,19 @@
use crate::LauncherPlugin;
use crate::ui::WaycastLauncher;
use gtk::Application;
use std::cell::RefCell;
use std::rc::Rc;
pub struct WaycastLauncherBuilder {
pub plugins: Vec<Box<dyn LauncherPlugin>>,
}
impl WaycastLauncherBuilder {
pub fn add_plugin<T: LauncherPlugin + 'static>(mut self, plugin: T) -> Self {
self.plugins.push(Box::new(plugin));
self
}
pub fn initialize(self, app: &Application) -> Rc<RefCell<WaycastLauncher>> {
WaycastLauncher::create_with_plugins(app, self.plugins)
}
}

View File

@ -1,3 +1,4 @@
use crate::{LauncherListItem, LauncherPlugin};
use gtk::gdk::Texture; use gtk::gdk::Texture;
use gtk::gdk_pixbuf::Pixbuf; use gtk::gdk_pixbuf::Pixbuf;
use gtk::prelude::*; use gtk::prelude::*;
@ -8,15 +9,23 @@ use gtk::{
use gtk4_layer_shell as layerShell; use gtk4_layer_shell as layerShell;
use layerShell::LayerShell; use layerShell::LayerShell;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use crate::{LauncherListItem, LauncherPlugin}; mod launcher_builder;
use launcher_builder::WaycastLauncherBuilder;
use std::sync::Arc;
pub struct WaycastLauncher { pub struct WaycastLauncher {
pub window: ApplicationWindow, pub window: ApplicationWindow,
pub list_box: ListBox, pub list_box: ListBox,
pub entries: Vec<Box<dyn LauncherListItem>>, pub entries: Vec<Box<dyn LauncherListItem>>,
pub plugins: Vec<Box<dyn LauncherPlugin>>, // All plugins
pub plugins: Vec<Arc<dyn LauncherPlugin>>,
// Plugins with by_prefix_only()->false
pub plugins_show_always: Vec<Arc<dyn LauncherPlugin>>,
// Prefix hash map
pub plugins_by_prefix: HashMap<String, Arc<dyn LauncherPlugin>>,
} }
impl WaycastLauncher { impl WaycastLauncher {
@ -27,21 +36,6 @@ impl WaycastLauncher {
} }
} }
pub struct WaycastLauncherBuilder {
plugins: Vec<Box<dyn LauncherPlugin>>,
}
impl WaycastLauncherBuilder {
pub fn add_plugin<T: LauncherPlugin + 'static>(mut self, plugin: T) -> Self {
self.plugins.push(Box::new(plugin));
self
}
pub fn initialize(self, app: &Application) -> Rc<RefCell<WaycastLauncher>> {
WaycastLauncher::create_with_plugins(app, self.plugins)
}
}
pub struct ListItem { pub struct ListItem {
text: String, text: String,
icon: String, icon: String,
@ -86,7 +80,10 @@ impl ListItem {
} }
impl WaycastLauncher { impl WaycastLauncher {
fn create_with_plugins(app: &Application, plugins: Vec<Box<dyn LauncherPlugin>>) -> Rc<RefCell<Self>> { fn create_with_plugins(
app: &Application,
init_plugins: Vec<Box<dyn LauncherPlugin>>,
) -> Rc<RefCell<Self>> {
let window = ApplicationWindow::builder() let window = ApplicationWindow::builder()
.application(app) .application(app)
.title("Waycast") .title("Waycast")
@ -127,12 +124,34 @@ impl WaycastLauncher {
window.set_keyboard_mode(layerShell::KeyboardMode::OnDemand); window.set_keyboard_mode(layerShell::KeyboardMode::OnDemand);
window.set_layer(layerShell::Layer::Top); window.set_layer(layerShell::Layer::Top);
let mut plugins: Vec<Arc<dyn LauncherPlugin>> = Vec::new();
for p in init_plugins {
plugins.push(Arc::from(p));
}
// Organize plugins for faster querying
let mut plugins_show_always: Vec<Arc<dyn LauncherPlugin>> = Vec::new();
for p in &plugins {
if !p.by_prefix_only() {
plugins_show_always.push(Arc::clone(p));
}
}
let mut plugins_by_prefix: HashMap<String, Arc<dyn LauncherPlugin>> = HashMap::new();
for p in &plugins {
if let Some(prefix) = p.prefix() {
plugins_by_prefix.insert(prefix, Arc::clone(p));
}
}
// Init the launcher model
let entries: Vec<Box<dyn LauncherListItem>> = Vec::new(); let entries: Vec<Box<dyn LauncherListItem>> = Vec::new();
let model: Rc<RefCell<WaycastLauncher>> = Rc::new(RefCell::new(WaycastLauncher { let model: Rc<RefCell<WaycastLauncher>> = Rc::new(RefCell::new(WaycastLauncher {
window, window,
list_box: list_box.clone(), list_box: list_box.clone(),
entries, entries,
plugins, plugins,
plugins_show_always,
plugins_by_prefix,
})); }));
// Populate the list // Populate the list
@ -194,14 +213,16 @@ impl WaycastLauncher {
if let Some(selected_row) = list_box_clone_for_search.selected_row() { if let Some(selected_row) = list_box_clone_for_search.selected_row() {
let index = selected_row.index(); let index = selected_row.index();
if index > 0 { if index > 0 {
if let Some(prev_row) = list_box_clone_for_search.row_at_index(index - 1) { if let Some(prev_row) =
list_box_clone_for_search.row_at_index(index - 1)
{
list_box_clone_for_search.select_row(Some(&prev_row)); list_box_clone_for_search.select_row(Some(&prev_row));
} }
} }
} }
gtk::glib::Propagation::Stop gtk::glib::Propagation::Stop
} }
_ => gtk::glib::Propagation::Proceed _ => gtk::glib::Propagation::Proceed,
} }
}); });
search_input.add_controller(search_key_controller); search_input.add_controller(search_key_controller);
@ -263,7 +284,7 @@ impl WaycastLauncher {
pub fn populate_list(&mut self) { pub fn populate_list(&mut self) {
self.entries.clear(); self.entries.clear();
for plugin in &self.plugins { for plugin in &self.plugins_show_always {
for entry in plugin.default_list() { for entry in plugin.default_list() {
self.entries.push(entry); self.entries.push(entry);
} }