From 8036e79049f88b62ca9efdaaaf3ee8af9222f676 Mon Sep 17 00:00:00 2001 From: dasetwas <18222134+DasEtwas@users.noreply.github.com> Date: Sat, 18 Sep 2021 16:20:31 +0200 Subject: [PATCH] version 1.6 - every save/open file dialog now remembers its last browsing location - panic button now not only resets waveguides, but also sets master volume to 1% or below - loading config files from JSON is now supported --- src/gui.rs | 64 ++++++++++++++++++++++++++++++++++++++++------------ src/main.rs | 8 +++++-- src/utils.rs | 26 +++++++++++++++------ 3 files changed, 74 insertions(+), 24 deletions(-) diff --git a/src/gui.rs b/src/gui.rs index df59467..7fde956 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -7,6 +7,7 @@ use conrod_core::{ *, }; use parking_lot::RwLock; +use std::path::PathBuf; use std::{fs::File, io::Write, sync::Arc}; // must be 2^n @@ -144,6 +145,9 @@ impl Ids { pub struct GUIState { waterfall: [f32; (WATERFALL_WIDTH * WATERFALL_HEIGHT) as usize], input: crossbeam_channel::Receiver>, + recording_save_path: Option, + config_save_path: Option, + config_load_path: Option, } impl GUIState { @@ -151,6 +155,9 @@ impl GUIState { GUIState { waterfall: [0.07f32; (WATERFALL_WIDTH * WATERFALL_HEIGHT) as usize], input, + recording_save_path: None, + config_save_path: None, + config_load_path: None, } } @@ -326,12 +333,21 @@ pub fn gui( match &mut generator.recorder { None => { let rec_name = recording_name(); - if let Some(save_path) = native_dialog::FileDialog::new() + + let mut dialog = native_dialog::FileDialog::new() .set_filename(&rec_name) - .add_filter("MONO Wave Audio file", &["wav"]) + .add_filter("MONO Wave Audio file", &["wav"]); + + if let Some(recording_save_path) = &gui_state.recording_save_path { + dialog = dialog.set_location(recording_save_path); + } + + if let Some(save_path) = dialog .show_save_single_file() .expect("Failed to open file save dialog") { + gui_state.recording_save_path = + save_path.parent().map(|p| p.to_owned()); generator.recorder = Some(Recorder::new(save_path, sample_rate)); } else { println!("Aborted recording"); @@ -352,23 +368,32 @@ pub fn gui( .h(BUTTON_LINE_SIZE) .set(ids.file_chooser_button, ui) { - let load_file_path = native_dialog::FileDialog::new() + let mut dialog = native_dialog::FileDialog::new() .add_filter("Engine sound configuration files", &["esc", "es"]) - .add_filter("All files", &["*"]) - .show_open_single_file() - .unwrap(); + .add_filter("All files", &["*"]); + + if let Some(config_load_path) = &gui_state.config_load_path { + dialog = dialog.set_location(config_load_path); + } + + let load_file_path = dialog.show_open_single_file().unwrap(); + + if let Some(load_file_path) = load_file_path { + gui_state.config_load_path = load_file_path.parent().map(|p| p.to_owned()); - if let Some(load_file_path) = load_file_path.map(|p| p.display().to_string()) { - match crate::load_engine(&load_file_path, sample_rate) { + let string_path = load_file_path.display().to_string(); + + match crate::load_engine( + &string_path, + sample_rate, + string_path.ends_with("json"), + ) { Ok(new_engine) => { - println!("Successfully loaded engine config \"{}\"", &load_file_path); + println!("Successfully loaded engine config \"{}\"", &string_path); generator.engine = new_engine; } Err(e) => { - eprintln!( - "Failed to load engine config \"{}\": {}", - &load_file_path, e - ); + eprintln!("Failed to load engine config \"{}\": {}", &string_path, e); } } } else { @@ -393,6 +418,7 @@ pub fn gui( .color(Color::Rgba(0.8, 0.1, 0.1, 1.0)) .set(ids.panic_button, ui) { + generator.volume = generator.volume.min(0.01); generator.reset(); } } @@ -412,13 +438,21 @@ pub fn gui( let name = config_name(); - if let Some(path) = native_dialog::FileDialog::new() + let mut dialog = native_dialog::FileDialog::new() .set_filename(&name) .add_filter("Engine sound RON file", &["esc", "ron"]) - .add_filter("Engine sound JSON file", &["json"]) + .add_filter("Engine sound JSON file", &["json"]); + + if let Some(config_save_path) = &gui_state.config_save_path { + dialog = dialog.set_location(config_save_path); + } + + if let Some(path) = dialog .show_save_single_file() .expect("Failed to open file save dialog") { + gui_state.config_save_path = path.parent().map(|p| p.to_owned()); + match path.extension() { Some(str) if str == "json" => { match serde_json::to_string_pretty(&generator.engine) { diff --git a/src/main.rs b/src/main.rs index f2d0cfe..a6335b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,7 +64,7 @@ fn main() { let sample_rate = value_t_or_exit!(matches, "samplerate", u32); let mut engine = match matches.value_of("config") { - Some(path) => match load_engine(path, sample_rate) { + Some(path) => match load_engine(path, sample_rate, path.ends_with("json")) { Ok(engine) => { println!("Successfully loaded config \"{}\"", path); engine @@ -251,7 +251,11 @@ fn main() { match event { glium::glutin::event::WindowEvent::DroppedFile(path) => { if let Some(path) = path.to_str() { - match crate::load_engine(path, sample_rate) { + match crate::load_engine( + path, + sample_rate, + path.ends_with("json"), + ) { Ok(new_engine) => { println!( "Successfully loaded engine config \"{}\"", diff --git a/src/utils.rs b/src/utils.rs index 00319be..a9d8bde 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -26,15 +26,27 @@ pub fn samples_to_distance(samples: usize, sample_rate: u32) -> f32 { samples_to_seconds(samples, sample_rate) * SPEED_OF_SOUND } -pub(crate) fn load_engine(path: &str, sample_rate: u32) -> Result { +pub(crate) fn load_engine(path: &str, sample_rate: u32, json: bool) -> Result { match File::open(path) { - Ok(file) => match ron::de::from_reader::<_, Engine>(file) { - Ok(mut engine) => { - fix_engine(&mut engine, sample_rate); - Ok(engine) + Ok(file) => { + if json { + match serde_json::de::from_reader::<_, Engine>(file) { + Ok(mut engine) => { + fix_engine(&mut engine, sample_rate); + Ok(engine) + } + Err(e) => Err(format!("Failed to load JSON config \"{}\": {}", &path, e)), + } + } else { + match ron::de::from_reader::<_, Engine>(file) { + Ok(mut engine) => { + fix_engine(&mut engine, sample_rate); + Ok(engine) + } + Err(e) => Err(format!("Failed to load RON config \"{}\": {}", &path, e)), + } } - Err(e) => Err(format!("Failed to load config \"{}\": {}", &path, e)), - }, + } Err(e) => Err(format!("Failed to open file \"{}\": {}", &path, e)), } }