use std::{collections::HashMap, rc::Rc}; use wgui::{ assets::AssetPath, components::button::ComponentButton, layout::WidgetPair, parser::{Fetchable, ParseDocumentParams, ParserData, ParserState}, }; use crate::{ tab::{Tab, TabParams, TabType}, util::{self, desktop_finder::DesktopEntry}, }; pub struct TabApps { #[allow(dead_code)] pub state: ParserState, #[allow(dead_code)] entries: Vec, #[allow(dead_code)] app_list: AppList, } impl Tab for TabApps { fn get_type(&self) -> TabType { TabType::Apps } } #[derive(Default)] struct AppList { data: Vec, } impl TabApps { pub fn new(mut tab_params: TabParams) -> anyhow::Result { let doc_params = &ParseDocumentParams { globals: tab_params.globals.clone(), path: AssetPath::BuiltIn("gui/tab/apps.xml"), extra: Default::default(), }; let mut state = wgui::parser::parse_from_assets(doc_params, tab_params.layout, tab_params.parent_id)?; gtk::init()?; let entries = util::desktop_finder::find_entries()?; let app_list_parent = state.fetch_widget(&tab_params.layout.state, "app_list_parent")?; let mut app_list = AppList::default(); app_list.mount_entries(&entries, &mut state, doc_params, &mut tab_params, &app_list_parent)?; Ok(Self { app_list, state, entries, }) } } impl AppList { fn mount_entry( &mut self, parser_state: &mut ParserState, doc_params: &ParseDocumentParams, params: &mut TabParams, list_parent: &WidgetPair, entry: &DesktopEntry, ) -> anyhow::Result<()> { let mut template_params = HashMap::new(); // entry icon template_params.insert( Rc::from("src_ext"), entry .icon_path .as_ref() .map_or_else(|| Rc::from(""), |icon_path| Rc::from(icon_path.as_str())), ); // entry fallback (question mark) icon template_params.insert( Rc::from("src"), if entry.icon_path.is_none() { Rc::from("dashboard/terminal.svg") } else { Rc::from("") }, ); template_params.insert(Rc::from("name"), Rc::from(entry.app_name.as_str())); let data = parser_state.parse_template(doc_params, "AppEntry", params.layout, list_parent.id, template_params)?; let button = data.fetch_component_as::("button")?; button.on_click(Box::new(move |_common, _evt| { log::info!("click"); Ok(()) })); self.data.push(data); Ok(()) } fn mount_entries( &mut self, entries: &[DesktopEntry], parser_state: &mut ParserState, doc_params: &ParseDocumentParams, params: &mut TabParams, list_parent: &WidgetPair, ) -> anyhow::Result<()> { for entry in entries { self.mount_entry(parser_state, doc_params, params, list_parent, entry)?; } Ok(()) } }