Files
wayvr/dash-frontend/src/tab/apps.rs
2025-10-12 17:30:30 +09:00

122 lines
2.6 KiB
Rust

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<DesktopEntry>,
#[allow(dead_code)]
app_list: AppList,
}
impl Tab for TabApps {
fn get_type(&self) -> TabType {
TabType::Apps
}
}
#[derive(Default)]
struct AppList {
data: Vec<ParserData>,
}
impl TabApps {
pub fn new(mut tab_params: TabParams) -> anyhow::Result<Self> {
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::<ComponentButton>("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(())
}
}