use std::sync::Arc;
use egui::{TextStyle, Ui, Vec2};
use nih_plug::prelude::{Param, ParamFlags, ParamPtr, ParamSetter, Params};
use super::ParamSlider;
pub trait ParamWidget {
fn add_widget<P: Param>(&self, ui: &mut Ui, param: &P, setter: &ParamSetter);
unsafe fn add_widget_raw(&self, ui: &mut Ui, param: &ParamPtr, setter: &ParamSetter) {
match param {
ParamPtr::FloatParam(p) => self.add_widget(ui, &**p, setter),
ParamPtr::IntParam(p) => self.add_widget(ui, &**p, setter),
ParamPtr::BoolParam(p) => self.add_widget(ui, &**p, setter),
ParamPtr::EnumParam(p) => self.add_widget(ui, &**p, setter),
}
}
}
pub struct GenericSlider;
pub fn create(
ui: &mut Ui,
params: Arc<impl Params>,
setter: &ParamSetter,
widget: impl ParamWidget,
) {
let padding = Vec2::splat(ui.text_style_height(&TextStyle::Body) * 0.2);
egui::containers::ScrollArea::vertical()
.auto_shrink([false, false])
.show(ui, |ui| {
let mut first_widget = true;
for (_, param_ptr, _) in params.param_map().into_iter() {
let flags = unsafe { param_ptr.flags() };
if flags.contains(ParamFlags::HIDE_IN_GENERIC_UI) {
continue;
}
if !first_widget {
ui.allocate_space(padding);
}
ui.label(unsafe { param_ptr.name() });
unsafe { widget.add_widget_raw(ui, ¶m_ptr, setter) };
first_widget = false;
}
});
}
impl ParamWidget for GenericSlider {
fn add_widget<P: Param>(&self, ui: &mut Ui, param: &P, setter: &ParamSetter) {
ui.add(ParamSlider::for_param(param, setter).with_width(100.0));
}
}