Replace gain_gui's editor with an iced stub
This commit is contained in:
parent
fda9cde064
commit
664267745a
4 changed files with 126 additions and 61 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1170,7 +1170,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic_float",
|
"atomic_float",
|
||||||
"nih_plug",
|
"nih_plug",
|
||||||
"nih_plug_egui",
|
"nih_plug_iced",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -10,6 +10,6 @@ crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nih_plug = { path = "../../../", features = ["assert_process_allocs"] }
|
nih_plug = { path = "../../../", features = ["assert_process_allocs"] }
|
||||||
nih_plug_egui = { path = "../../../nih_plug_egui" }
|
nih_plug_iced = { path = "../../../nih_plug_iced" }
|
||||||
|
|
||||||
atomic_float = "0.1"
|
atomic_float = "0.1"
|
||||||
|
|
118
plugins/examples/gain-gui/src/editor.rs
Normal file
118
plugins/examples/gain-gui/src/editor.rs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
use nih_plug::prelude::{Editor, GuiContext};
|
||||||
|
use nih_plug_iced::widgets::ParamMessage;
|
||||||
|
use nih_plug_iced::*;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::GainParams;
|
||||||
|
|
||||||
|
// Makes sense to also define this here, makes it a bit easier to keep track of
|
||||||
|
pub(crate) fn default_state() -> Arc<IcedState> {
|
||||||
|
IcedState::from_size(200, 150)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create(
|
||||||
|
params: Pin<Arc<GainParams>>,
|
||||||
|
editor_state: Arc<IcedState>,
|
||||||
|
) -> Option<Box<dyn Editor>> {
|
||||||
|
create_iced_editor::<GainEditor>(editor_state, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GainEditor {
|
||||||
|
params: Pin<Arc<GainParams>>,
|
||||||
|
context: Arc<dyn GuiContext>,
|
||||||
|
|
||||||
|
gain_dummy_state: widget::button::State,
|
||||||
|
meter_dummy_state: widget::button::State,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Message {
|
||||||
|
/// Update a parameter's value.
|
||||||
|
ParamUpdate(ParamMessage),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IcedEditor for GainEditor {
|
||||||
|
type Executor = executor::Default;
|
||||||
|
type Message = Message;
|
||||||
|
type InitializationFlags = Pin<Arc<GainParams>>;
|
||||||
|
|
||||||
|
fn new(
|
||||||
|
params: Self::InitializationFlags,
|
||||||
|
context: Arc<dyn GuiContext>,
|
||||||
|
) -> (Self, Command<Self::Message>) {
|
||||||
|
let editor = GainEditor {
|
||||||
|
params,
|
||||||
|
context,
|
||||||
|
gain_dummy_state: widget::button::State::new(),
|
||||||
|
meter_dummy_state: widget::button::State::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
(editor, Command::none())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn context(&self) -> &dyn GuiContext {
|
||||||
|
self.context.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
_window: &mut WindowQueue,
|
||||||
|
message: Self::Message,
|
||||||
|
) -> Command<Self::Message> {
|
||||||
|
match message {
|
||||||
|
Message::ParamUpdate(message) => self.handle_param_message(message),
|
||||||
|
}
|
||||||
|
|
||||||
|
Command::none()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view(&mut self) -> Element<'_, Self::Message> {
|
||||||
|
Column::new()
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
.push(
|
||||||
|
Text::new("Gain GUI")
|
||||||
|
.size(40)
|
||||||
|
.height(45.into())
|
||||||
|
.width(Length::Fill)
|
||||||
|
.horizontal_alignment(alignment::Horizontal::Center)
|
||||||
|
.vertical_alignment(alignment::Vertical::Bottom),
|
||||||
|
)
|
||||||
|
.push(
|
||||||
|
Text::new("Gain")
|
||||||
|
.height(25.into())
|
||||||
|
.width(Length::Fill)
|
||||||
|
.horizontal_alignment(alignment::Horizontal::Center)
|
||||||
|
.vertical_alignment(alignment::Vertical::Center),
|
||||||
|
)
|
||||||
|
.push(
|
||||||
|
Button::new(&mut self.gain_dummy_state, Text::new("Gain"))
|
||||||
|
.height(30.into())
|
||||||
|
.width(180.into()),
|
||||||
|
)
|
||||||
|
.push(Space::with_height(10.into()))
|
||||||
|
.push(
|
||||||
|
Button::new(&mut self.meter_dummy_state, Text::new("Meter"))
|
||||||
|
.height(15.into())
|
||||||
|
.width(180.into()),
|
||||||
|
)
|
||||||
|
.push(
|
||||||
|
Text::new("Ticks 'n stuff")
|
||||||
|
.size(12)
|
||||||
|
.height(15.into())
|
||||||
|
.width(Length::Fill)
|
||||||
|
.horizontal_alignment(alignment::Horizontal::Center)
|
||||||
|
.vertical_alignment(alignment::Vertical::Center),
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn background_color(&self) -> nih_plug_iced::Color {
|
||||||
|
nih_plug_iced::Color {
|
||||||
|
r: 0.98,
|
||||||
|
g: 0.98,
|
||||||
|
b: 0.98,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,15 @@
|
||||||
use atomic_float::AtomicF32;
|
use atomic_float::AtomicF32;
|
||||||
use nih_plug::prelude::*;
|
use nih_plug::prelude::*;
|
||||||
use nih_plug_egui::{create_egui_editor, egui, widgets, EguiState};
|
use nih_plug_iced::IcedState;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
mod editor;
|
||||||
|
|
||||||
/// This is mostly identical to the gain example, minus some fluff, and with a GUI.
|
/// This is mostly identical to the gain example, minus some fluff, and with a GUI.
|
||||||
struct Gain {
|
struct Gain {
|
||||||
params: Pin<Arc<GainParams>>,
|
params: Pin<Arc<GainParams>>,
|
||||||
editor_state: Arc<EguiState>,
|
editor_state: Arc<IcedState>,
|
||||||
|
|
||||||
/// Needed to normalize the peak meter's response based on the sample rate.
|
/// Needed to normalize the peak meter's response based on the sample rate.
|
||||||
peak_meter_decay_weight: f32,
|
peak_meter_decay_weight: f32,
|
||||||
|
@ -33,7 +35,7 @@ impl Default for Gain {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
params: Arc::pin(GainParams::default()),
|
params: Arc::pin(GainParams::default()),
|
||||||
editor_state: EguiState::from_size(300, 180),
|
editor_state: editor::default_state(),
|
||||||
|
|
||||||
peak_meter_decay_weight: 1.0,
|
peak_meter_decay_weight: 1.0,
|
||||||
peak_meter: Arc::new(AtomicF32::new(util::MINUS_INFINITY_DB)),
|
peak_meter: Arc::new(AtomicF32::new(util::MINUS_INFINITY_DB)),
|
||||||
|
@ -79,62 +81,7 @@ impl Plugin for Gain {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn editor(&self) -> Option<Box<dyn Editor>> {
|
fn editor(&self) -> Option<Box<dyn Editor>> {
|
||||||
let params = self.params.clone();
|
editor::create(self.params.clone(), self.editor_state.clone())
|
||||||
let peak_meter = self.peak_meter.clone();
|
|
||||||
create_egui_editor(
|
|
||||||
self.editor_state.clone(),
|
|
||||||
(),
|
|
||||||
move |egui_ctx, setter, _state| {
|
|
||||||
egui::CentralPanel::default().show(egui_ctx, |ui| {
|
|
||||||
// NOTE: See `plugins/diopser/src/editor.rs` for an example using the generic UI widget
|
|
||||||
|
|
||||||
// This is a fancy widget that can get all the information it needs to properly
|
|
||||||
// display and modify the parameter from the parametr itself
|
|
||||||
// It's not yet fully implemented, as the text is missing.
|
|
||||||
ui.label("Some random integer");
|
|
||||||
ui.add(widgets::ParamSlider::for_param(¶ms.some_int, setter));
|
|
||||||
|
|
||||||
ui.label("Gain");
|
|
||||||
ui.add(widgets::ParamSlider::for_param(¶ms.gain, setter));
|
|
||||||
|
|
||||||
ui.label(
|
|
||||||
"Also gain, but with a lame widget. Can't even render the value correctly!",
|
|
||||||
);
|
|
||||||
// This is a simple naieve version of a parameter slider that's not aware of how
|
|
||||||
// the parmaeters work
|
|
||||||
ui.add(
|
|
||||||
egui::widgets::Slider::from_get_set(-30.0..=30.0, |new_value| {
|
|
||||||
match new_value {
|
|
||||||
Some(new_value) => {
|
|
||||||
setter.begin_set_parameter(¶ms.gain);
|
|
||||||
setter.set_parameter(¶ms.gain, new_value as f32);
|
|
||||||
setter.end_set_parameter(¶ms.gain);
|
|
||||||
new_value
|
|
||||||
}
|
|
||||||
None => params.gain.value as f64,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.suffix(" dB"),
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: Add a proper custom widget instead of reusing a progress bar
|
|
||||||
let peak_meter =
|
|
||||||
util::gain_to_db(peak_meter.load(std::sync::atomic::Ordering::Relaxed));
|
|
||||||
let peak_meter_text = if peak_meter > util::MINUS_INFINITY_DB {
|
|
||||||
format!("{:.1} dBFS", peak_meter)
|
|
||||||
} else {
|
|
||||||
String::from("-inf dBFS")
|
|
||||||
};
|
|
||||||
|
|
||||||
let peak_meter_normalized = (peak_meter + 60.0) / 60.0;
|
|
||||||
ui.allocate_space(egui::Vec2::splat(2.0));
|
|
||||||
ui.add(
|
|
||||||
egui::widgets::ProgressBar::new(peak_meter_normalized)
|
|
||||||
.text(peak_meter_text),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts_bus_config(&self, config: &BusConfig) -> bool {
|
fn accepts_bus_config(&self, config: &BusConfig) -> bool {
|
||||||
|
|
Loading…
Add table
Reference in a new issue