diff --git a/src/backend/common.rs b/src/backend/common.rs index 2d9a9c8..b52ece4 100644 --- a/src/backend/common.rs +++ b/src/backend/common.rs @@ -73,7 +73,7 @@ where let mut show_screens = app.session.config.show_screens.clone(); if show_screens.is_empty() { if let Some((_, s, _)) = data.screens.first() { - show_screens.arc_ins(s.name.clone()); + show_screens.arc_set(s.name.clone()); } } diff --git a/src/backend/input.rs b/src/backend/input.rs index 7005c10..9ca6a7b 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -6,7 +6,7 @@ use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; use smallvec::{smallvec, SmallVec}; use crate::backend::common::{snap_upright, OverlaySelector}; -use crate::config::{save_state, AStrMapExt, GeneralConfig}; +use crate::config::{AStrMapExt, GeneralConfig}; use crate::overlays::anchor::ANCHOR_NAME; use crate::state::AppState; @@ -538,21 +538,17 @@ impl Pointer { if let Some(grab_data) = self.interaction.grabbed.as_ref() { if overlay.state.curvature != grab_data.old_curvature { if let Some(val) = overlay.state.curvature { - config.curve_values.arc_ins(overlay.state.name.clone(), val); + config.curve_values.arc_set(overlay.state.name.clone(), val); } else { let ref_name = overlay.state.name.as_ref(); config.curve_values.arc_rm(ref_name); } } - config.transform_values.arc_ins( - overlay.state.name.clone(), - overlay.state.saved_transform.unwrap(), - ); - match save_state(config) { - Ok(_) => log::debug!("Saved state"), - Err(e) => log::error!("Failed to save state: {:?}", e), - } } + config.transform_values.arc_set( + overlay.state.name.clone(), + overlay.state.saved_transform.unwrap(), + ); } self.interaction.grabbed = None; diff --git a/src/config.rs b/src/config.rs index cba7ccc..d544a6f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -23,16 +23,15 @@ use serde::Serialize; pub type AStrMap = Vec<(Arc, V)>; pub trait AStrMapExt { - fn arc_ins(&mut self, key: Arc, value: V) -> bool; + fn arc_set(&mut self, key: Arc, value: V) -> bool; fn arc_get(&self, key: &str) -> Option<&V>; fn arc_rm(&mut self, key: &str) -> Option; } impl AStrMapExt for AStrMap { - fn arc_ins(&mut self, key: Arc, value: V) -> bool { - if self.iter().any(|(k, _)| k.as_ref().eq(key.as_ref())) { - return false; - } + fn arc_set(&mut self, key: Arc, value: V) -> bool { + let index = self.iter().position(|(k, _)| k.as_ref().eq(key.as_ref())); + index.map(|i| self.remove(i).1); self.push((key, value)); true } @@ -51,13 +50,13 @@ impl AStrMapExt for AStrMap { pub type AStrSet = Vec>; pub trait AStrSetExt { - fn arc_ins(&mut self, value: Arc) -> bool; + fn arc_set(&mut self, value: Arc) -> bool; fn arc_get(&self, value: &str) -> bool; fn arc_rm(&mut self, value: &str) -> bool; } impl AStrSetExt for AStrSet { - fn arc_ins(&mut self, value: Arc) -> bool { + fn arc_set(&mut self, value: Arc) -> bool { if self.iter().any(|v| v.as_ref().eq(value.as_ref())) { return false; } @@ -416,7 +415,7 @@ fn get_state_path() -> PathBuf { path } -pub fn save_state(config: &GeneralConfig) -> anyhow::Result<()> { +pub fn save_layout(config: &GeneralConfig) -> anyhow::Result<()> { let conf = AutoState { show_screens: config.show_screens.clone(), curve_values: config.curve_values.clone(), diff --git a/src/gui/modular/button.rs b/src/gui/modular/button.rs index d7921c1..190bb3a 100644 --- a/src/gui/modular/button.rs +++ b/src/gui/modular/button.rs @@ -16,7 +16,7 @@ use crate::{ overlay::RelativeTo, task::{ColorChannel, SystemTask, TaskType}, }, - config::{save_settings, save_state, AStrSetExt}, + config::{save_layout, save_settings, AStrSetExt}, overlays::{ toast::{Toast, ToastTopic}, watch::WATCH_NAME, @@ -59,6 +59,7 @@ pub enum SystemAction { PlayspaceFixFloor, RecalculateExtent, PersistConfig, + PersistLayout, } #[derive(Deserialize, Clone)] @@ -418,6 +419,11 @@ fn run_system(action: &SystemAction, app: &mut AppState) { log::error!("Failed to save config: {:?}", e); } } + SystemAction::PersistLayout => { + if let Err(e) = save_layout(&app.session.config) { + log::error!("Failed to save layout: {:?}", e); + } + } } } @@ -594,11 +600,11 @@ fn run_overlay(overlay: &OverlaySelector, action: &OverlayAction, app: &mut AppS if !o.want_visible { state_dirty |= app.session.config.show_screens.arc_rm(o.name.as_ref()); } else if o.want_visible { - state_dirty |= app.session.config.show_screens.arc_ins(o.name.clone()); + state_dirty |= app.session.config.show_screens.arc_set(o.name.clone()); } if state_dirty { - match save_state(&app.session.config) { + match save_layout(&app.session.config) { Ok(_) => log::debug!("Saved state"), Err(e) => log::error!("Failed to save state: {:?}", e), } diff --git a/src/res/settings.yaml b/src/res/settings.yaml index 39f1839..cdb7ca0 100644 --- a/src/res/settings.yaml +++ b/src/res/settings.yaml @@ -591,4 +591,18 @@ elements: click_down: - type: System action: PersistConfig + - type: Toast + message: Settings saved successfully. + + - type: Button + rect: [30, 625, 250, 30] + font_size: 12 + fg_color: "#ffffff" + bg_color: "#206060" + text: "Save Overlay Layout" + click_down: + - type: System + action: PersistLayout + - type: Toast + message: Saved. You will see this layout on next startup.