diff --git a/src/arranger/arranger_v/v_head.rs b/src/arranger/arranger_v/v_head.rs index 1b773b40..5c18dbac 100644 --- a/src/arranger/arranger_v/v_head.rs +++ b/src/arranger/arranger_v/v_head.rs @@ -16,25 +16,24 @@ from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a> = Self { // A }); render!(Tui: (self: ArrangerVHead<'a>) => { - - fn row > (color: ItemPalette, field: &T) -> impl Content + use<'_, T> { + fn row > (color: ItemPalette, field: T) -> impl Content { row!(Tui::fg(color.light.rgb, "▎"), Tui::fg(color.lightest.rgb, field)) } - Some(Push::x(self.scenes_w, Coll::map(ArrangerTrack::with_widths(self.tracks), |(_, track, x1, x2), i| { let (w, h) = (ArrangerTrack::MIN_WIDTH.max(x2 - x1), HEADER_H); - let color = track.color(); + let color = track.color(); + let input = Self::format_input(track); + let output = Self::format_output(track); Tui::bg(color.base.rgb, Min::xy(w as u16, h, Fixed::xy(w as u16, 5, col!( - row(color, &Self::format_name(track, w)), - row(color, &Self::format_input(track)?), - row(color, &Self::format_output(track)?), - row(color, &Self::format_elapsed(track, self.timebase)), - row(color, &Self::format_until_next(track, self.current)), + row(color, Self::format_name(track, w)), + row(color, Self::format_input(track).ok()), + row(color, Self::format_output(track).ok()), + row(color, Self::format_elapsed(track, self.timebase)), + row(color, Self::format_until_next(track, self.current)), )))) }) )) - }); impl ArrangerVHead<'_> { diff --git a/src/piano_h.rs b/src/piano_h.rs index a66c375c..157ecd6b 100644 --- a/src/piano_h.rs +++ b/src/piano_h.rs @@ -61,7 +61,7 @@ render!(Tui: (self: PianoHorizontal) => { }; let field = move|x, y|row!( Tui::fg_bg(color.lighter.rgb, color.darker.rgb, Tui::bold(true, x)), - Tui::fg_bg(color.lighter.rgb, color.dark.rgb, &y), + Tui::fg_bg(color.lighter.rgb, color.dark.rgb, y), ); let keys_width = 5; let keys = move||PianoHorizontalKeys(self); @@ -69,7 +69,7 @@ render!(Tui: (self: PianoHorizontal) => { let notes = move||PianoHorizontalNotes(self); let cursor = move||PianoHorizontalCursor(self); let border = Fill::xy(Outer(Style::default().fg(self.color.dark.rgb).bg(self.color.darkest.rgb))); - let with_border = |x|lay!(border, Padding::xy(0, 0, &x)); + let with_border = |x|lay!(border, Padding::xy(0, 0, x)); with_border(lay!( Push::x(0, row!( //" ", diff --git a/src/pool.rs b/src/pool.rs index 40d465c3..605f7eff 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -197,6 +197,13 @@ impl PoolModel { pub(crate) fn phrases_mode_mut (&mut self) -> &mut Option { &mut self.mode } + pub fn file_picker (&self) -> Option<&FileBrowser> { + match self.mode { + Some(PoolMode::Import(_, ref file_picker)) => Some(file_picker), + Some(PoolMode::Export(_, ref file_picker)) => Some(file_picker), + _ => None + } + } } pub struct PoolView<'a>(pub(crate) &'a PoolModel); // TODO: Display phrases always in order of appearance @@ -207,48 +214,44 @@ render!(Tui: (self: PoolView<'a>) => { let upper_left = "Pool:"; let upper_right = format!("({})", phrases.len()); let color = self.0.phrase().read().unwrap().color; - Tui::bg(bg, lay!(move|add|{ - add(&Fill::xy(Outer(Style::default().fg(color.base.rgb).bg(bg))))?; - //add(&Lozenge(Style::default().bg(border_bg).fg(border_color)))?; - add(&Padding::xy(0, 1, Fill::xy(col!(move|add|match mode { - Some(PoolMode::Import(_, ref file_picker)) => add(file_picker), - Some(PoolMode::Export(_, ref file_picker)) => add(file_picker), - _ => Ok(for (i, phrase) in phrases.iter().enumerate() { - add(&lay!(|add|{ - let MidiClip { ref name, color, length, .. } = *phrase.read().unwrap(); - let mut length = PhraseLength::new(length, None); - if let Some(PoolMode::Length(phrase, new_length, focus)) = mode { - if i == *phrase { - length.pulses = *new_length; - length.focus = Some(*focus); + let border = Fill::xy(Outer(Style::default().fg(color.base.rgb).bg(bg))); + let enclose = |x|lay!(border, Padding::xy(0, 1, Tui::bg(bg, x))); + let content = Cond::either( + self.0.file_picker().is_some(), + Thunk::new(||self.0.file_picker().unwrap()), + Thunk::new(||Coll::map(phrases.iter(), |phrase, i|{ + let MidiClip { ref name, color, length, .. } = *phrase.read().unwrap(); + let mut length = PhraseLength::new(length, None); + if let Some(PoolMode::Length(phrase, new_length, focus)) = self.0.mode { + if i == phrase { + length.pulses = new_length; + length.focus = Some(focus); + } + } + let clip = Tui::bg(color.base.rgb, Fill::x(col!( + Fill::x(lay!( + Fill::x(Align::w(format!(" {i}"))), + Fill::x(Align::e(Pull::x(1, length.clone()))), + )), + Tui::bold(true, { + let mut row2 = format!(" {name}"); + if let Some(PoolMode::Rename(phrase, _)) = self.0.mode { + if i == phrase { + row2 = format!("{row2}▄"); } - } - add(&Tui::bg(color.base.rgb, Fill::x(col!( - Fill::x(lay!(|add|{ - add(&Fill::x(Align::w(format!(" {i}"))))?; - add(&Fill::x(Align::e(Pull::x(1, length.clone())))) - })), - Tui::bold(true, { - let mut row2 = format!(" {name}"); - if let Some(PoolMode::Rename(phrase, _)) = mode { - if i == *phrase { - row2 = format!("{row2}▄"); - } - }; - row2 - }), - ))))?; - if i == self.0.phrase_index() { - add(&CORNERS)?; - } - Ok(()) - }))?; - }) - }))))?; - add(&Fill::x(Align::nw(Push::x(1, Tui::fg(title_color, upper_left.to_string())))))?; - add(&Fill::x(Align::ne(Pull::x(1, Tui::fg(title_color, upper_right.to_string())))))?; - add(&self.0.size) - })) + }; + row2 + }), + ))); + Push::y(i as u16 * 2, lay!(clip, Cond::when(i == self.0.phrase_index(), CORNERS))) + }))); + enclose(lay!( + //add(&Lozenge(Style::default().bg(border_bg).fg(border_color)))?; + content, + Fill::x(Align::nw(Push::x(1, Tui::fg(title_color, upper_left.to_string())))), + Fill::x(Align::ne(Pull::x(1, Tui::fg(title_color, upper_right.to_string())))), + self.0.size.clone() + )) }); command!(|self: FileBrowserCommand, state: PoolModel|{ use PoolMode::*; diff --git a/src/sampler/sampler_tui.rs b/src/sampler/sampler_tui.rs index ec5fe9b6..07e49f28 100644 --- a/src/sampler/sampler_tui.rs +++ b/src/sampler/sampler_tui.rs @@ -50,8 +50,8 @@ render!(Tui: (self: SamplerTui) => { let fg = self.color.base.rgb; let bg = self.color.darkest.rgb; let border = Fill::xy(Outer(Style::default().fg(fg).bg(bg))); - let with_border = |x|lay!(border, Fill::xy(&x)); - let with_size = |x|lay!(self.size, x); + let with_border = |x|lay!(border, Fill::xy(x)); + let with_size = |x|lay!(self.size.clone(), x); Tui::bg(bg, Fill::xy(with_border(Bsp::s( Tui::fg(self.color.light.rgb, Tui::bold(true, &"Sampler")), with_size(Shrink::y(1, Bsp::e( diff --git a/src/sequencer.rs b/src/sequencer.rs index e912b0fd..f6365fc1 100644 --- a/src/sequencer.rs +++ b/src/sequencer.rs @@ -49,7 +49,7 @@ render!(Tui: (self: SequencerTui) => { let status = SequencerStatus::from(self); let with_status = |x|Split::n(false, if self.status { 2 } else { 0 }, status, x); let with_editbar = |x|Split::n(false, 1, MidiEditStatus(&self.editor), x); - let with_size = |x|lay!(self.size, x); + let with_size = |x|lay!(self.size.clone(), x); let editor = with_editbar(with_pool(Fill::xy(&self.editor))); let color = self.player.play_phrase().as_ref().map(|(_,p)| diff --git a/src/status.rs b/src/status.rs index 7a461789..c8b995d5 100644 --- a/src/status.rs +++ b/src/status.rs @@ -10,7 +10,7 @@ render!(Tui: (self:MidiEditStatus<'a>) => { let field = move|x, y|row!( Tui::fg_bg(color.lighter.rgb, color.darker.rgb, Tui::bold(true, x)), Tui::fg_bg(color.light.rgb, color.darker.rgb, Tui::bold(true, "│")), - Tui::fg_bg(color.lightest.rgb, color.dark.rgb, &y), + Tui::fg_bg(color.lightest.rgb, color.dark.rgb, y), ); let bg = color.darkest.rgb; let fg = color.lightest.rgb; diff --git a/src/transport.rs b/src/transport.rs index 10f1abec..387e3476 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -97,22 +97,22 @@ render!(Tui: (self: TransportView) => { ); Fixed::y(3, Tui::bg(color.base.rgb, Fill::x(row!( Thunk::new(move||col!( - transport_field(" Beat", self.beat.as_str()), - transport_field(" Time", format!("{:.1}s", self.current_second).as_str()), - transport_field(" BPM", self.bpm.as_str()), + transport_field(" Beat", self.beat.clone()), + transport_field(" Time", format!("{:.1}s", self.current_second)), + transport_field(" BPM", self.bpm.clone()), )), Thunk::new(move||col!( - transport_field(" Rate", format!("{}", self.sr).as_str()), - transport_field(" Chunk", format!("{}", self.chunk).as_str()), - transport_field(" Lag", format!("{:.3}ms", self.latency).as_str()), + transport_field(" Rate", format!("{}", self.sr)), + transport_field(" Chunk", format!("{}", self.chunk)), + transport_field(" Lag", format!("{:.3}ms", self.latency)), )), col!( //Field(" CPU%", format!("{:.1}ms", self.perf).as_str(), &color), ), )))) }); -struct TransportField<'a>(&'a str, &'a str, ItemPalette); -render!(Tui: (self: TransportField<'a>) => row!( +struct TransportField(&'static str, String, ItemPalette); +render!(Tui: (self: TransportField) => row!( Tui::fg_bg(self.2.lightest.rgb, self.2.base.rgb, Tui::bold(true, self.0)), Tui::fg_bg(self.2.base.rgb, self.2.darkest.rgb, "▌"), Tui::fg_bg(self.2.lightest.rgb, self.2.darkest.rgb, format!("{:>10}", self.1)),