diff --git a/engine/src/output.rs b/engine/src/output.rs index 2de19448..a8911fc3 100644 --- a/engine/src/output.rs +++ b/engine/src/output.rs @@ -18,29 +18,30 @@ pub trait Output { } pub trait Content: Send + Sync { - fn content (&self) -> Option> { - None::<()> + fn content (&self) -> impl Content { + () } fn area (&self, area: E::Area) -> E::Area { - if let Some(content) = self.content() { - content.area(area) - } else { - [0.into(), 0.into(), 0.into(), 0.into()].into() - } + self.content().area(area) } fn render (&self, output: &mut E::Output) { - if let Some(content) = self.content() { - output.place(self.area(output.area()), &content) - } + self.content().render(output) } } -impl Content for () {} +impl Content for () { + fn area (&self, area: E::Area) -> E::Area { + [0.into(), 0.into(), 0.into(), 0.into()].into() + } + fn render (&self, output: &mut E::Output) {} +} impl> Content for &T {} impl> Content for Option {} +impl> Content for Vec {} + #[macro_export] macro_rules! render { (($self:ident:$Struct:ty) => $content:expr) => { impl Content for $Struct { diff --git a/layout/src/transform.rs b/layout/src/transform.rs index 7f01a639..f759fc5e 100644 --- a/layout/src/transform.rs +++ b/layout/src/transform.rs @@ -175,11 +175,10 @@ fn align, N: Coordinate, R: Area + From<[N;4]>> (ali impl> Content for Align { fn render (&self, to: &mut E::Output) { let outer_area = to.area(); - if let Some(content) = self.content() { - let inner_area = content.area(outer_area); - if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) { - to.place(aligned, &content) - } + let content = self.content(); + let inner_area = content.area(outer_area); + if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) { + to.place(aligned, &content) } } } diff --git a/src/arranger.rs b/src/arranger.rs index 8b0af52d..262d9767 100644 --- a/src/arranger.rs +++ b/src/arranger.rs @@ -102,23 +102,25 @@ impl ArrangerTui { render!(Tui: (self: ArrangerTui) => { let play = PlayPause(self.clock.is_rolling()); let transport = TransportView::new(self, Some(ItemPalette::from(TuiTheme::g(96))), true); - let with_transport = |x|col!(row!(&play, &transport), &x); let pool_size = if self.phrases.visible { self.splits[1] } else { 0 }; let with_pool = |x|Split::w(false, pool_size, PoolView(&self.phrases), x); let status = ArrangerStatus::from(self); let with_editbar = |x|Split::n(false, 1, MidiEditStatus(&self.editor), x); let with_status = |x|Split::n(false, 2, status, x); let with_size = |x|lay!(&self.size, x); - let arranger = ||lay!(|add|{ + let arranger = ||{ let color = self.color; - add(&Fill::xy(Tui::bg(color.darkest.rgb, "")))?; - add(&Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))))?; - add(&Self::render_mode(self)) - }); - with_size(with_status(with_editbar(with_pool(with_transport(col!( + lay!( + Fill::xy(Tui::bg(color.darkest.rgb, "")), + Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))), + Self::render_mode(self), + ) + }; + with_size(with_status(with_editbar(with_pool(col!( + row!(play, transport), Fill::x(Fixed::y(20, arranger())), Fill::xy(&self.editor), - )))))) + ))))) }); audio!(|self: ArrangerTui, client, scope|{ // Start profiling cycle diff --git a/src/arranger/arranger_v/v_clips.rs b/src/arranger/arranger_v/v_clips.rs index 686a4563..0aac140c 100644 --- a/src/arranger/arranger_v/v_clips.rs +++ b/src/arranger/arranger_v/v_clips.rs @@ -17,12 +17,11 @@ impl<'a> ArrangerVClips<'a> { } } } -impl<'a, E: Engine> Content for ArrangerVClips<'a> { - fn content (&self) -> Option> { +impl<'a> Content for ArrangerVClips<'a> { + fn content (&self) -> impl Content { let iter = self.scenes.iter().zip(self.rows.iter().map(|row|row.0)); - let col = Coll::map(self.scenes.iter().zip(self.rows.iter().map(|row|row.0)), |(scene, pulses), i| - Self::format_scene(self.tracks, scene, pulses)); - Some(Fill::xy(col)) + let col = Coll::map(iter, |(scene, pulses), i|Self::format_scene(self.tracks, scene, pulses)); + Fill::xy(col) } } impl<'a> ArrangerVClips<'a> { @@ -30,15 +29,19 @@ impl<'a> ArrangerVClips<'a> { fn format_scene ( tracks: &'a [ArrangerTrack], scene: &'a ArrangerScene, pulses: usize ) -> impl Content + use<'a> { - let height = 1.max((pulses / PPQ) as u16); + let height = 1.max((pulses / PPQ) as u16); let playing = scene.is_playing(tracks); - Fixed::y(height, row!( - Tui::bg(scene.color.base.rgb, - if playing { "▶ " } else { " " }), - Tui::fg_bg(scene.color.lightest.rgb, scene.color.base.rgb, - Expand::x(1, Tui::bold(true, scene.name.read().unwrap().as_str()))), - Coll::map(ArrangerTrack::with_widths(tracks), |(index, track, x1, x2), _| - Push::x(Self::format_clip(scene, index, track, (x2 - x1) as u16, height)))))} + let icon = Tui::bg( + scene.color.base.rgb, if playing { "▶ " } else { " " } + ); + let name = Tui::fg_bg(scene.color.lightest.rgb, scene.color.base.rgb, + Expand::x(1, Tui::bold(true, scene.name.read().unwrap().clone())) + ); + let clips = Coll::map(ArrangerTrack::with_widths(tracks), move|(index, track, x1, x2), _| + Push::x((x2 - x1) as u16, Self::format_clip(scene, index, track, (x2 - x1) as u16, height)) + ); + Fixed::y(height, row!(icon, name, clips)) + } fn format_clip ( scene: &'a ArrangerScene, index: usize, track: &'a ArrangerTrack, w: u16, h: u16 diff --git a/src/arranger/arranger_v/v_sep.rs b/src/arranger/arranger_v/v_sep.rs index 80173d09..7377fbfc 100644 --- a/src/arranger/arranger_v/v_sep.rs +++ b/src/arranger/arranger_v/v_sep.rs @@ -13,12 +13,12 @@ from!(|state:&ArrangerTui|ArrangerVColSep = Self { }); render!(Tui: |self: ArrangerVColSep, to| { let style = Some(Style::default().fg(self.fg)); - Ok(for x in self.cols.iter().map(|col|col.1) { + for x in self.cols.iter().map(|col|col.1) { let x = self.scenes_w + to.area().x() + x as u16; for y in to.area().y()..to.area().y2() { to.blit(&"▎", x, y, style); } - }) + } }); pub struct ArrangerVRowSep { diff --git a/src/midi/midi_editor.rs b/src/midi/midi_editor.rs index 8f4da8fa..cc56e5bc 100644 --- a/src/midi/midi_editor.rs +++ b/src/midi/midi_editor.rs @@ -119,7 +119,7 @@ render!(Tui: (self: MidiEditor) => { //render!(|self: MidiEditor|lay!(|add|{add(&self.size)?;add(self.mode)}));//bollocks -pub trait PhraseViewMode: Content + HasSize + MidiRange + MidiPoint + Debug + Send + Sync { +pub trait PhraseViewMode: HasSize + MidiRange + MidiPoint + Debug + Send + Sync { fn buffer_size (&self, phrase: &MidiClip) -> (usize, usize); fn redraw (&mut self); fn phrase (&self) -> &Option>>; @@ -131,7 +131,7 @@ pub trait PhraseViewMode: Content + HasSize + MidiRange + MidiPoint + } impl Content for Box { - fn content (&self) -> Option> { + fn content (&self) -> impl Content { Some(&(*self)) } }