use std::{ collections::{ BTreeMap, VecDeque, }, fs, path::Path, sync::Arc, }; use devices::description::DeviceKind; use egui::{ Context, DragValue, Pos2, Ui, Vec2, Window, }; use serde::{ Deserialize, Deserializer, Serialize, Serializer, }; use uuid::Uuid; use visuals::templates::WidgetTemplate; pub mod container; pub mod devices; pub mod graph; pub mod module_description; pub mod visuals; pub mod widgets; pub fn widget_prefabs( path: impl AsRef, ) -> Result, Box> { fs::read_to_string(path).map_err(Into::into).and_then(|s| { let prefabs = serde_yaml::from_str(&s)?; Ok(prefabs) }) } pub fn widget_name(uuid: Option, widgets: &BTreeMap) -> String { if let Some(uuid) = uuid { format!("{}: {}", uuid, widgets[&uuid].name) } else { "None".into() } } pub fn pos_drag_value(ui: &mut Ui, label: impl AsRef, pos: &mut Pos2) { two_drag_value(ui, label.as_ref(), "X", "Y", &mut pos.x, &mut pos.y) } pub fn vec_drag_value(ui: &mut Ui, label: impl AsRef, vec: &mut Vec2) { two_drag_value(ui, label.as_ref(), "X", "Y", &mut vec.x, &mut vec.y) } pub fn two_drag_value( ui: &mut Ui, label: impl AsRef, l1: impl AsRef, l2: impl AsRef, v1: &mut f32, v2: &mut f32, ) { ui.horizontal(|ui| { ui.label(label.as_ref()); ui.label(l1.as_ref()); ui.add(DragValue::new(v1)); ui.label(l2.as_ref()); ui.add(DragValue::new(v2)); }); } pub fn error_window(error: &mut Option>, ctx: &Context) { Window::new("Error").resizable(false).show(ctx, |ui| { ui.vertical_centered(|ui| { ui.label(error.as_ref().unwrap().to_string()); if ui.button("Ok").clicked() { error.take(); } }) }); } fn ser_btree_as_vec(map: &BTreeMap, ser: S) -> Result where S: Serializer, T: Serialize, { map.values().collect::>().serialize(ser) } fn de_vec_as_btree<'de, D, T>(de: D) -> Result, D::Error> where D: Deserializer<'de>, T: Deserialize<'de>, { let vec: Vec = Vec::deserialize(de)?; Ok(vec.into_iter().enumerate().collect()) } pub fn ser_device_description(dd: &usize, ser: S) -> Result where S: Serializer, { DeviceKind::Audio(*dd).name().serialize(ser) } pub fn de_device_description<'de, D>(de: D) -> Result where D: Deserializer<'de>, D::Error: serde::de::Error, { let s = String::deserialize(de)?; devices::DEVICES .iter() .enumerate() .find_map(|(id, dd)| if dd.name == s { Some(id) } else { None }) .ok_or(serde::de::Error::custom(format!( "{s} is not a known device name, I only know these devices: {:?}", DeviceKind::all() .iter() .map(DeviceKind::name) .collect::>() ))) } pub struct STQueue { inner: Arc>>, } impl Clone for STQueue { fn clone(&self) -> Self { Self { inner: Arc::clone(&self.inner), } } } impl STQueue { pub fn new() -> Self { Self { inner: Default::default(), } } pub fn put(&self, msg: T) { self.inner.lock().push_front(msg) } pub fn get(&self) -> Option { self.inner.lock().pop_back() } } impl Default for STQueue { fn default() -> Self { Self::new() } } pub trait Uuidentified { fn uuid(&self) -> Uuid; } pub trait Tooltipable { fn tooltip(&self) -> String; }