use std::{collections::HashMap, marker::PhantomData, rc::Rc}; use wgui::{ assets::AssetPath, components::{checkbox::ComponentCheckbox, slider::ComponentSlider}, globals::WguiGlobals, layout::WidgetID, parser::{self, Fetchable, ParseDocumentParams, ParserState}, task::Tasks, }; use wlx_common::dash_interface; use crate::{ frontend::Frontend, tab::{Tab, TabType}, }; #[derive(Debug)] enum Task { Refresh, FocusClient(String), SetBrightness(f32), } pub struct TabMonado { #[allow(dead_code)] state: ParserState, tasks: Tasks, marker: PhantomData, globals: WguiGlobals, id_list_parent: WidgetID, cells: Vec, ticks: u32, } impl Tab for TabMonado { fn get_type(&self) -> TabType { TabType::Games } fn update(&mut self, frontend: &mut Frontend, data: &mut T) -> anyhow::Result<()> { for task in self.tasks.drain() { match task { Task::Refresh => self.refresh(frontend, data)?, Task::FocusClient(name) => self.focus_client(frontend, data, name)?, Task::SetBrightness(brightness) => self.set_brightness(frontend, data, brightness), } } // every few seconds if self.ticks.is_multiple_of(500) { self.tasks.push(Task::Refresh); } self.ticks += 1; Ok(()) } } fn doc_params(globals: &'_ WguiGlobals) -> ParseDocumentParams<'_> { ParseDocumentParams { globals: globals.clone(), path: AssetPath::BuiltIn("gui/tab/monado.xml"), extra: Default::default(), } } fn yesno(n: bool) -> &'static str { match n { true => "yes", false => "no", } } impl TabMonado { pub fn new(frontend: &mut Frontend, parent_id: WidgetID) -> anyhow::Result { let globals = frontend.layout.state.globals.clone(); let state = wgui::parser::parse_from_assets(&doc_params(&globals), &mut frontend.layout, parent_id)?; let id_list_parent = state.get_widget_id("list_parent")?; let tasks = Tasks::::new(); tasks.push(Task::Refresh); Ok(Self { state, marker: PhantomData, tasks, globals, id_list_parent, ticks: 0, cells: Vec::new(), }) } fn mount_client(&mut self, frontend: &mut Frontend, client: &dash_interface::MonadoClient) -> anyhow::Result<()> { let mut par = HashMap::, Rc>::new(); par.insert( "checked".into(), if client.is_primary { Rc::from("1") } else { Rc::from("0") }, ); par.insert("name".into(), client.name.clone().into()); par.insert("flag_active".into(), yesno(client.is_active).into()); par.insert("flag_focused".into(), yesno(client.is_focused).into()); par.insert("flag_io_active".into(), yesno(client.is_io_active).into()); par.insert("flag_overlay".into(), yesno(client.is_overlay).into()); par.insert("flag_primary".into(), yesno(client.is_primary).into()); par.insert("flag_visible".into(), yesno(client.is_visible).into()); let state_cell = self.state.parse_template( &doc_params(&self.globals), "Cell", &mut frontend.layout, self.id_list_parent, par, )?; let checkbox = state_cell.fetch_component_as::("checkbox")?; checkbox.on_toggle({ let tasks = self.tasks.clone(); let client_name = client.name.clone(); Box::new(move |_common, e| { if e.checked { tasks.push(Task::FocusClient(client_name.clone())); } Ok(()) }) }); self.cells.push(state_cell); Ok(()) } fn refresh(&mut self, frontend: &mut Frontend, data: &mut T) -> anyhow::Result<()> { log::debug!("refreshing monado client list"); let clients = frontend.interface.monado_client_list(data)?; frontend.layout.remove_children(self.id_list_parent); self.cells.clear(); for client in clients { self.mount_client(frontend, &client)?; } // get brightness let slider_brightness = self.state.fetch_component_as::("slider_brightness")?; if let Some(brightness) = frontend.interface.monado_brightness_get(data) { let mut c = frontend.layout.start_common(); slider_brightness.set_value(&mut c.common(), brightness * 100.0); c.finish()?; slider_brightness.on_value_changed({ let tasks = self.tasks.clone(); Box::new(move |_common, e| { tasks.push(Task::SetBrightness(e.value / 100.0)); Ok(()) }) }); } Ok(()) } fn focus_client(&mut self, frontend: &mut Frontend, data: &mut T, name: String) -> anyhow::Result<()> { frontend.interface.monado_client_focus(data, &name)?; self.tasks.push(Task::Refresh); Ok(()) } fn set_brightness(&mut self, frontend: &mut Frontend, data: &mut T, brightness: f32) { frontend.interface.monado_brightness_set(data, brightness); } }