Skip to main content

nice_plug_iced/
lib.rs

1use std::sync::{Arc, Mutex};
2
3use crossbeam_utils::atomic::AtomicCell;
4use iced_baseview::{PollSubNotifier, Program};
5use nice_plug_core::editor::Editor;
6use serde::{Deserialize, Serialize};
7
8pub use iced_baseview as iced;
9
10pub mod application;
11#[doc(inline)]
12pub use application::application;
13pub use application::{Application, EditorState};
14
15mod editor;
16pub use editor::{NiceGuiContext, WindowState};
17
18/// Create a new `Editor` using the Iced GUI framework.
19///
20/// * `window_state` - The initial window state.
21/// * `editor_state` - Custom state which persists between editor opens.
22/// * `notifier` - An atomic flag used to notify the program when it should
23///   poll for new updates and redraw (i.e. as a result of the host updating
24///   parameters or the audio thread updating the state of meters). This flag
25///   is polled every frame right before drawing. If the flag is set then the
26///   `poll_events` subscription will be called.
27/// * `settings` - Additional settings for the editor.
28/// * `build` - The function which builds the Iced program.
29pub fn create_iced_editor<P, B, EState>(
30    window_state: Arc<WindowState>,
31    editor_state: EState,
32    notifier: PollSubNotifier,
33    settings: EditorSettings,
34    build: B,
35) -> Option<Box<dyn Editor>>
36where
37    P: Program + 'static,
38    B: Fn(EditorState<EState>, NiceGuiContext) -> P + 'static + Send + Sync,
39    EState: Send + 'static,
40{
41    Some(Box::new(editor::IcedEditor {
42        window_state,
43        editor_state: Arc::new(Mutex::new(Some(editor_state))),
44        settings: Arc::new(settings),
45        build: Arc::new(build),
46        notifier,
47
48        // TODO: We can't get the size of the window when baseview does its own scaling, so if the
49        //       host does not set a scale factor on Windows or Linux we should just use a factor of
50        //       1. That may make the GUI tiny but it also prevents it from getting cut off.
51        #[cfg(target_os = "macos")]
52        scaling_factor: AtomicCell::new(None),
53        #[cfg(not(target_os = "macos"))]
54        scaling_factor: AtomicCell::new(Some(1.0)),
55    }))
56}
57
58#[derive(Default, Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
59pub struct EditorSettings {
60    /// Ignore key inputs, except for modifier keys such as SHIFT and ALT
61    pub ignore_non_modifier_keys: bool,
62
63    /// Always redraw whenever the baseview window updates instead of only when iced wants to update
64    /// the window. This works around a current baseview limitation where it does not support
65    /// trigger a redraw on window visibility change (which may cause blank windows when opening or
66    /// reopening the editor) and an iced limitation where it's not possible to have animations
67    /// without using an asynchronous timer stream to send redraw messages to the application.
68    pub always_redraw: bool,
69}