use std::path::{Path, PathBuf}; use gtk::prelude::*; use relm4::prelude::*; use crate::sheet::Sheet; use super::sheet_listing::SheetListingInput; #[derive(Debug, Clone)] pub enum SheetModelType { Sheet { sheet: Sheet }, Pdf { path: PathBuf }, } impl SheetModelType { pub fn get_path(&self) -> &str { match self { SheetModelType::Sheet { sheet } => &sheet.path, SheetModelType::Pdf { path } => path.to_str().unwrap(), } } } pub struct SheetModel { pub label: String, pub sheet_model_type: SheetModelType, visible: bool, } #[derive(Debug)] pub struct RowActivated; #[derive(Debug, Clone)] pub struct OnQueryUpdate { pub query: String, } #[relm4::factory(pub)] impl FactoryComponent for SheetModel { type Init = SheetModelType; type ParentWidget = gtk::ListBox; type CommandOutput = (); type ParentInput = SheetListingInput; type Input = OnQueryUpdate; type Output = RowActivated; view! { #[root] gtk::ListBoxRow { #[watch] set_visible: self.visible, gtk::Box { set_orientation: gtk::Orientation::Vertical, append = >k::Label { set_label: &self.label, set_halign: gtk::Align::Start, set_margin_all: 10, } } } } fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender) -> Self { let label = match &value { SheetModelType::Sheet { sheet } => format!("{}", sheet.name), SheetModelType::Pdf { path } => { format!("{}", path.file_name().unwrap().to_str().unwrap()) } }; SheetModel { label, sheet_model_type: value, visible: true, } } fn update(&mut self, msg: Self::Input, _sender: FactorySender) { let query = msg.query.to_ascii_lowercase(); let split = query.split_ascii_whitespace(); let label = self.label.to_ascii_lowercase(); self.visible = split .into_iter() .all(|query_part| label.contains(query_part)); } }