diff --git a/Cargo.lock b/Cargo.lock index 0ae02b15..d7112916 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2423,6 +2423,7 @@ dependencies = [ "lazy_static", "nih_plug", "parking_lot 0.12.1", + "serde", ] [[package]] diff --git a/nih_plug_egui/Cargo.toml b/nih_plug_egui/Cargo.toml index 5edecdf3..76a37148 100644 --- a/nih_plug_egui/Cargo.toml +++ b/nih_plug_egui/Cargo.toml @@ -21,3 +21,5 @@ egui = "0.17" egui-baseview = { git = "https://github.com/robbert-vdh/egui-baseview.git", branch = "fix/update-dependencies" } lazy_static = "1.4" parking_lot = "0.12" +# To make the state persistable +serde = { version = "1.0", features = ["derive"] } diff --git a/nih_plug_egui/src/lib.rs b/nih_plug_egui/src/lib.rs index 5b963d07..d91b74f5 100644 --- a/nih_plug_egui/src/lib.rs +++ b/nih_plug_egui/src/lib.rs @@ -10,8 +10,10 @@ use baseview::{Size, WindowHandle, WindowOpenOptions, WindowScalePolicy}; use crossbeam::atomic::AtomicCell; use egui::Context; use egui_baseview::EguiWindow; +use nih_plug::param::internals::PersistentField; use nih_plug::prelude::{Editor, GuiContext, ParamSetter, ParentWindowHandle}; use parking_lot::RwLock; +use serde::{Deserialize, Serialize}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -57,13 +59,30 @@ where })) } -// TODO: Once we add resizing, we may want to be able to remember the GUI size. In that case we need -// to make this serializable (only restoring the size of course) so it can be persisted. +/// State for an `nih_plug_egui` editor. +#[derive(Serialize, Deserialize)] pub struct EguiState { + /// The window's size in logical pixels before applying `scale_factor`. + #[serde(with = "nih_plug::param::internals::serialize_atomic_cell")] size: AtomicCell<(u32, u32)>, + /// Whether the editor's window is currently open. + #[serde(skip)] open: AtomicBool, } +impl<'a> PersistentField<'a, EguiState> for Arc { + fn set(&self, new_value: EguiState) { + self.size.store(new_value.size.load()); + } + + fn map(&self, f: F) -> R + where + F: Fn(&EguiState) -> R, + { + f(self) + } +} + impl EguiState { /// Initialize the GUI's state. This value can be passed to [`create_egui_editor()`]. The window /// size is in logical pixels, so before it is multiplied by the DPI scaling factor.