mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
wip3 (34e): ohmy
This commit is contained in:
parent
36280ce9b7
commit
b028dc41a3
4 changed files with 92 additions and 87 deletions
|
|
@ -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 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);
|
||||
|
||||
|
|
@ -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> {
|
||||
fn min_size (&self, _: E::Size) -> Perhaps<E::Size> {
|
||||
todo!();
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ use crate::*;
|
|||
|
||||
impl<E: Engine, W: Render<E>> LayoutFixed<E> for W {}
|
||||
|
||||
pub trait LayoutFixed<E: Engine>: Render<E> + Sized {
|
||||
fn fixed_x (self, x: E::Unit) -> Fixed<E, Self> {
|
||||
Fixed::X(x, self)
|
||||
pub trait LayoutFixed<E: Engine> {
|
||||
fn fixed_x <W: Render<E>> (x: E::Unit, w: W) -> Fixed<E, W> {
|
||||
Fixed::X(x, w)
|
||||
}
|
||||
fn fixed_y (self, y: E::Unit) -> Fixed<E, Self> {
|
||||
Fixed::Y(y, self)
|
||||
fn fixed_y <W: Render<E>> (y: E::Unit, w: W) -> Fixed<E, W> {
|
||||
Fixed::Y(y, w)
|
||||
}
|
||||
fn fixed_xy (self, x: E::Unit, y: E::Unit) -> Fixed<E, Self> {
|
||||
Fixed::XY(x, y, self)
|
||||
fn fixed_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Fixed<E, W> {
|
||||
Fixed::XY(x, y, w)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
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> {
|
||||
fn map <T, I, R, F> (iterator: I, callback: F) -> Map<E, T, I, R, F>
|
||||
pub trait LayoutMapReduce<E: Engine, I: Iterator<Item = T>, T, R: Render<E>> {
|
||||
fn map <F> (iterator: I, callback: F) -> Map<E, T, I, R, F>
|
||||
where
|
||||
I: Iterator<Item=T>,
|
||||
R: Render<E>,
|
||||
F: Fn(T)->R
|
||||
{
|
||||
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
|
||||
I: Iterator<Item=T>,
|
||||
R: Render<E>,
|
||||
F: Fn(R, T)->R
|
||||
{
|
||||
Reduce(Default::default(), iterator, callback)
|
||||
|
|
|
|||
|
|
@ -103,34 +103,11 @@ pub fn arranger_content_vertical (
|
|||
let rows: &[(usize, usize)] = rows.as_ref();
|
||||
let cols: &[(usize, usize)] = cols.as_ref();
|
||||
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
|
||||
let header = Tui::reduce(tracks.iter().zip(cols.iter().map(|col|col.0)), |prev, (track, w)|{
|
||||
// track titles
|
||||
let header = Tui::reduce(
|
||||
tracks.iter().zip(cols.iter().map(|col|col.0)),
|
||||
|prev, (track, w)|{
|
||||
// name and width of track
|
||||
let name = track.name().read().unwrap();
|
||||
let max_w = w.saturating_sub(1).min(name.len()).max(2);
|
||||
|
|
@ -158,6 +135,7 @@ pub fn arranger_content_vertical (
|
|||
String::new()
|
||||
}
|
||||
}).unwrap_or(String::from("▎"));
|
||||
let timer = Tui::to_south(until_next, elapsed);
|
||||
// name of active MIDI input
|
||||
let input = format!("▎>{}", track.player.midi_ins().get(0)
|
||||
.map(|port|port.short_name())
|
||||
|
|
@ -168,55 +146,77 @@ pub fn arranger_content_vertical (
|
|||
.map(|port|port.short_name())
|
||||
.transpose()?
|
||||
.unwrap_or("(none)".into()));
|
||||
let current =
|
||||
Tui::push_x(scenes_w,
|
||||
Tui::bg(track.color().rgb,
|
||||
Tui::min_xy(w as u16, header_h,
|
||||
Tui::to_south(name, Tui::to_south(until_next, elapsed)))));
|
||||
Tui::to_east(prev, current)
|
||||
});
|
||||
//Tui::to_east(prev, Tui::push_x(scenes_w,
|
||||
//Tui::bg(track.color().rgb,
|
||||
//Tui::min_xy(w as u16, header_h,
|
||||
//Tui::to_south(name, timer)))))
|
||||
prev
|
||||
}
|
||||
);
|
||||
|
||||
// tracks and scenes
|
||||
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)),
|
||||
|(scene, pulses)| {
|
||||
let height = 1.max((pulses / PPQ) as u16);
|
||||
let playing = scene.is_playing(tracks);
|
||||
Tui::fixed_y(
|
||||
height,
|
||||
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)),
|
||||
|(scene, pulses)| {
|
||||
let height = 1.max((pulses / PPQ) as u16);
|
||||
let playing = scene.is_playing(tracks);
|
||||
Tui::fixed_y(
|
||||
height,
|
||||
Tui::to_east(
|
||||
Tui::to_east(
|
||||
Tui::to_east(
|
||||
if playing { "▶ " } else { " " },
|
||||
Tui::bold(true, scene.name.read().unwrap().as_str())
|
||||
),
|
||||
Tui::iter(
|
||||
cols.iter().map(|col|col.0).enumerate(),
|
||||
|(track, w)|Tui::fixed_xy(w as u16, height, Layers::new(move |add|{
|
||||
let mut bg = clip_bg;
|
||||
match (tracks.get(track), scene.clips.get(track)) {
|
||||
(Some(track), Some(Some(phrase))) => {
|
||||
let name = &(phrase as &Arc<RwLock<Phrase>>).read().unwrap().name;
|
||||
let name = format!("{}", name);
|
||||
let max_w = name.len().min((w as usize).saturating_sub(2));
|
||||
let color = phrase.read().unwrap().color;
|
||||
add(&name.as_str()[0..max_w].push_x(1).fixed_x(w as u16))?;
|
||||
bg = color.dark.rgb;
|
||||
if let Some((_, Some(ref playing))) = track.player.play_phrase() {
|
||||
if *playing.read().unwrap() == *phrase.read().unwrap() {
|
||||
bg = color.light.rgb
|
||||
}
|
||||
};
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
add(&Background(bg))
|
||||
}))
|
||||
)
|
||||
if playing { "▶ " } else { " " },
|
||||
Tui::bold(true, scene.name.read().unwrap().as_str())
|
||||
),
|
||||
Tui::iter(
|
||||
cols.iter().map(|col|col.0).enumerate(),
|
||||
|(track, w)|Tui::fixed_xy(w as u16, height, Layers::new(move |add|{
|
||||
let mut bg = clip_bg;
|
||||
match (tracks.get(track), scene.clips.get(track)) {
|
||||
(Some(track), Some(Some(phrase))) => {
|
||||
let name = &(phrase as &Arc<RwLock<Phrase>>).read().unwrap().name;
|
||||
let name = format!("{}", name);
|
||||
let max_w = name.len().min((w as usize).saturating_sub(2));
|
||||
let color = phrase.read().unwrap().color;
|
||||
add(&name.as_str()[0..max_w].push_x(1).fixed_x(w as u16))?;
|
||||
bg = color.dark.rgb;
|
||||
if let Some((_, Some(ref playing))) = track.player.play_phrase() {
|
||||
if *playing.read().unwrap() == *phrase.read().unwrap() {
|
||||
bg = color.light.rgb
|
||||
}
|
||||
};
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
add(&Background(bg))
|
||||
}))
|
||||
)
|
||||
)
|
||||
}
|
||||
));
|
||||
)
|
||||
}
|
||||
));
|
||||
|
||||
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
|
||||
add(&Tui::to_south(header, content))?;
|
||||
// cursor
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue