unified compact flag in groovebox

This commit is contained in:
🪞👃🪞 2025-01-02 18:40:29 +01:00
parent c9a79b1f29
commit 511ff91864
12 changed files with 129 additions and 188 deletions

View file

@ -14,6 +14,7 @@ pub struct Groovebox {
pub editor: MidiEditor,
pub sampler: Sampler,
pub compact: bool,
pub size: Measure<Tui>,
pub status: bool,
pub note_buf: Vec<u8>,
@ -47,6 +48,7 @@ impl Groovebox {
note_buf: vec![],
perf: PerfModel::default(),
status: true,
compact: true,
})
}
}
@ -64,7 +66,7 @@ audio!(|self: Groovebox, client, scope|{
if Control::Quit == SamplerAudio(&mut self.sampler).process(client, scope) {
return Control::Quit
}
// TODO move this to sampler:
// TODO move these to editor and sampler:
for RawMidi { time, bytes } in self.player.midi_ins[0].iter(scope) {
if let LiveEvent::Midi { message, .. } = LiveEvent::parse(bytes).unwrap() {
match message {
@ -73,22 +75,7 @@ audio!(|self: Groovebox, client, scope|{
},
MidiMessage::Controller { controller, value } => {
if let Some(sample) = &self.sampler.mapped[self.editor.note_point()] {
let mut sample = sample.write().unwrap();
let percentage = value.as_int() as f64 / 127.;
match controller.as_int() {
20 => {
sample.start = (percentage * sample.end as f64) as usize;
},
21 => {
let length = sample.channels[0].len();
sample.end = sample.start + (percentage * (length as f64 - sample.start as f64)) as usize;
sample.end = sample.end.min(length);
},
24 => {
sample.gain = percentage as f32 * 2.0;
},
_ => {}
}
sample.write().unwrap().handle_cc(controller, value)
}
}
_ => {}
@ -101,23 +88,23 @@ audio!(|self: Groovebox, client, scope|{
render!(Tui: (self: Groovebox) => {
let w = self.size.w();
let phrase_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 };
let pool_w = if self.pool.visible { phrase_w } else { 0 };
let sampler_w = if self.pool.visible { phrase_w } else { 4 };
let sample_h = if self.pool.visible { 8 } else { 0 };
let pool_w = if !self.compact { phrase_w } else { 5 };
let sampler_w = if !self.compact { phrase_w } else { 4 };
let sample_h = if !self.compact { 5 } else { 0 };
let note_pt = self.editor.note_point();
let color = self.player.play_phrase().as_ref()
.and_then(|(_,p)|p.as_ref().map(|p|p.read().unwrap().color))
.clone();
let sampler =
Fixed::x(sampler_w, Push::y(1, Align::w(Fill::y(SampleList::new(&self.sampler, &self.editor)))));
Fixed::x(sampler_w, Push::y(1, Align::w(Fill::y(SampleList::new(self.compact, &self.sampler, &self.editor)))));
let selectors =
Bsp::e(ClipSelected::play_phrase(&self.player), ClipSelected::next_phrase(&self.player));
let edit_clip =
MidiEditClip(&self.editor);
self.size.of(Bsp::s(
Fill::x(Fixed::y(if self.pool.visible { 3 } else { 1 }, lay!(
Fill::x(Fixed::y(2, lay!(
Align::w(Meter("L/", self.sampler.input_meter[0])),
Align::e(Meter("R/", self.sampler.input_meter[1])),
Align::x(Tui::bg(TuiTheme::g(32), TransportView::new(true, &self.player.clock))),
@ -141,7 +128,7 @@ render!(Tui: (self: Groovebox) => {
Align::x(Fixed::y(1, MidiEditStatus(&self.editor))),
),
Bsp::w(
Fixed::x(pool_w, Align::e(Fill::y(PoolView(&self.pool)))),
Fixed::x(pool_w, Align::e(Fill::y(PoolView(self.compact, &self.pool)))),
Fill::xy(Bsp::e(sampler, &self.editor)),
),
)
@ -151,6 +138,7 @@ render!(Tui: (self: Groovebox) => {
});
pub enum GrooveboxCommand {
Compact(bool),
History(isize),
Clock(ClockCommand),
Pool(PoolCommand),
@ -172,8 +160,8 @@ input_to_command!(GrooveboxCommand: <Tui>|state: Groovebox, input|match input.ev
if state.clock().is_stopped() { Play(Some(0)) } else { Pause(Some(0)) }
),
// Tab: Toggle visibility of phrase pool column
key_pat!(Tab) => Cmd::Pool(PoolCommand::Show(!state.pool.visible)),
// Tab: Toggle visibility of sidebars
key_pat!(Tab) => Cmd::Compact(!state.compact),
// q: Enqueue currently edited phrase
key_pat!(Char('q')) => Cmd::Enqueue(Some(state.pool.phrase().clone())),
@ -211,9 +199,6 @@ input_to_command!(GrooveboxCommand: <Tui>|state: Groovebox, input|match input.ev
});
command!(|self: GrooveboxCommand, state: Groovebox|match self {
Self::History(delta) => {
todo!("undo/redo")
},
Self::Enqueue(phrase) => {
state.player.enqueue_next(phrase.as_ref());
None
@ -235,7 +220,14 @@ command!(|self: GrooveboxCommand, state: Groovebox|match self {
_ => cmd.delegate(&mut state.pool, Self::Pool)?
}
},
Self::Sampler(cmd) => cmd.delegate(&mut state.sampler, Self::Sampler)?,
Self::Editor(cmd) => cmd.delegate(&mut state.editor, Self::Editor)?,
Self::Clock(cmd) => cmd.delegate(state, Self::Clock)?,
Self::Sampler(cmd) => cmd.delegate(&mut state.sampler, Self::Sampler)?,
Self::Editor(cmd) => cmd.delegate(&mut state.editor, Self::Editor)?,
Self::Clock(cmd) => cmd.delegate(state, Self::Clock)?,
Self::History(delta) => { todo!("undo/redo") },
Self::Compact(compact) => if state.compact != compact {
state.compact = compact;
Some(Self::Compact(!compact))
} else {
None
},
});