wip3 (34e): ohmy

This commit is contained in:
🪞👃🪞 2024-12-09 16:46:28 +01:00
parent 36280ce9b7
commit b028dc41a3
4 changed files with 92 additions and 87 deletions

View file

@ -46,7 +46,7 @@ pub struct ToNorth<E: Engine, A: Render<E>, B: Render<E>>(Option<E::Unit>, A, B)
pub struct ToSouth<E: Engine, A: Render<E>, B: Render<E>>(Option<E::Unit>, A, B); pub struct ToSouth<E: Engine, A: Render<E>, B: Render<E>>(Option<E::Unit>, A, B);
pub struct ToEast<E: Engine, A: Render<E>, B: Render<E>>(Option<E::Unit>, A, B); pub struct ToEast<E: Engine, A, B>(Option<E::Unit>, A, B);
pub struct ToWest<E: Engine, A: Render<E>, B: Render<E>>(Option<E::Unit>, A, B); pub struct ToWest<E: Engine, A: Render<E>, B: Render<E>>(Option<E::Unit>, A, B);
@ -68,6 +68,15 @@ impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for ToSouth<E, A, B> {
} }
} }
impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for ToWest<E, A, B> {
fn min_size (&self, _: E::Size) -> Perhaps<E::Size> {
todo!();
}
fn render (&self, _: &mut E::Output) -> Usually<()> {
Ok(())
}
}
impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for ToEast<E, A, B> { impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for ToEast<E, A, B> {
fn min_size (&self, _: E::Size) -> Perhaps<E::Size> { fn min_size (&self, _: E::Size) -> Perhaps<E::Size> {
todo!(); todo!();

View file

@ -2,15 +2,15 @@ use crate::*;
impl<E: Engine, W: Render<E>> LayoutFixed<E> for W {} impl<E: Engine, W: Render<E>> LayoutFixed<E> for W {}
pub trait LayoutFixed<E: Engine>: Render<E> + Sized { pub trait LayoutFixed<E: Engine> {
fn fixed_x (self, x: E::Unit) -> Fixed<E, Self> { fn fixed_x <W: Render<E>> (x: E::Unit, w: W) -> Fixed<E, W> {
Fixed::X(x, self) Fixed::X(x, w)
} }
fn fixed_y (self, y: E::Unit) -> Fixed<E, Self> { fn fixed_y <W: Render<E>> (y: E::Unit, w: W) -> Fixed<E, W> {
Fixed::Y(y, self) Fixed::Y(y, w)
} }
fn fixed_xy (self, x: E::Unit, y: E::Unit) -> Fixed<E, Self> { fn fixed_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Fixed<E, W> {
Fixed::XY(x, y, self) Fixed::XY(x, y, w)
} }
} }

View file

@ -1,20 +1,16 @@
use crate::*; use crate::*;
impl<E: Engine> LayoutMapReduce<E> for E {} impl<E: Engine, I: Iterator<Item=T>, T, R: Render<E>> LayoutMapReduce<E, I, T, R> for E {}
pub trait LayoutMapReduce<E: Engine> { pub trait LayoutMapReduce<E: Engine, I: Iterator<Item = T>, T, R: Render<E>> {
fn map <T, I, R, F> (iterator: I, callback: F) -> Map<E, T, I, R, F> fn map <F> (iterator: I, callback: F) -> Map<E, T, I, R, F>
where where
I: Iterator<Item=T>,
R: Render<E>,
F: Fn(T)->R F: Fn(T)->R
{ {
Map(Default::default(), iterator, callback) Map(Default::default(), iterator, callback)
} }
fn reduce <T, I, R, F> (iterator: I, callback: F) -> Reduce<E, T, I, R, F> fn reduce <F> (iterator: I, callback: F) -> Reduce<E, T, I, R, F>
where where
I: Iterator<Item=T>,
R: Render<E>,
F: Fn(R, T)->R F: Fn(R, T)->R
{ {
Reduce(Default::default(), iterator, callback) Reduce(Default::default(), iterator, callback)

View file

@ -103,34 +103,11 @@ pub fn arranger_content_vertical (
let rows: &[(usize, usize)] = rows.as_ref(); let rows: &[(usize, usize)] = rows.as_ref();
let cols: &[(usize, usize)] = cols.as_ref(); let cols: &[(usize, usize)] = cols.as_ref();
let any_size = |_|Ok(Some([0,0])); let any_size = |_|Ok(Some([0,0]));
let arrangement = Layers::new(move |add|{
// column separators
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
let style = Some(Style::default().fg(sep_fg));
Ok(for x in cols.iter().map(|col|col.1) {
let x = scenes_w + to.area().x() + x as u16;
for y in to.area().y()..to.area().y2() { to.blit(&"", x, y, style); }
})
}))?;
// row separators
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
Ok(for y in rows.iter().map(|row|row.1) {
let y = to.area().y() + (y / PPQ) as u16 + 1;
if y >= to.buffer.area.height { break }
for x in to.area().x()..to.area().x2().saturating_sub(2) {
if x < to.buffer.area.x && y < to.buffer.area.y {
let cell = to.buffer.get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = sep_fg;
}
}
})
}))?;
// track titles // track titles
let header = Tui::reduce(tracks.iter().zip(cols.iter().map(|col|col.0)), |prev, (track, w)|{ let header = Tui::reduce(
tracks.iter().zip(cols.iter().map(|col|col.0)),
|prev, (track, w)|{
// name and width of track // name and width of track
let name = track.name().read().unwrap(); let name = track.name().read().unwrap();
let max_w = w.saturating_sub(1).min(name.len()).max(2); let max_w = w.saturating_sub(1).min(name.len()).max(2);
@ -158,6 +135,7 @@ pub fn arranger_content_vertical (
String::new() String::new()
} }
}).unwrap_or(String::from("")); }).unwrap_or(String::from(""));
let timer = Tui::to_south(until_next, elapsed);
// name of active MIDI input // name of active MIDI input
let input = format!("▎>{}", track.player.midi_ins().get(0) let input = format!("▎>{}", track.player.midi_ins().get(0)
.map(|port|port.short_name()) .map(|port|port.short_name())
@ -168,15 +146,14 @@ pub fn arranger_content_vertical (
.map(|port|port.short_name()) .map(|port|port.short_name())
.transpose()? .transpose()?
.unwrap_or("(none)".into())); .unwrap_or("(none)".into()));
let current = //Tui::to_east(prev, Tui::push_x(scenes_w,
Tui::push_x(scenes_w, //Tui::bg(track.color().rgb,
Tui::bg(track.color().rgb, //Tui::min_xy(w as u16, header_h,
Tui::min_xy(w as u16, header_h, //Tui::to_south(name, timer)))))
Tui::to_south(name, Tui::to_south(until_next, elapsed))))); prev
Tui::to_east(prev, current) }
}); );
// tracks and scenes
let content = Tui::fixed_y((view.size.h() as u16).saturating_sub(header_h), Tui::reduce( let content = Tui::fixed_y((view.size.h() as u16).saturating_sub(header_h), Tui::reduce(
scenes.iter().zip(rows.iter().map(|row|row.0)), scenes.iter().zip(rows.iter().map(|row|row.0)),
|(scene, pulses)| { |(scene, pulses)| {
@ -217,6 +194,29 @@ pub fn arranger_content_vertical (
} }
)); ));
let arrangement = Layers::new(move |add|{
// column separators
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
let style = Some(Style::default().fg(sep_fg));
Ok(for x in cols.iter().map(|col|col.1) {
let x = scenes_w + to.area().x() + x as u16;
for y in to.area().y()..to.area().y2() { to.blit(&"", x, y, style); }
})
}))?;
// row separators
add(&Widget::new(any_size, move|to: &mut TuiOutput|{
Ok(for y in rows.iter().map(|row|row.1) {
let y = to.area().y() + (y / PPQ) as u16 + 1;
if y >= to.buffer.area.height { break }
for x in to.area().x()..to.area().x2().saturating_sub(2) {
if x < to.buffer.area.x && y < to.buffer.area.y {
let cell = to.buffer.get_mut(x, y);
cell.modifier = Modifier::UNDERLINED;
cell.underline_color = sep_fg;
}
}
})
}))?;
// full grid with header and footer // full grid with header and footer
add(&Tui::to_south(header, content))?; add(&Tui::to_south(header, content))?;
// cursor // cursor