rewrite vertical arranger as components

This commit is contained in:
🪞👃🪞 2024-09-12 19:41:47 +03:00
parent 5670fc179b
commit a57bb60ac9

View file

@ -498,103 +498,77 @@ impl<'a> Widget for CursorFocus<'a> {
struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer<Tui>]); struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer<Tui>]);
impl<'a> Widget for TracksHeader<'a> { impl<'a> Content for TracksHeader<'a> {
type Engine = Tui; type Engine = Tui;
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn content (&self) -> impl Widget<Engine = Tui> {
let area = to.area(); let Self(_offset, columns, tracks) = *self;
let Self(offset, track_cols, tracks) = *self; Split::right(move |add|{
let [x, y, width, _] = area; for (track, (w, _)) in tracks.iter().zip(columns) {
for (track, (w, x)) in tracks.iter().zip(track_cols) { add(&Min::W(*w as u16, Layers::new(|add|{
let x = *x as u16; add(&FillBg(COLOR_BG1))?;
if x > width { add(&track.name.read().unwrap().as_str())
break })))?;
} }
let name = track.name.read().unwrap(); Ok(())
to.fill_bg([offset + x, y, *w as u16, 2], COLOR_BG1); })
to.blit(&*name, offset + x + 1, y, Some(Style::default().white()))?;
}
Ok(Some([x, y, width, 2]))
} }
} }
struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer<Tui>], &'a[Scene]); struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer<Tui>], &'a[Scene]);
impl<'a> Widget for SceneRows<'a> { impl<'a> Content for SceneRows<'a> {
type Engine = Tui; type Engine = Tui;
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn content (&self) -> impl Widget<Engine = Tui> {
let area = to.area(); let Self(offset, columns, rows, tracks, scenes) = *self;
let Self(offset, track_cols, scene_rows, tracks, scenes) = *self; Split::down(move |add| {
let black = Some(Style::default().fg(Nord::SEPARATOR)); for (scene, (_pulses, _)) in scenes.iter().zip(rows) {
let [_, mut y, _, _height] = area; add(&SceneRow(tracks, scene, columns, offset))?;
for (_, x) in track_cols.iter() {
let x = *x as u16;
if x > 0 {
for y in area.y()-2..y-2 {
to.blit(&"", x - 1, y, black)?;
}
} }
} Ok(())
for (scene, (pulses, _)) in scenes.iter().zip(scene_rows) { })
//if y > height {
//break
//}
let h = 1.max((pulses / 96) as u16);
SceneRow(tracks, scene, track_cols, offset)
.render(to.with_area(area.x(), y, area.w(), h))?;
y = y + h
}
Ok(Some(area))
} }
} }
struct SceneRow<'a>(&'a[Sequencer<Tui>], &'a Scene, &'a[(usize, usize)], u16); struct SceneRow<'a>(&'a[Sequencer<Tui>], &'a Scene, &'a[(usize, usize)], u16);
impl<'a> Widget for SceneRow<'a> { impl<'a> Content for SceneRow<'a> {
type Engine = Tui; type Engine = Tui;
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn content (&self) -> impl Widget<Engine = Tui> {
let area = to.area(); let Self(tracks, scene, columns, _offset) = self;
let Self(tracks, scene, track_cols, offset) = self;
let [x, y, width, _] = area;
let playing = scene.is_playing(tracks); let playing = scene.is_playing(tracks);
to.blit(&if playing { "" } else { " " }, x, y, None)?; Split::right(move |add| {
to.blit(&*scene.name.read().unwrap(), x + 1, y, Some(Style::default().white()))?; add(&Layers::new(|add|{
to.fill_bg([x, y, offset.saturating_sub(1), area.h()], COLOR_BG1); add(&if playing { "" } else { " " })?;
for (track, (w, x)) in track_cols.iter().enumerate() { add(&scene.name.read().unwrap().as_str())?;
let x = *x as u16 + offset; add(&FillBg(COLOR_BG1))
if x > width { }))?;
break for (track, (_w, _x)) in columns.iter().enumerate() {
add(&SceneClip(tracks.get(track), scene.clips.get(track)))?;
} }
if let (Some(track), Some(Some(clip))) = ( Ok(())
tracks.get(track), scene.clips.get(track) })
) {
SceneClip(track, *clip).render(to.with_area(x, y, *w as u16, area.h()))?;
}
}
Ok(Some(area))
} }
} }
struct SceneClip<'a>(&'a Sequencer<Tui>, usize); struct SceneClip<'a>(Option<&'a Sequencer<Tui>>, Option<&'a Option<usize>>);
impl<'a> Widget for SceneClip<'a> { impl<'a> Content for SceneClip<'a> {
type Engine = Tui; type Engine = Tui;
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { fn content (&self) -> impl Widget<Engine = Tui> {
let area = to.area();
let Self(track, clip) = self; let Self(track, clip) = self;
let style = Some(Style::default().white()); Layers::new(move |add|{
if let Some(phrase) = track.phrases.get(*clip) { let mut color = COLOR_BG0;
let phrase = phrase.read().unwrap(); if let (Some(track), Some(Some(clip))) = (track, clip) {
let name = phrase.name.read().unwrap(); if let Some(phrase) = track.phrases.get(*clip) {
to.blit(&format!("{clip:02} {name}"), area.x() + 1, area.y(), style)?; add(&format!(
to.fill_bg(area, if track.sequence == Some(*clip) { "{clip:02} {}",
Nord::PLAYING phrase.read().unwrap().name.read().unwrap()
} else { ).as_str())?;
COLOR_BG1 color = if track.sequence == Some(*clip) { Nord::PLAYING } else { COLOR_BG1 };
}); }
} else { }
to.fill_bg(area, COLOR_BG0) add(&FillBg(color))
} })
Ok(Some(area))
} }
} }
@ -867,6 +841,7 @@ impl<'a> Widget for TrackScenesColumn<'a> {
Ok(Some([x, y, x2, height])) Ok(Some([x, y, x2, height]))
} }
} }
/// Appears on first run (i.e. if state dir is missing). /// Appears on first run (i.e. if state dir is missing).
pub struct ArrangerRenameModal<E: Engine> { pub struct ArrangerRenameModal<E: Engine> {
_engine: std::marker::PhantomData<E>, _engine: std::marker::PhantomData<E>,
@ -876,6 +851,7 @@ pub struct ArrangerRenameModal<E: Engine> {
result: Arc<RwLock<String>>, result: Arc<RwLock<String>>,
cursor: usize cursor: usize
} }
impl<E: Engine> ArrangerRenameModal<E> { impl<E: Engine> ArrangerRenameModal<E> {
pub fn new (target: ArrangerFocus, value: &Arc<RwLock<String>>) -> Self { pub fn new (target: ArrangerFocus, value: &Arc<RwLock<String>>) -> Self {
Self { Self {
@ -888,6 +864,7 @@ impl<E: Engine> ArrangerRenameModal<E> {
} }
} }
} }
impl Widget for ArrangerRenameModal<Tui> { impl Widget for ArrangerRenameModal<Tui> {
type Engine = Tui; type Engine = Tui;
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
@ -914,6 +891,7 @@ impl Widget for ArrangerRenameModal<Tui> {
Ok(Some(area)) Ok(Some(area))
} }
} }
impl Handle<Tui> for ArrangerRenameModal<Tui> { impl Handle<Tui> for ArrangerRenameModal<Tui> {
fn handle (&mut self, from: &Tui) -> Perhaps<bool> { fn handle (&mut self, from: &Tui) -> Perhaps<bool> {
match from.event() { match from.event() {
@ -952,6 +930,7 @@ impl Handle<Tui> for ArrangerRenameModal<Tui> {
} }
} }
} }
impl<E: Engine + Send> Exit for ArrangerRenameModal<E> { impl<E: Engine + Send> Exit for ArrangerRenameModal<E> {
fn exited (&self) -> bool { fn exited (&self) -> bool {
self.done self.done