84 lines
4.1 KiB
Rust
84 lines
4.1 KiB
Rust
|
|
//! egui editor.
|
||
|
|
//!
|
||
|
|
//! Placeholder layout for now — Stage 6 replaces it with meters, gain-reduction displays, a
|
||
|
|
//! gain-curve view and draggable crossover handles. Built to stay usable meanwhile: a resizable
|
||
|
|
//! window with a vertical scroll area so every control is reachable at any window size, global
|
||
|
|
//! controls in a label|slider grid, and the four channels (low/mid/high/all) side by side.
|
||
|
|
|
||
|
|
use nih_plug::prelude::*;
|
||
|
|
use nih_plug_egui::{
|
||
|
|
create_egui_editor,
|
||
|
|
egui::{self, Vec2},
|
||
|
|
resizable_window::ResizableWindow,
|
||
|
|
widgets,
|
||
|
|
};
|
||
|
|
use std::sync::Arc;
|
||
|
|
|
||
|
|
use crate::params::{Codename206Params, CompressorParams};
|
||
|
|
use crate::Codename206;
|
||
|
|
|
||
|
|
/// Build the plugin editor over a shared handle to the params.
|
||
|
|
pub(crate) fn create(params: Arc<Codename206Params>) -> Option<Box<dyn Editor>> {
|
||
|
|
let egui_state = params.editor_state.clone();
|
||
|
|
create_egui_editor(
|
||
|
|
params.editor_state.clone(),
|
||
|
|
(),
|
||
|
|
|_, _| {},
|
||
|
|
move |egui_ctx, setter, _state| {
|
||
|
|
// One column of controls for a single compressor channel.
|
||
|
|
let band_col = |ui: &mut egui::Ui, title: &str, p: &CompressorParams| {
|
||
|
|
ui.strong(title);
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.detection, setter));
|
||
|
|
ui.label("Threshold");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.threshold_db, setter));
|
||
|
|
ui.label("Ratio");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.ratio, setter));
|
||
|
|
ui.label("Knee");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.knee_db, setter));
|
||
|
|
ui.label("Attack");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.attack_ms, setter));
|
||
|
|
ui.label("Release");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.release_ms, setter));
|
||
|
|
ui.label("Makeup");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.makeup_db, setter));
|
||
|
|
ui.add(widgets::ParamSlider::for_param(&p.bypass, setter));
|
||
|
|
};
|
||
|
|
|
||
|
|
// Resizable window; vertical scroll so every control stays reachable even when the
|
||
|
|
// window is small. (Placeholder layout — Stage 6 will replace it.)
|
||
|
|
ResizableWindow::new("editor")
|
||
|
|
.min_size(Vec2::new(480.0, 320.0))
|
||
|
|
.show(egui_ctx, egui_state.as_ref(), |ui| {
|
||
|
|
egui::ScrollArea::vertical().show(ui, |ui| {
|
||
|
|
ui.heading(Codename206::NAME);
|
||
|
|
// Global controls stacked vertically so they never overflow sideways.
|
||
|
|
egui::Grid::new("globals").num_columns(2).show(ui, |ui| {
|
||
|
|
ui.label("Xover Lo/Mid");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(¶ms.crossover_low_hz, setter));
|
||
|
|
ui.end_row();
|
||
|
|
ui.label("Xover Mid/Hi");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(¶ms.crossover_high_hz, setter));
|
||
|
|
ui.end_row();
|
||
|
|
ui.label("Look-ahead");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(¶ms.look_ahead_ms, setter));
|
||
|
|
ui.end_row();
|
||
|
|
ui.label("Ceiling");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(¶ms.output_ceiling_db, setter));
|
||
|
|
ui.end_row();
|
||
|
|
ui.label("Lim Release");
|
||
|
|
ui.add(widgets::ParamSlider::for_param(¶ms.limiter_release_ms, setter));
|
||
|
|
ui.end_row();
|
||
|
|
});
|
||
|
|
ui.separator();
|
||
|
|
ui.columns(4, |cols| {
|
||
|
|
band_col(&mut cols[0], "LOW", ¶ms.low);
|
||
|
|
band_col(&mut cols[1], "MID", ¶ms.mid);
|
||
|
|
band_col(&mut cols[2], "HIGH", ¶ms.high);
|
||
|
|
band_col(&mut cols[3], "ALL", ¶ms.all);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
},
|
||
|
|
)
|
||
|
|
}
|