feat: draggable crossover handles with dynamic lo<=hi limit

Replace the two plain crossover sliders with a horizontal log-frequency strip
(LOW/MID/HIGH) and two draggable handles, plus number boxes (double-click to
type). Handles and boxes enforce a dynamic limit so lo/mid never crosses
mid/hi, on top of each param's own range. Lives in the editor/ widget module.

Known limitation: the lo<=hi limit is editor-only, so host automation can write
the two params past each other (briefly inverting the mid band). The DSP clamps
to monotonic, but FL's automation can misbehave once inverted. Left as-is.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mikkeli Matlock
2026-06-24 16:55:30 +09:00
parent 514fd964f6
commit 3aeb09957a
2 changed files with 144 additions and 6 deletions
+3 -6
View File
@@ -19,6 +19,7 @@ use crate::meters::Meters;
use crate::params::{Codename206Params, CompressorParams};
use crate::Codename206;
mod crossover;
mod meter;
mod plot;
@@ -75,14 +76,10 @@ pub(crate) fn create(params: Arc<Codename206Params>, meters: Arc<Meters>) -> Opt
ui.separator();
plot::draw(ui, &meters, &mut state.plot);
ui.separator();
crossover::draw(ui, &params, setter);
ui.separator();
// 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(&params.crossover_low_hz, setter));
ui.end_row();
ui.label("Xover Mid/Hi");
ui.add(widgets::ParamSlider::for_param(&params.crossover_high_hz, setter));
ui.end_row();
ui.label("Look-ahead");
ui.add(widgets::ParamSlider::for_param(&params.look_ahead_ms, setter));
ui.end_row();