From 936c996ce6631a4daacdbc81300d161d15c07924 Mon Sep 17 00:00:00 2001 From: Johann Woelper Date: Mon, 2 Sep 2024 12:22:38 +0200 Subject: [PATCH] feat: Persistent and volatile settings are now split for easier versioning of configuration files --- src/appstate.rs | 4 ++-- src/main.rs | 44 ++++++++++++++++++++++---------------------- src/settings.rs | 19 +++++++++++-------- src/ui.rs | 4 ++-- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/appstate.rs b/src/appstate.rs index bf9487b0..b639a455 100644 --- a/src/appstate.rs +++ b/src/appstate.rs @@ -139,8 +139,8 @@ impl Default for OculanteState { key_grab: Default::default(), edit_state: Default::default(), pointer_over_ui: Default::default(), - persistent_settings: Default::default(), - volatile_settings: Default::default(), + persistent_settings: PersistentSettings::load().unwrap_or_default(), + volatile_settings: VolatileSettings::load().unwrap_or_default(), always_on_top: Default::default(), network_mode: Default::default(), window_size: Default::default(), diff --git a/src/main.rs b/src/main.rs index ff25da85..5aa22603 100644 --- a/src/main.rs +++ b/src/main.rs @@ -116,6 +116,18 @@ fn main() -> Result<(), String> { let _ = mac::launch(); } + // Unfortunately we need to load the volatile settings here, too - the window settings need + // to be set before window creation + match settings::VolatileSettings::load() { + Ok(volatile_settings) => { + if volatile_settings.window_geometry != Default::default() { + window_config.width = volatile_settings.window_geometry.1 .0 as u32; + window_config.height = volatile_settings.window_geometry.1 .1 as u32; + } + } + Err(e) => error!("Could not load volatile settings: {e}"), + } + // Unfortunately we need to load the persistent settings here, too - the window settings need // to be set before window creation match settings::PersistentSettings::load() { @@ -123,11 +135,8 @@ fn main() -> Result<(), String> { window_config.vsync = settings.vsync; window_config.lazy_loop = !settings.force_redraw; window_config.decorations = !settings.borderless; - if settings.window_geometry != Default::default() { - window_config.width = settings.window_geometry.1 .0 as u32; - window_config.height = settings.window_geometry.1 .1 as u32; - } - debug!("Loaded settings."); + + trace!("Loaded settings."); if settings.zen_mode { let mut title_string = window_config.title.clone(); title_string.push_str(&format!( @@ -139,7 +148,7 @@ fn main() -> Result<(), String> { window_config.min_size = Some(settings.min_window_size); } Err(e) => { - error!("Could not load settings: {e}"); + error!("Could not load persistent settings: {e}"); } } window_config.always_on_top = true; @@ -198,18 +207,6 @@ fn init(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins) -> OculanteSta ..Default::default() }; - match settings::PersistentSettings::load() { - Ok(settings) => { - state.persistent_settings = settings; - info!("Successfully loaded previous settings.") - } - Err(e) => { - warn!("Settings failed to load: {e}. This may happen after application updates. Generating a fresh file."); - state.persistent_settings = Default::default(); - state.persistent_settings.save_blocking(); - } - } - state.player = Player::new( state.texture_channel.0.clone(), state.persistent_settings.max_cache, @@ -466,6 +463,7 @@ fn event(app: &mut App, state: &mut OculanteState, evt: Event) { } if key_pressed(app, state, Quit) { state.persistent_settings.save_blocking(); + _ = state.volatile_settings.save_blocking(); app.backend.exit(); } #[cfg(feature = "turbo")] @@ -608,6 +606,7 @@ fn event(app: &mut App, state: &mut OculanteState, evt: Event) { app.window().size(), ); state.persistent_settings.save_blocking(); + _ = state.volatile_settings.save_blocking(); } Event::MouseWheel { delta_y, .. } => { trace!("Mouse wheel event"); @@ -711,6 +710,7 @@ fn update(app: &mut App, state: &mut OculanteState) { app.window().size(), ); state.persistent_settings.save_blocking(); + _ = state.volatile_settings.save_blocking(); trace!("Save {t}"); } @@ -847,12 +847,12 @@ fn drawe(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut O | FrameSource::Still | FrameSource::ImageCollectionMember => { if let Some(path) = &state.current_path { - if !state.persistent_settings.recent_images.contains(path) { + if !state.volatile_settings.recent_images.contains(path) { state - .persistent_settings + .volatile_settings .recent_images .insert(0, path.clone()); - state.persistent_settings.recent_images.truncate(10); + state.volatile_settings.recent_images.truncate(10); } } } @@ -1216,7 +1216,7 @@ fn drawe(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut O // Show file browser to select image to load #[cfg(feature = "file_open")] fn browse_for_image_path(state: &mut OculanteState) { - let start_directory = state.persistent_settings.last_open_directory.clone(); + let start_directory = state.volatile_settings.last_open_directory.clone(); let load_sender = state.load_channel.0.clone(); state.redraw = true; std::thread::spawn(move || { diff --git a/src/settings.rs b/src/settings.rs index da379fd6..e61dd642 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,5 +1,6 @@ use crate::{shortcuts::*, utils::ColorChannel}; use anyhow::{anyhow, Result}; +use log::{info, trace}; use notan::egui::{Context, Visuals}; use serde::{Deserialize, Serialize}; use std::{ @@ -125,16 +126,17 @@ impl PersistentSettings { } } -fn save(s: &PersistentSettings) -> Result<()> { +fn save(ps: &PersistentSettings) -> Result<()> { let local_dir = dirs::config_local_dir() .ok_or(anyhow!("Can't get local dir"))? .join("oculante"); if !local_dir.exists() { _ = create_dir_all(&local_dir); } - let f = File::create(local_dir.join("config.json"))?; - Ok(serde_json::to_writer_pretty(f, s)?) + _ = serde_json::to_writer_pretty(f, ps)?; + trace!("Saved to {}", local_dir.display()); + Ok(()) } #[derive(Default, Debug, Serialize, Deserialize, Clone)] @@ -148,7 +150,6 @@ pub struct VolatileSettings { impl VolatileSettings { pub fn load() -> Result { - //data_local_dir let config_path = dirs::config_local_dir() .ok_or(anyhow!("Can't get config_local dir"))? .join("oculante") @@ -157,9 +158,9 @@ impl VolatileSettings { // migrate old config ?; - Ok(serde_json::from_reader::<_, VolatileSettings>(File::open( - config_path, - )?)?) + let s = serde_json::from_reader::<_, VolatileSettings>(File::open(config_path)?)?; + info!("Loaded volatile settings."); + Ok(s) } pub fn save_blocking(&self) -> Result<()> { @@ -171,7 +172,9 @@ impl VolatileSettings { } let f = File::create(local_dir.join("config_volatile.json"))?; - Ok(serde_json::to_writer_pretty(f, self)?) + let _res = serde_json::to_writer_pretty(f, self)?; + trace!("Saved volatile settings"); + Ok(()) } } diff --git a/src/ui.rs b/src/ui.rs index cd3c21c6..08f8da16 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1264,7 +1264,7 @@ pub fn edit_ui(app: &mut App, ctx: &Context, state: &mut OculanteState, gfx: &mu if state.current_image.is_some() { if ui.button(format!("{FLOPPY_DISK} Save as...")).clicked() { - let start_directory = state.persistent_settings.last_open_directory.clone(); + let start_directory = state.volatile_settings.last_open_directory.clone(); let image_to_save = state.edit_state.result_pixel_op.clone(); let msg_sender = state.message_channel.0.clone(); @@ -2207,7 +2207,7 @@ pub fn draw_hamburger_menu(ui: &mut Ui, state: &mut OculanteState, app: &mut App } ui.menu_button("Recent", |ui| { - for r in &state.persistent_settings.recent_images.clone() { + for r in &state.volatile_settings.recent_images.clone() { if let Some(filename) = r.file_name() { if ui.button(filename.to_string_lossy()).clicked() { load_image_from_path(r, state);