diff --git a/Cargo.lock b/Cargo.lock index 21229e8..30b7e14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -974,6 +974,7 @@ dependencies = [ "relm4", "relm4-components", "relm4-icons", + "walkdir", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 876a154..94074b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,5 @@ relm4 = "0.6.2" relm4-components = "0.6.2" # Optional: icons relm4-icons = { version = "0.6.0", features = ["plus"] } + +walkdir = "2" diff --git a/src/main.rs b/src/main.rs index 4baa47f..00036a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,17 @@ mod mcdu; +mod sheet_listing; + +use std::{env, path::PathBuf, process}; use gtk::prelude::*; use mcdu::McduModel; -use relm4::prelude::*; +use relm4::{gtk::PolicyType, prelude::*}; +use sheet_listing::SheetListingModel; struct AppModel { text: String, mcdu: Controller, + sheet_listing: Controller, } #[derive(Debug)] @@ -18,7 +23,7 @@ enum AppInput { impl SimpleComponent for AppModel { type Input = AppInput; type Output = (); - type Init = (); + type Init = PathBuf; view! { #[root] @@ -28,19 +33,33 @@ impl SimpleComponent for AppModel { set_title: Some("Play music!!!"), gtk::Box { set_orientation: gtk::Orientation::Horizontal, - model.mcdu.widget(), - #[name = "label"] - gtk::Label { - #[watch] - set_label: &model.text, - set_margin_all: 5, - } + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_hexpand: true, + gtk::ScrolledWindow { + model.sheet_listing.widget(), + set_vexpand: true, + set_hexpand: true, + // set_hscrollbar_policy: PolicyType::Never, + }, + }, + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_valign: gtk::Align::Center, + model.mcdu.widget(), + #[name = "label"] + gtk::Label { + #[watch] + set_label: &model.text, + set_margin_all: 5, + } + }, } } } fn init( - _init: Self::Init, + path: Self::Init, window: &Self::Root, sender: ComponentSender, ) -> relm4::ComponentParts { @@ -52,9 +71,14 @@ impl SimpleComponent for AppModel { mcdu::McduOutput::ButtonPress(c) => AppInput::McduInput(c), }); + let sheet_listing = SheetListingModel::builder() + .launch(path) + .forward(sender.input_sender(), |_response| todo!()); + let model = AppModel { - text: String::from("Text: NONE"), + text: String::from("Text: "), mcdu, + sheet_listing, }; let widgets = view_output!(); @@ -71,5 +95,19 @@ impl SimpleComponent for AppModel { fn main() { let app = RelmApp::new("de.frajul.sheet-organizer"); - app.run::(()); + + let args: Vec = env::args().collect(); + + if args.len() <= 1 { + eprintln!("Please provide sheet folder path"); + process::exit(1); + } + let file_path = PathBuf::from(&args[1]); + if !file_path.is_dir() { + eprintln!("Sheet folder path is no dir or does not exist"); + process::exit(1); + } + + // Pass empty command line args to allow my own parsing + app.with_args(Vec::new()).run::(file_path); } diff --git a/src/sheet_listing.rs b/src/sheet_listing.rs new file mode 100644 index 0000000..0c73146 --- /dev/null +++ b/src/sheet_listing.rs @@ -0,0 +1,91 @@ +use std::path::PathBuf; + +use gtk::prelude::*; +use relm4::{ + gtk, Component, ComponentController, ComponentParts, ComponentSender, SimpleComponent, +}; +use relm4::{gtk::PolicyType, prelude::*}; +use walkdir::WalkDir; + +pub struct SheetModel { + path: PathBuf, +} + +#[relm4::component(pub)] +impl SimpleComponent for SheetModel { + type Init = PathBuf; + type Input = (); + type Output = (); + + view! { + #[root] + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + gtk::Label { + set_label: &format!("{}", model.path.file_name().unwrap().to_string_lossy()), + set_halign: gtk::Align::Start, + set_margin_all: 10, + } + } + } + + fn init( + path: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = SheetModel { path }; + let widgets = view_output!(); + ComponentParts { model, widgets } + } +} + +pub struct SheetListingModel; + +#[derive(Debug)] +pub enum SheetListingOutput { + ButtonPress(char), +} + +#[relm4::component(pub)] +impl SimpleComponent for SheetListingModel { + type Init = PathBuf; + type Input = (); + type Output = SheetListingOutput; + + view! { + #[root] + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + // set_column_spacing: 5, + // set_row_spacing: 5, + } + } + + fn init( + dir: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + for entry in WalkDir::new(dir) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|file| file.file_type().is_file()) + .map(|file| file.into_path()) + .filter(|path| { + path.extension() + .map(|s| s.to_string_lossy().to_ascii_lowercase() == "pdf") + .unwrap_or(false) + }) + { + // println!("{}", entry.display()); + + let sheet_model = SheetModel::builder().launch(entry); + root.append(sheet_model.widget()); + } + + let model = SheetListingModel; + let widgets = view_output!(); + ComponentParts { model, widgets } + } +}