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