From 6f91eb085d5b3712c0b64131428fe333b4ca467a Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 3 Oct 2024 20:23:35 +0300 Subject: [PATCH] remove single-use horizontal arranger widgets --- crates/tek_sequencer/src/sequencer.rs | 21 - crates/tek_sequencer/src/sequencer_tui.rs | 481 ++++++++++------------ 2 files changed, 226 insertions(+), 276 deletions(-) diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index 9c87d68c..5e44d06f 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -346,27 +346,6 @@ pub struct VerticalArrangerCursor<'a>( pub struct HorizontalArranger<'a, E: Engine>( pub &'a Arranger ); -pub struct TrackNameColumn<'a, E: Engine>( - pub &'a [Sequencer], pub ArrangerFocus -); -pub struct TrackMonitorColumn<'a, E: Engine>( - pub &'a [Sequencer] -); -pub struct TrackRecordColumn<'a, E: Engine>( - pub &'a [Sequencer] -); -pub struct TrackOverdubColumn<'a, E: Engine>( - pub &'a [Sequencer] -); -pub struct TrackEraseColumn<'a, E: Engine>( - pub &'a [Sequencer] -); -pub struct TrackGainColumn<'a, E: Engine>( - pub &'a [Sequencer] -); -pub struct TrackScenesColumn<'a, E: Engine>( - pub &'a [Sequencer], pub &'a [Scene], pub ArrangerFocus -); /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/crates/tek_sequencer/src/sequencer_tui.rs b/crates/tek_sequencer/src/sequencer_tui.rs index c2e51f8b..293fefd0 100644 --- a/crates/tek_sequencer/src/sequencer_tui.rs +++ b/crates/tek_sequencer/src/sequencer_tui.rs @@ -354,50 +354,214 @@ impl<'a> Content for HorizontalArranger<'a, Tui> { type Engine = Tui; fn content (&self) -> impl Widget { let Arranger { tracks, focused, selected, scenes, .. } = self.0; - let tracks = tracks.as_slice(); - Layers::new(|add|{ - add(&focused.then_some(Background(Color::Rgb(40, 50, 30))))?; - add(&Stack::right(|add|{ - add(&TrackNameColumn(tracks, *selected))?; - add(&TrackMonitorColumn(tracks))?; - add(&TrackRecordColumn(tracks))?; - add(&TrackOverdubColumn(tracks))?; - add(&TrackEraseColumn(tracks))?; - add(&TrackGainColumn(tracks))?; - add(&TrackScenesColumn(tracks, scenes.as_slice(), *selected))?; - Ok(()) - })) - }) - } -} - -impl<'a> Widget for TrackNameColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, _to: &mut TuiOutput) -> Usually<()> { - todo!(); - //let Self(tracks, selected) = self; - //let yellow = Some(Style::default().yellow().bold().not_dim()); - //let white = Some(Style::default().white().bold().not_dim()); - //let area = to.area(); - //let area = [area.x(), area.y(), 3 + 5.max(track_name_max_len(tracks)) as u16, area.h()]; - //let offset = 0; // track scroll offset - //for y in 0..area.h() { - //if y == 0 { - //to.blit(&"Mixer", area.x() + 1, area.y() + y, Some(DIM))?; - //} else if y % 2 == 0 { - //let index = (y as usize - 2) / 2 + offset; - //if let Some(track) = tracks.get(index) { - //let selected = selected.track() == Some(index); - //let style = if selected { yellow } else { white }; - //to.blit(&format!(" {index:>02} "), area.x(), area.y() + y, style)?; - //to.blit(&*track.name.read().unwrap(), area.x() + 4, area.y() + y, style)?; - //} - //} - //} - //Ok(Some(area)) + let _tracks = tracks.as_slice(); + lay!( + focused.then_some(Background(Color::Rgb(40, 50, 30))), + row!( + // name + CustomWidget::new(|_|{ + todo!() + }, |_: &mut TuiOutput|{ + todo!() + //let Self(tracks, selected) = self; + //let yellow = Some(Style::default().yellow().bold().not_dim()); + //let white = Some(Style::default().white().bold().not_dim()); + //let area = to.area(); + //let area = [area.x(), area.y(), 3 + 5.max(track_name_max_len(tracks)) as u16, area.h()]; + //let offset = 0; // track scroll offset + //for y in 0..area.h() { + //if y == 0 { + //to.blit(&"Mixer", area.x() + 1, area.y() + y, Some(DIM))?; + //} else if y % 2 == 0 { + //let index = (y as usize - 2) / 2 + offset; + //if let Some(track) = tracks.get(index) { + //let selected = selected.track() == Some(index); + //let style = if selected { yellow } else { white }; + //to.blit(&format!(" {index:>02} "), area.x(), area.y() + y, style)?; + //to.blit(&*track.name.read().unwrap(), area.x() + 4, area.y() + y, style)?; + //} + //} + //} + //Ok(Some(area)) + }), + // monitor + CustomWidget::new(|_|{ + todo!() + }, |_: &mut TuiOutput|{ + todo!() + //let Self(tracks) = self; + //let mut area = to.area(); + //let on = Some(Style::default().not_dim().green().bold()); + //let off = Some(DIM); + //area.x += 1; + //for y in 0..area.h() { + //if y == 0 { + ////" MON ".blit(to.buffer, area.x, area.y + y, style2)?; + //} else if y % 2 == 0 { + //let index = (y as usize - 2) / 2; + //if let Some(track) = tracks.get(index) { + //let style = if track.monitoring { on } else { off }; + //to.blit(&" MON ", area.x(), area.y() + y, style)?; + //} else { + //area.height = y; + //break + //} + //} + //} + //area.width = 4; + //Ok(Some(area)) + }), + // record + CustomWidget::new(|_|{ + todo!() + }, |_: &mut TuiOutput|{ + todo!() + //let Self(tracks) = self; + //let mut area = to.area(); + //let on = Some(Style::default().not_dim().red().bold()); + //let off = Some(Style::default().dim()); + //area.x += 1; + //for y in 0..area.h() { + //if y == 0 { + ////" REC ".blit(to.buffer, area.x, area.y + y, style2)?; + //} else if y % 2 == 0 { + //let index = (y as usize - 2) / 2; + //if let Some(track) = tracks.get(index) { + //let style = if track.recording { on } else { off }; + //to.blit(&" REC ", area.x(), area.y() + y, style)?; + //} else { + //area.height = y; + //break + //} + //} + //} + //area.width = 4; + //Ok(Some(area)) + }), + // overdub + CustomWidget::new(|_|{ + todo!() + }, |_: &mut TuiOutput|{ + todo!() + //let Self(tracks) = self; + //let mut area = to.area(); + //let on = Some(Style::default().not_dim().yellow().bold()); + //let off = Some(Style::default().dim()); + //area.x = area.x + 1; + //for y in 0..area.h() { + //if y == 0 { + ////" OVR ".blit(to.buffer, area.x, area.y + y, style2)?; + //} else if y % 2 == 0 { + //let index = (y as usize - 2) / 2; + //if let Some(track) = tracks.get(index) { + //to.blit(&" OVR ", area.x(), area.y() + y, if track.overdub { + //on + //} else { + //off + //})?; + //} else { + //area.height = y; + //break + //} + //} + //} + //area.width = 4; + //Ok(Some(area)) + }), + // erase + CustomWidget::new(|_|{ + todo!() + }, |_: &mut TuiOutput|{ + todo!() + }), + // gain + CustomWidget::new(|_|{ + todo!() + //let Self(tracks) = self; + //let mut area = to.area(); + //let off = Some(Style::default().dim()); + //area.x = area.x + 1; + //for y in 0..area.h() { + //if y == 0 { + ////" DEL ".blit(to.buffer, area.x, area.y + y, style2)?; + //} else if y % 2 == 0 { + //let index = (y as usize - 2) / 2; + //if let Some(_) = tracks.get(index) { + //to.blit(&" DEL ", area.x(), area.y() + y, off)?; + //} else { + //area.height = y; + //break + //} + //} + //} + //area.width = 4; + //Ok(Some(area)) + }, |_: &mut TuiOutput|{ + todo!() + //let Self(tracks) = self; + //let mut area = to.area(); + //let off = Some(Style::default().dim()); + //area.x = area.x() + 1; + //for y in 0..area.h() { + //if y == 0 { + ////" GAIN ".blit(to.buffer, area.x, area.y + y, style2)?; + //} else if y % 2 == 0 { + //let index = (y as usize - 2) / 2; + //if let Some(_) = tracks.get(index) { + //to.blit(&" +0.0 ", area.x(), area.y() + y, off)?; + //} else { + //area.height = y; + //break + //} + //} + //} + //area.width = 7; + //Ok(Some(area)) + }), + // scenes + CustomWidget::new(|_|{ + todo!() + }, |to: &mut TuiOutput|{ + let Arranger { tracks, scenes, selected, .. } = self.0; + let area = to.area(); + let mut x2 = 0; + let [x, y, _, height] = area; + for (scene_index, scene) in scenes.iter().enumerate() { + let active_scene = selected.scene() == Some(scene_index); + let sep = Some(if active_scene { + Style::default().yellow().not_dim() + } else { + Style::default().dim() + }); + for y in y+1..y+height { + to.blit(&"│", x + x2, y, sep); + } + let name = scene.name.read().unwrap(); + let mut x3 = name.len() as u16; + to.blit(&*name, x + x2, y, sep); + for (i, clip) in scene.clips.iter().enumerate() { + let active_track = selected.track() == Some(i); + if let Some(clip) = clip { + let y2 = y + 2 + i as u16 * 2; + let label = match tracks[i].phrases.get(*clip) { + Some(phrase) => &format!("{}", phrase.read().unwrap().name.read().unwrap()), + None => "...." + }; + to.blit(&label, x + x2, y2, Some(if active_track && active_scene { + Style::default().not_dim().yellow().bold() + } else { + Style::default().not_dim() + })); + x3 = x3.max(label.len() as u16) + } + } + x2 = x2 + x3 + 1; + } + //Ok(Some([x, y, x2, height])) + Ok(()) + }), + ) + ) } } @@ -407,206 +571,6 @@ pub fn track_name_max_len (tracks: &[Sequencer]) -> usize { .fold(0, usize::max) } -impl<'a> Widget for TrackMonitorColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, _to: &mut TuiOutput) -> Usually<()> { - todo!(); - //let Self(tracks) = self; - //let mut area = to.area(); - //let on = Some(Style::default().not_dim().green().bold()); - //let off = Some(DIM); - //area.x += 1; - //for y in 0..area.h() { - //if y == 0 { - ////" MON ".blit(to.buffer, area.x, area.y + y, style2)?; - //} else if y % 2 == 0 { - //let index = (y as usize - 2) / 2; - //if let Some(track) = tracks.get(index) { - //let style = if track.monitoring { on } else { off }; - //to.blit(&" MON ", area.x(), area.y() + y, style)?; - //} else { - //area.height = y; - //break - //} - //} - //} - //area.width = 4; - //Ok(Some(area)) - } -} - -impl<'a> Widget for TrackRecordColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, _to: &mut TuiOutput) -> Usually<()> { - todo!(); - //let Self(tracks) = self; - //let mut area = to.area(); - //let on = Some(Style::default().not_dim().red().bold()); - //let off = Some(Style::default().dim()); - //area.x += 1; - //for y in 0..area.h() { - //if y == 0 { - ////" REC ".blit(to.buffer, area.x, area.y + y, style2)?; - //} else if y % 2 == 0 { - //let index = (y as usize - 2) / 2; - //if let Some(track) = tracks.get(index) { - //let style = if track.recording { on } else { off }; - //to.blit(&" REC ", area.x(), area.y() + y, style)?; - //} else { - //area.height = y; - //break - //} - //} - //} - //area.width = 4; - //Ok(Some(area)) - } -} - -impl<'a> Widget for TrackOverdubColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, _to: &mut TuiOutput) -> Usually<()> { - todo!(); - //let Self(tracks) = self; - //let mut area = to.area(); - //let on = Some(Style::default().not_dim().yellow().bold()); - //let off = Some(Style::default().dim()); - //area.x = area.x + 1; - //for y in 0..area.h() { - //if y == 0 { - ////" OVR ".blit(to.buffer, area.x, area.y + y, style2)?; - //} else if y % 2 == 0 { - //let index = (y as usize - 2) / 2; - //if let Some(track) = tracks.get(index) { - //to.blit(&" OVR ", area.x(), area.y() + y, if track.overdub { - //on - //} else { - //off - //})?; - //} else { - //area.height = y; - //break - //} - //} - //} - //area.width = 4; - //Ok(Some(area)) - } -} - -impl<'a> Widget for TrackEraseColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, _to: &mut TuiOutput) -> Usually<()> { - todo!(); - //let Self(tracks) = self; - //let mut area = to.area(); - //let off = Some(Style::default().dim()); - //area.x = area.x + 1; - //for y in 0..area.h() { - //if y == 0 { - ////" DEL ".blit(to.buffer, area.x, area.y + y, style2)?; - //} else if y % 2 == 0 { - //let index = (y as usize - 2) / 2; - //if let Some(_) = tracks.get(index) { - //to.blit(&" DEL ", area.x(), area.y() + y, off)?; - //} else { - //area.height = y; - //break - //} - //} - //} - //area.width = 4; - //Ok(Some(area)) - } -} - -impl<'a> Widget for TrackGainColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, _to: &mut TuiOutput) -> Usually<()> { - todo!(); - //let Self(tracks) = self; - //let mut area = to.area(); - //let off = Some(Style::default().dim()); - //area.x = area.x() + 1; - //for y in 0..area.h() { - //if y == 0 { - ////" GAIN ".blit(to.buffer, area.x, area.y + y, style2)?; - //} else if y % 2 == 0 { - //let index = (y as usize - 2) / 2; - //if let Some(_) = tracks.get(index) { - //to.blit(&" +0.0 ", area.x(), area.y() + y, off)?; - //} else { - //area.height = y; - //break - //} - //} - //} - //area.width = 7; - //Ok(Some(area)) - } -} - -impl<'a> Widget for TrackScenesColumn<'a, Tui> { - type Engine = Tui; - fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { - todo!() - } - fn render (&self, to: &mut TuiOutput) -> Usually<()> { - let Self(tracks, scenes, selected) = self; - let area = to.area(); - let mut x2 = 0; - let [x, y, _, height] = area; - for (scene_index, scene) in scenes.iter().enumerate() { - let active_scene = selected.scene() == Some(scene_index); - let sep = Some(if active_scene { - Style::default().yellow().not_dim() - } else { - Style::default().dim() - }); - for y in y+1..y+height { - to.blit(&"│", x + x2, y, sep); - } - let name = scene.name.read().unwrap(); - let mut x3 = name.len() as u16; - to.blit(&*name, x + x2, y, sep); - for (i, clip) in scene.clips.iter().enumerate() { - let active_track = selected.track() == Some(i); - if let Some(clip) = clip { - let y2 = y + 2 + i as u16 * 2; - let label = match tracks[i].phrases.get(*clip) { - Some(phrase) => &format!("{}", phrase.read().unwrap().name.read().unwrap()), - None => "...." - }; - to.blit(&label, x + x2, y2, Some(if active_track && active_scene { - Style::default().not_dim().yellow().bold() - } else { - Style::default().not_dim() - })); - x3 = x3.max(label.len() as u16) - } - } - x2 = x2 + x3 + 1; - } - //Ok(Some([x, y, x2, height])) - Ok(()) - } -} - /////////////////////////////////////////////////////////////////////////////////////////////////// impl Content for ArrangerRenameModal { @@ -633,7 +597,7 @@ impl Content for ArrangerRenameModal { //to.blit(&"▂", area.x() + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style); //Ok(Some(area)) //Ok(()) - } + } } impl Handle for ArrangerRenameModal { @@ -800,16 +764,23 @@ impl Sequencer { impl Content for Sequencer { type Engine = Tui; fn content (&self) -> impl Widget { - let toolbar = col!( - col! { "Name", self.name.read().unwrap().as_str(), }, - "", - col! { "Start: ", " 1.1.1", "End: ", " 2.1.1", }, - "", - col! { "Loop [ ]", "From: ", " 1.1.1", "Length: ", " 1.0.0", }, - "", - col! { "Notes: ", "C#0-C#9 ", "[ /2 ]", "[ x2 ]" - , "[ Rev ]", "[ Inv ]", "[ Dup ]" }, - ).min_x(10); + let toolbar = Stack::down(move|add|{ + add(&col! {"Name", self.name.read().unwrap().as_str(),})?; + if let Some(phrase) = self.phrase.as_ref() { + panic!(); + let phrase = phrase.read().unwrap(); + let length = phrase.length; + let looped = phrase.looped; + add(&"")?; + add(&col! {"Length: ", format!("{length}").as_str(),})?; + add(&"")?; + add(&col! { "Loop [ ]", "From: ", " 1.1.1", "Length: ", " 1.0.0", })?; + add(&"")?; + add(&col! { "Notes: ", "C#0-C#9 ", "[ /2 ]", "[ x2 ]" + , "[ Rev ]", "[ Inv ]", "[ Dup ]" })?; + } + Ok(()) + }).min_x(10); let content = lay!( // keys CustomWidget::new(|_|Ok(Some([32,4])), |to: &mut TuiOutput|{