redesign
This commit is contained in:
@@ -3,33 +3,23 @@ use vizia::prelude::*;
|
||||
|
||||
use crate::widgets::piano::PianoKeyboard;
|
||||
|
||||
pub const MOD_NSRC: usize = 19;
|
||||
pub const MOD_NDST: usize = 11;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Data)]
|
||||
pub enum Panel {
|
||||
Osc,
|
||||
Env,
|
||||
Lfo,
|
||||
Filter,
|
||||
Fx,
|
||||
ModMatrix,
|
||||
Voice,
|
||||
Effects,
|
||||
Matrix,
|
||||
}
|
||||
|
||||
impl Panel {
|
||||
pub const ALL: &'static [Self] = &[
|
||||
Self::Osc,
|
||||
Self::Env,
|
||||
Self::Lfo,
|
||||
Self::Filter,
|
||||
Self::Fx,
|
||||
Self::ModMatrix,
|
||||
];
|
||||
pub const ALL: &'static [Self] = &[Self::Voice, Self::Effects, Self::Matrix];
|
||||
pub fn label(self) -> &'static str {
|
||||
match self {
|
||||
Self::Osc => "OSC",
|
||||
Self::Env => "ENV",
|
||||
Self::Lfo => "LFO",
|
||||
Self::Filter => "FLT",
|
||||
Self::Fx => "FX",
|
||||
Self::ModMatrix => "MOD",
|
||||
Self::Voice => "VOICE",
|
||||
Self::Effects => "EFFECTS",
|
||||
Self::Matrix => "MATRIX",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +36,11 @@ pub struct AppData {
|
||||
pub store: ParamStore,
|
||||
pub held_notes: Vec<u8>,
|
||||
pub octave: i32,
|
||||
pub mod_depths: Vec<f32>,
|
||||
pub fx_enabled: Vec<bool>,
|
||||
pub active_env: usize,
|
||||
pub active_lfo: usize,
|
||||
pub fx_selected: usize,
|
||||
}
|
||||
|
||||
impl AppData {
|
||||
@@ -56,13 +51,18 @@ impl AppData {
|
||||
Self {
|
||||
params,
|
||||
store,
|
||||
active_panel: Panel::Osc,
|
||||
active_panel: Panel::Voice,
|
||||
preset_name: "Init".into(),
|
||||
voice_count: 0,
|
||||
cpu_load: 0.0,
|
||||
host_bpm: 120.0,
|
||||
held_notes: Vec::new(),
|
||||
octave: 4,
|
||||
mod_depths: vec![0.0; MOD_NSRC * MOD_NDST],
|
||||
fx_enabled: vec![true; 6],
|
||||
active_env: 0,
|
||||
active_lfo: 0,
|
||||
fx_selected: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,13 +70,18 @@ impl AppData {
|
||||
#[derive(Debug)]
|
||||
pub enum AppEvent {
|
||||
SetParam(ParamId, f32),
|
||||
SetParamRaw(ParamId, f32),
|
||||
SetPanel(Panel),
|
||||
UpdateMetrics { voices: u8, cpu: f32 },
|
||||
|
||||
NoteOn(u8, u8),
|
||||
NoteOff(u8),
|
||||
OctaveUp,
|
||||
OctaveDown,
|
||||
SetModDepth { src: usize, dst: usize, depth: f32 },
|
||||
ToggleFx(usize),
|
||||
SelectEnv(usize),
|
||||
SelectLfo(usize),
|
||||
SelectFx(usize),
|
||||
}
|
||||
|
||||
impl Model for AppData {
|
||||
@@ -87,12 +92,16 @@ impl Model for AppData {
|
||||
self.params[*id as usize] = v;
|
||||
self.store.set(*id, v);
|
||||
}
|
||||
AppEvent::SetParamRaw(id, val) => {
|
||||
self.params[*id as usize] = *val;
|
||||
self.store.set(*id, *val);
|
||||
}
|
||||
AppEvent::SetPanel(p) => self.active_panel = *p,
|
||||
AppEvent::UpdateMetrics { voices, cpu } => {
|
||||
self.voice_count = *voices;
|
||||
self.cpu_load = *cpu;
|
||||
}
|
||||
AppEvent::NoteOn(note, _vel) => {
|
||||
AppEvent::NoteOn(note, _) => {
|
||||
if !self.held_notes.contains(note) {
|
||||
self.held_notes.push(*note);
|
||||
}
|
||||
@@ -100,6 +109,20 @@ impl Model for AppData {
|
||||
AppEvent::NoteOff(note) => self.held_notes.retain(|n| n != note),
|
||||
AppEvent::OctaveUp => self.octave = (self.octave + 1).min(8),
|
||||
AppEvent::OctaveDown => self.octave = (self.octave - 1).max(0),
|
||||
AppEvent::SetModDepth { src, dst, depth } => {
|
||||
let idx = src * MOD_NDST + dst;
|
||||
if idx < self.mod_depths.len() {
|
||||
self.mod_depths[idx] = depth.clamp(-1.0, 1.0);
|
||||
}
|
||||
}
|
||||
AppEvent::ToggleFx(s) => {
|
||||
if *s < self.fx_enabled.len() {
|
||||
self.fx_enabled[*s] = !self.fx_enabled[*s];
|
||||
}
|
||||
}
|
||||
AppEvent::SelectEnv(i) => self.active_env = *i,
|
||||
AppEvent::SelectLfo(i) => self.active_lfo = *i,
|
||||
AppEvent::SelectFx(i) => self.fx_selected = *i,
|
||||
});
|
||||
event.map(|we: &WindowEvent, _| {
|
||||
crate::widgets::piano::handle_kbd(cx, we, self.octave);
|
||||
@@ -112,48 +135,26 @@ pub fn build_root(cx: &mut Context) {
|
||||
crate::panels::header::build(cx);
|
||||
|
||||
HStack::new(cx, |cx| {
|
||||
VStack::new(cx, |cx| {
|
||||
for &p in Panel::ALL {
|
||||
tab_button(cx, p);
|
||||
}
|
||||
})
|
||||
.width(Pixels(56.0))
|
||||
.height(Stretch(1.0))
|
||||
.background_color(Color::rgb(14, 14, 26));
|
||||
crate::panels::macro_bar::build(cx);
|
||||
|
||||
Binding::new(cx, AppData::active_panel, |cx, panel_lens| {
|
||||
VStack::new(cx, |cx| match panel_lens.get(cx) {
|
||||
Panel::Osc => crate::panels::osc::build(cx),
|
||||
Panel::Env => crate::panels::env_panel::build(cx),
|
||||
Panel::Lfo => crate::panels::lfo::build(cx),
|
||||
Panel::Filter => crate::panels::filter::build(cx),
|
||||
Panel::Fx => crate::panels::fx::build(cx),
|
||||
Panel::ModMatrix => crate::panels::mod_matrix::build(cx),
|
||||
Binding::new(cx, AppData::active_panel, |cx, p| {
|
||||
VStack::new(cx, |cx| match p.get(cx) {
|
||||
Panel::Voice => crate::panels::voice::build(cx),
|
||||
Panel::Effects => crate::panels::fx::build(cx),
|
||||
Panel::Matrix => crate::panels::mod_matrix::build(cx),
|
||||
})
|
||||
.class("panel")
|
||||
.width(Stretch(1.0))
|
||||
.height(Stretch(1.0));
|
||||
.height(Stretch(1.0))
|
||||
.background_color(Color::rgb(12, 12, 20));
|
||||
});
|
||||
|
||||
crate::panels::macro_bar::build(cx);
|
||||
crate::panels::env_lfo_sidebar::build(cx);
|
||||
})
|
||||
.height(Stretch(1.0));
|
||||
|
||||
PianoKeyboard::new(cx);
|
||||
})
|
||||
.background_color(Color::rgb(18, 18, 28))
|
||||
.background_color(Color::rgb(10, 10, 16))
|
||||
.width(Stretch(1.0))
|
||||
.height(Stretch(1.0));
|
||||
}
|
||||
|
||||
fn tab_button(cx: &mut Context, p: Panel) {
|
||||
Binding::new(cx, AppData::active_panel, move |cx, active_lens| {
|
||||
let al = active_lens.get(cx) == p;
|
||||
Label::new(cx, p.label())
|
||||
.class("tab")
|
||||
.checked(al)
|
||||
.on_press(move |cx| cx.emit(AppEvent::SetPanel(p)))
|
||||
.width(Stretch(1.0))
|
||||
.height(Pixels(44.0))
|
||||
.text_align(TextAlign::Center);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user