1
0
Fork 0

Make Arc<ViziaState> persistable

This allows the plugin instance's size and scale to be remembered.
This commit is contained in:
Robbert van der Helm 2022-07-13 23:07:59 +02:00
parent 2a1abf10e1
commit ef1d56646a
4 changed files with 48 additions and 5 deletions

1
Cargo.lock generated
View file

@ -2445,6 +2445,7 @@ dependencies = [
"crossbeam", "crossbeam",
"nih_plug", "nih_plug",
"nih_plug_assets", "nih_plug_assets",
"serde",
"vizia", "vizia",
] ]

View file

@ -13,6 +13,8 @@ nih_plug_assets = { git = "https://github.com/robbert-vdh/nih_plug_assets.git" }
baseview = { git = "https://github.com/robbert-vdh/baseview.git", branch = "feature/resize" } baseview = { git = "https://github.com/robbert-vdh/baseview.git", branch = "feature/resize" }
crossbeam = "0.8" crossbeam = "0.8"
# To make the state persistable
serde = { version = "1.0", features = ["derive"] }
# This fork contains changed for better keyboard modifier handling and DPI # This fork contains changed for better keyboard modifier handling and DPI
# scaling, window scaling, and a lot more fixes and improvements # scaling, window scaling, and a lot more fixes and improvements
vizia = { git = "https://github.com/robbert-vdh/vizia.git", branch = "patched", default_features = false, features = ["baseview", "clipboard", "x11"] } vizia = { git = "https://github.com/robbert-vdh/vizia.git", branch = "patched", default_features = false, features = ["baseview", "clipboard", "x11"] }

View file

@ -5,7 +5,9 @@
use baseview::{WindowHandle, WindowScalePolicy}; use baseview::{WindowHandle, WindowScalePolicy};
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
use nih_plug::param::internals::PersistentField;
use nih_plug::prelude::{Editor, GuiContext, ParentWindowHandle}; use nih_plug::prelude::{Editor, GuiContext, ParentWindowHandle};
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use vizia::prelude::*; use vizia::prelude::*;
@ -70,21 +72,36 @@ where
})) }))
} }
/// State for a `nih_plug_vizia` editor. The scale factor can be manipulated at runtime by changing /// State for an `nih_plug_vizia` editor. The scale factor can be manipulated at runtime by changing
/// `cx.user_scale_factor`. /// `cx.user_scale_factor`.
/// #[derive(Serialize, Deserialize)]
/// # TODO
///
/// Make this serializable so it can be persisted.
pub struct ViziaState { pub struct ViziaState {
/// The window's size in logical pixels before applying `scale_factor`. /// The window's size in logical pixels before applying `scale_factor`.
#[serde(with = "nih_plug::param::internals::serialize_atomic_cell")]
size: AtomicCell<(u32, u32)>, size: AtomicCell<(u32, u32)>,
/// A scale factor that should be applied to `size` separate from from any system HiDPI scaling. /// A scale factor that should be applied to `size` separate from from any system HiDPI scaling.
/// This can be used to allow GUIs to be scaled uniformly. /// This can be used to allow GUIs to be scaled uniformly.
#[serde(with = "nih_plug::param::internals::serialize_atomic_cell")]
scale_factor: AtomicCell<f64>, scale_factor: AtomicCell<f64>,
/// Whether the editor's window is currently open.
#[serde(skip)]
open: AtomicBool, open: AtomicBool,
} }
impl<'a> PersistentField<'a, ViziaState> for Arc<ViziaState> {
fn set(&self, new_value: ViziaState) {
self.size.store(new_value.size.load());
self.scale_factor.store(new_value.scale_factor.load());
}
fn map<F, R>(&self, f: F) -> R
where
F: Fn(&ViziaState) -> R,
{
f(self)
}
}
impl ViziaState { impl ViziaState {
/// Initialize the GUI's state. This value can be passed to [`create_vizia_editor()`]. The /// Initialize the GUI's state. This value can be passed to [`create_vizia_editor()`]. The
/// window size is in logical pixels, so before it is multiplied by the DPI scaling factor. /// window size is in logical pixels, so before it is multiplied by the DPI scaling factor.

View file

@ -10,6 +10,29 @@ pub use serde_json::from_str as deserialize_field;
/// Re-export for use in the [`Params`] proc-macro. /// Re-export for use in the [`Params`] proc-macro.
pub use serde_json::to_string as serialize_field; pub use serde_json::to_string as serialize_field;
/// Can be used with the `#[serde(with = "nih_plug::param::internals::serialize_atomic_cell")]`
/// attribute to serialize `AtomicCell<T>`s.
pub mod serialize_atomic_cell {
use crossbeam::atomic::AtomicCell;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<S, T>(cell: &AtomicCell<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Serialize + Copy,
{
cell.load().serialize(serializer)
}
pub fn deserialize<'de, D, T>(deserializer: D) -> Result<AtomicCell<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de> + Copy,
{
T::deserialize(deserializer).map(AtomicCell::new)
}
}
/// Describes a struct containing parameters and other persistent fields. /// Describes a struct containing parameters and other persistent fields.
/// ///
/// This trait can be derived on a struct containing [`FloatParam`][super::FloatParam] and other /// This trait can be derived on a struct containing [`FloatParam`][super::FloatParam] and other