Move Editor and ParentWindowHandle to a new module
This commit is contained in:
parent
34cc1ba30b
commit
6ee3aafa91
|
@ -6,6 +6,11 @@ new and what's changed, this document lists all breaking changes in reverse
|
|||
chronological order. If a new feature did not require any changes to existing
|
||||
code then it will not be listed here.
|
||||
|
||||
## [2022-10-21]
|
||||
|
||||
- The `Editor` trait and the `ParentWindowHandle` struct have been moved from
|
||||
`nih_plug::plugin` to a new `nih_plug::editor` module.
|
||||
|
||||
## [2022-10-20]
|
||||
|
||||
- Similar to the below change, `Plugin` also no longer requires `Sync`.
|
||||
|
|
81
src/editor.rs
Normal file
81
src/editor.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
//! Traits for working with plugin editors.
|
||||
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::context::GuiContext;
|
||||
|
||||
/// An editor for a [`Plugin`][crate::prelude::Plugin].
|
||||
pub trait Editor: Send {
|
||||
/// Create an instance of the plugin's editor and embed it in the parent window. As explained in
|
||||
/// [`Plugin::editor()`][crate::prelude::Plugin::editor()], you can then read the parameter
|
||||
/// values directly from your [`Params`][crate::prelude::Params] object, and modifying the
|
||||
/// values can be done using the functions on the [`ParamSetter`][crate::prelude::ParamSetter].
|
||||
/// When you change a parameter value that way it will be broadcasted to the host and also
|
||||
/// updated in your [`Params`][crate::prelude::Params] struct.
|
||||
///
|
||||
/// This function should return a handle to the editor, which will be dropped when the editor
|
||||
/// gets closed. Implement the [`Drop`] trait on the returned handle if you need to explicitly
|
||||
/// handle the editor's closing behavior.
|
||||
///
|
||||
/// If [`set_scale_factor()`][Self::set_scale_factor()] has been called, then any created
|
||||
/// windows should have their sizes multiplied by that factor.
|
||||
///
|
||||
/// The wrapper guarantees that a previous handle has been dropped before this function is
|
||||
/// called again.
|
||||
//
|
||||
// TODO: Think of how this would work with the event loop. On Linux the wrapper must provide a
|
||||
// timer using VST3's `IRunLoop` interface, but on Window and macOS the window would
|
||||
// normally register its own timer. Right now we just ignore this because it would
|
||||
// otherwise be basically impossible to have this still be GUI-framework agnostic. Any
|
||||
// callback that deos involve actual GUI operations will still be spooled to the IRunLoop
|
||||
// instance.
|
||||
// TODO: This function should return an `Option` instead. Right now window opening failures are
|
||||
// always fatal. This would need to be fixed in baseview first.
|
||||
fn spawn(
|
||||
&self,
|
||||
parent: ParentWindowHandle,
|
||||
context: Arc<dyn GuiContext>,
|
||||
) -> Box<dyn Any + Send>;
|
||||
|
||||
/// Returns the (current) size of the editor in pixels as a `(width, height)` pair. This size
|
||||
/// must be reported in _logical pixels_, i.e. the size before being multiplied by the DPI
|
||||
/// scaling factor to get the actual physical screen pixels.
|
||||
fn size(&self) -> (u32, u32);
|
||||
|
||||
/// Set the DPI scaling factor, if supported. The plugin APIs don't make any guarantees on when
|
||||
/// this is called, but for now just assume it will be the first function that gets called
|
||||
/// before creating the editor. If this is set, then any windows created by this editor should
|
||||
/// have their sizes multiplied by this scaling factor on Windows and Linux.
|
||||
///
|
||||
/// Right now this is never called on macOS since DPI scaling is built into the operating system
|
||||
/// there.
|
||||
fn set_scale_factor(&self, factor: f32) -> bool;
|
||||
|
||||
/// A callback that will be called whenever the parameter values changed while the editor is
|
||||
/// open. You don't need to do anything with this, but this can be used to force a redraw when
|
||||
/// the host sends a new value for a parameter or when a parameter change sent to the host gets
|
||||
/// processed.
|
||||
///
|
||||
/// This function will be called from the **audio thread**. It must thus be lock-free and may
|
||||
/// not allocate.
|
||||
fn param_values_changed(&self);
|
||||
|
||||
// TODO: Reconsider adding a tick function here for the Linux `IRunLoop`. To keep this platform
|
||||
// and API agnostic, add a way to ask the GuiContext if the wrapper already provides a
|
||||
// tick function. If it does not, then the Editor implementation must handle this by
|
||||
// itself. This would also need an associated `PREFERRED_FRAME_RATE` constant.
|
||||
// TODO: Host->Plugin resizing
|
||||
}
|
||||
|
||||
/// A raw window handle for platform and GUI framework agnostic editors.
|
||||
pub struct ParentWindowHandle {
|
||||
pub handle: RawWindowHandle,
|
||||
}
|
||||
|
||||
unsafe impl HasRawWindowHandle for ParentWindowHandle {
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
self.handle
|
||||
}
|
||||
}
|
|
@ -103,6 +103,7 @@ pub mod util;
|
|||
|
||||
pub mod buffer;
|
||||
pub mod context;
|
||||
pub mod editor;
|
||||
mod event_loop;
|
||||
pub mod midi;
|
||||
pub mod params;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
//! Traits and structs describing plugins and editors.
|
||||
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::buffer::Buffer;
|
||||
use crate::context::{GuiContext, InitContext, ProcessContext};
|
||||
use crate::context::{InitContext, ProcessContext};
|
||||
use crate::editor::Editor;
|
||||
use crate::midi::MidiConfig;
|
||||
use crate::params::Params;
|
||||
use crate::wrapper::clap::features::ClapFeature;
|
||||
|
@ -252,79 +251,6 @@ const fn swap_vst3_uid_byte_order(mut uid: [u8; 16]) -> [u8; 16] {
|
|||
uid
|
||||
}
|
||||
|
||||
/// An editor for a [`Plugin`].
|
||||
pub trait Editor: Send {
|
||||
/// Create an instance of the plugin's editor and embed it in the parent window. As explained in
|
||||
/// [`Plugin::editor()`], you can then read the parameter values directly from your [`Params`]
|
||||
/// object, and modifying the values can be done using the functions on the
|
||||
/// [`ParamSetter`][crate::prelude::ParamSetter]. When you change a parameter value that way it will be
|
||||
/// broadcasted to the host and also updated in your [`Params`] struct.
|
||||
///
|
||||
/// This function should return a handle to the editor, which will be dropped when the editor
|
||||
/// gets closed. Implement the [`Drop`] trait on the returned handle if you need to explicitly
|
||||
/// handle the editor's closing behavior.
|
||||
///
|
||||
/// If [`set_scale_factor()`][Self::set_scale_factor()] has been called, then any created
|
||||
/// windows should have their sizes multiplied by that factor.
|
||||
///
|
||||
/// The wrapper guarantees that a previous handle has been dropped before this function is
|
||||
/// called again.
|
||||
//
|
||||
// TODO: Think of how this would work with the event loop. On Linux the wrapper must provide a
|
||||
// timer using VST3's `IRunLoop` interface, but on Window and macOS the window would
|
||||
// normally register its own timer. Right now we just ignore this because it would
|
||||
// otherwise be basically impossible to have this still be GUI-framework agnostic. Any
|
||||
// callback that deos involve actual GUI operations will still be spooled to the IRunLoop
|
||||
// instance.
|
||||
// TODO: This function should return an `Option` instead. Right now window opening failures are
|
||||
// always fatal. This would need to be fixed in baseview first.
|
||||
fn spawn(
|
||||
&self,
|
||||
parent: ParentWindowHandle,
|
||||
context: Arc<dyn GuiContext>,
|
||||
) -> Box<dyn Any + Send>;
|
||||
|
||||
/// Returns the (current) size of the editor in pixels as a `(width, height)` pair. This size
|
||||
/// must be reported in _logical pixels_, i.e. the size before being multiplied by the DPI
|
||||
/// scaling factor to get the actual physical screen pixels.
|
||||
fn size(&self) -> (u32, u32);
|
||||
|
||||
/// Set the DPI scaling factor, if supported. The plugin APIs don't make any guarantees on when
|
||||
/// this is called, but for now just assume it will be the first function that gets called
|
||||
/// before creating the editor. If this is set, then any windows created by this editor should
|
||||
/// have their sizes multiplied by this scaling factor on Windows and Linux.
|
||||
///
|
||||
/// Right now this is never called on macOS since DPI scaling is built into the operating system
|
||||
/// there.
|
||||
fn set_scale_factor(&self, factor: f32) -> bool;
|
||||
|
||||
/// A callback that will be called whenever the parameter values changed while the editor is
|
||||
/// open. You don't need to do anything with this, but this can be used to force a redraw when
|
||||
/// the host sends a new value for a parameter or when a parameter change sent to the host gets
|
||||
/// processed.
|
||||
///
|
||||
/// This function will be called from the **audio thread**. It must thus be lock-free and may
|
||||
/// not allocate.
|
||||
fn param_values_changed(&self);
|
||||
|
||||
// TODO: Reconsider adding a tick function here for the Linux `IRunLoop`. To keep this platform
|
||||
// and API agnostic, add a way to ask the GuiContext if the wrapper already provides a
|
||||
// tick function. If it does not, then the Editor implementation must handle this by
|
||||
// itself. This would also need an associated `PREFERRED_FRAME_RATE` constant.
|
||||
// TODO: Host->Plugin resizing
|
||||
}
|
||||
|
||||
/// A raw window handle for platform and GUI framework agnostic editors.
|
||||
pub struct ParentWindowHandle {
|
||||
pub handle: RawWindowHandle,
|
||||
}
|
||||
|
||||
unsafe impl HasRawWindowHandle for ParentWindowHandle {
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
self.handle
|
||||
}
|
||||
}
|
||||
|
||||
/// The plugin's IO configuration.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct BusConfig {
|
||||
|
|
|
@ -13,6 +13,7 @@ pub use crate::util;
|
|||
pub use crate::buffer::Buffer;
|
||||
pub use crate::context::{GuiContext, InitContext, ParamSetter, PluginApi, ProcessContext};
|
||||
// This also includes the derive macro
|
||||
pub use crate::editor::{Editor, ParentWindowHandle};
|
||||
pub use crate::midi::{control_change, MidiConfig, NoteEvent};
|
||||
pub use crate::params::enums::{Enum, EnumParam};
|
||||
pub use crate::params::internals::ParamPtr;
|
||||
|
@ -21,9 +22,8 @@ pub use crate::params::smoothing::{Smoothable, Smoother, SmoothingStyle};
|
|||
pub use crate::params::Params;
|
||||
pub use crate::params::{BoolParam, FloatParam, IntParam, Param, ParamFlags};
|
||||
pub use crate::plugin::{
|
||||
AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, ClapPlugin, Editor,
|
||||
ParentWindowHandle, Plugin, PolyModulationConfig, PortNames, ProcessMode, ProcessStatus,
|
||||
Vst3Plugin,
|
||||
AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, ClapPlugin, Plugin,
|
||||
PolyModulationConfig, PortNames, ProcessMode, ProcessStatus, Vst3Plugin,
|
||||
};
|
||||
pub use crate::wrapper::clap::features::ClapFeature;
|
||||
pub use crate::wrapper::state::PluginState;
|
||||
|
|
|
@ -78,13 +78,13 @@ use super::descriptor::PluginDescriptor;
|
|||
use super::util::ClapPtr;
|
||||
use crate::buffer::Buffer;
|
||||
use crate::context::Transport;
|
||||
use crate::editor::{Editor, ParentWindowHandle};
|
||||
use crate::event_loop::{EventLoop, MainThreadExecutor, TASK_QUEUE_CAPACITY};
|
||||
use crate::midi::{MidiConfig, NoteEvent};
|
||||
use crate::params::internals::ParamPtr;
|
||||
use crate::params::{ParamFlags, Params};
|
||||
use crate::plugin::{
|
||||
AuxiliaryBuffers, BufferConfig, BusConfig, ClapPlugin, Editor, ParentWindowHandle, ProcessMode,
|
||||
ProcessStatus,
|
||||
AuxiliaryBuffers, BufferConfig, BusConfig, ClapPlugin, ProcessMode, ProcessStatus,
|
||||
};
|
||||
use crate::util::permit_alloc;
|
||||
use crate::wrapper::clap::util::{read_stream, write_stream};
|
||||
|
|
|
@ -14,12 +14,13 @@ use super::backend::Backend;
|
|||
use super::config::WrapperConfig;
|
||||
use super::context::{WrapperGuiContext, WrapperInitContext, WrapperProcessContext};
|
||||
use crate::context::Transport;
|
||||
use crate::editor::{Editor, ParentWindowHandle};
|
||||
use crate::midi::NoteEvent;
|
||||
use crate::params::internals::ParamPtr;
|
||||
use crate::params::{ParamFlags, Params};
|
||||
use crate::plugin::{
|
||||
AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, Editor, ParentWindowHandle,
|
||||
Plugin, ProcessMode, ProcessStatus,
|
||||
AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, Plugin, ProcessMode,
|
||||
ProcessStatus,
|
||||
};
|
||||
use crate::util::permit_alloc;
|
||||
use crate::wrapper::state::{self, PluginState};
|
||||
|
|
|
@ -16,11 +16,12 @@ use super::util::{ObjectPtr, VstPtr, VST3_MIDI_PARAMS_END, VST3_MIDI_PARAMS_STAR
|
|||
use super::view::WrapperView;
|
||||
use crate::buffer::Buffer;
|
||||
use crate::context::Transport;
|
||||
use crate::editor::Editor;
|
||||
use crate::event_loop::{EventLoop, MainThreadExecutor, OsEventLoop};
|
||||
use crate::midi::{MidiConfig, NoteEvent};
|
||||
use crate::params::internals::ParamPtr;
|
||||
use crate::params::{ParamFlags, Params};
|
||||
use crate::plugin::{BufferConfig, BusConfig, Editor, ProcessMode, ProcessStatus, Vst3Plugin};
|
||||
use crate::plugin::{BufferConfig, BusConfig, ProcessMode, ProcessStatus, Vst3Plugin};
|
||||
use crate::wrapper::state::{self, PluginState};
|
||||
use crate::wrapper::util::{hash_param_id, process_wrapper};
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ use vst3_sys::VST3;
|
|||
|
||||
use super::inner::{Task, WrapperInner};
|
||||
use super::util::{ObjectPtr, VstPtr};
|
||||
use crate::plugin::{Editor, ParentWindowHandle, Vst3Plugin};
|
||||
use crate::editor::{Editor, ParentWindowHandle};
|
||||
use crate::plugin::Vst3Plugin;
|
||||
|
||||
// Alias needed for the VST3 attribute macro
|
||||
use vst3_sys as vst3_com;
|
||||
|
|
Loading…
Reference in a new issue