mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
rewrite vertical arranger as components
This commit is contained in:
parent
5670fc179b
commit
a57bb60ac9
1 changed files with 53 additions and 74 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue