use std::path::PathBuf; use gtk::prelude::*; use relm4::{component::Connector, prelude::*}; use crate::{ ui::{mcdu::McduOutput, sheet_model::SheetModelType}, FileValidationResult, }; use super::{ mcdu::McduModel, sheet_listing::{SheetListingInput, SheetListingModel}, }; pub struct AppModel { mcdu: Controller, sheets_and_files_listing: Controller, new_files_listing: Controller, } #[derive(Debug)] pub enum AppInput { SearchStarted(String), NewFilesSheetPressed(SheetModelType), SheetsAndFilesSheetPressed(SheetModelType), } #[relm4::component(pub)] impl SimpleComponent for AppModel { type Input = AppInput; type Output = (); type Init = FileValidationResult; view! { #[root] gtk::Window{ set_default_width: 300, set_default_height: 300, set_title: Some("Play music!!!"), set_maximized: true, gtk::Box { set_orientation: gtk::Orientation::Horizontal, gtk::Box { set_orientation: gtk::Orientation::Vertical, set_hexpand: true, #[name = "stack_switcher"] gtk::StackSwitcher { set_stack: Some(&stack), set_margin_all: 10, }, #[name = "stack"] gtk::Stack { add_titled[None, "Sheets & Files"]= >k::ScrolledWindow { model.sheets_and_files_listing.widget(), set_vexpand: true, set_hexpand: true, }, add_titled[None, "New Files"]= >k::ScrolledWindow { model.new_files_listing.widget(), set_vexpand: true, set_hexpand: true, }, }, }, model.mcdu.widget(), } } } fn init( file_validation_result: Self::Init, window: &Self::Root, sender: ComponentSender, ) -> relm4::ComponentParts { relm4_icons::initialize_icons(); let mcdu = McduModel::builder() .launch(()) .forward(sender.input_sender(), |response| match response { McduOutput::SearchStarted(query) => AppInput::SearchStarted(query), }); let new_files: Vec = file_validation_result .unassigned_files .iter() .map(|file| SheetModelType::Pdf { path: file.to_path_buf(), }) .collect(); let new_files_clone_iter = file_validation_result .unassigned_files .into_iter() .map(|file| SheetModelType::Pdf { path: file }); let sheets_and_files: Vec = file_validation_result .validated_sheets .into_iter() .chain(file_validation_result.updated_sheets.into_iter()) .map(|sheet| SheetModelType::Sheet { sheet }) .chain(new_files_clone_iter) .collect(); let sheets_and_files_listing = SheetListingModel::builder() .launch(sheets_and_files) .forward(sender.input_sender(), |response| { AppInput::SheetsAndFilesSheetPressed(response.sheet_model_type) }); let new_files_listing = SheetListingModel::builder() .launch(new_files) .forward(sender.input_sender(), |response| { AppInput::NewFilesSheetPressed(response.sheet_model_type) }); let model = AppModel { mcdu, sheets_and_files_listing, new_files_listing, }; let widgets = view_output!(); ComponentParts { model, widgets } } fn update(&mut self, message: Self::Input, _sender: ComponentSender) { // AppInput::SheetPressed(sheet) => opener::open(sheet).unwrap(), match message { AppInput::SearchStarted(query) => { self.sheets_and_files_listing .emit(SheetListingInput::Query(query.clone())); self.new_files_listing.emit(SheetListingInput::Query(query)); } AppInput::NewFilesSheetPressed(_) => { // TODO } AppInput::SheetsAndFilesSheetPressed(sheet_model_type) => { opener::open(sheet_model_type.get_path()).unwrap() } } } }