mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
demacroify per_track_top
This commit is contained in:
parent
1fb5dfbe11
commit
7a97b07c0a
1 changed files with 70 additions and 79 deletions
149
tek/src/view.rs
149
tek/src/view.rs
|
|
@ -194,19 +194,35 @@ macro_rules! per_track {
|
|||
let content = Fixed::y(1, $content);
|
||||
let styled = Tui::fg_bg($track.color.lightest.rgb, $track.color.base.rgb, content);
|
||||
map_east(x1 as u16, width, Align::y(Fixed::x(width, styled))) }))).into() }} }
|
||||
macro_rules! per_track_top {
|
||||
($area:expr;|$self:ident,$track:ident,$index:ident|$content:expr) => {{
|
||||
let tracks = ||$self.tracks_sizes($self.is_editing(), $self.editor_w())
|
||||
.map_while(|(t, track, x1, x2)|if x2 >= $area {
|
||||
None } else { Some((t, track, x1, x2)) });
|
||||
(move||Fill::xy(Align::nw(Map::new(tracks, move|(_, $track, x1, x2), $index| {
|
||||
let width = (x2 - x1) as u16;
|
||||
let content = Fixed::y(1, $content);
|
||||
let styled = Tui::fg_bg($track.color.lightest.rgb, $track.color.base.rgb, content);
|
||||
map_east(x1 as u16, width, Fixed::x(width, Align::n(styled))) }))).boxed()).into() }} }
|
||||
impl Tek {
|
||||
|
||||
fn view_row_top <'a> (
|
||||
// SIZES //////////////////////////////////////////////////////////////////////////////////////
|
||||
fn w (&self) -> u16 {
|
||||
self.tracks_sizes(self.is_editing(), self.editor_w())
|
||||
.last().map(|x|x.3 as u16) .unwrap_or(0)
|
||||
}
|
||||
fn w_sidebar (&self) -> u16 {
|
||||
let w = (self.size.w() / 10);
|
||||
let w = w.min(if w > 80 { 20 } else if w > 70 { 18 } else if w > 60 { 16 }
|
||||
else if w > 50 { 14 } else if w > 40 { 12 } else { 10 });
|
||||
//let w = if self.is_editing() { w / 2 } else { w };
|
||||
w as u16
|
||||
}
|
||||
fn w_tracks (&self, editing: bool, bigger: usize) -> u16 {
|
||||
self.tracks_sizes(editing, bigger).last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
|
||||
}
|
||||
fn h_inputs (&self) -> u16 {
|
||||
1 + self.inputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
fn h_outputs (&self) -> u16 {
|
||||
1 + self.outputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
fn h_scenes (&self, editing: bool, height: usize, larger: usize) -> u16 {
|
||||
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
|
||||
/// COMPONENTS ////////////////////////////////////////////////////////////////////////////////
|
||||
fn row_top <'a> (
|
||||
&'a self, w: u16, h: u16, a: impl Content<TuiOut> + 'a, b: impl Content<TuiOut> + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fixed::y(h, Bsp::a(
|
||||
|
|
@ -214,17 +230,21 @@ impl Tek {
|
|||
Fill::xy(Align::n(Fixed::xy(w, h, b)))
|
||||
))
|
||||
}
|
||||
fn per_track_top <'a, T: Content<TuiOut> + 'a> (
|
||||
&'a self, f: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
let width = self.size.w();
|
||||
let filter = move|(t, track, x1, x2)|if x2 >= width {None} else {Some((t, track, x1, x2))};
|
||||
let tracks = move||self.tracks_sizes(self.is_editing(), self.editor_w()).map_while(filter);
|
||||
Fill::xy(Align::nw(Map::new(tracks, move|(index, track, x1, x2), _|{
|
||||
let width = (x2 - x1) as u16;
|
||||
let content = Fixed::y(1, f(index, track));
|
||||
let styled = Tui::fg_bg(track.color.lightest.rgb, track.color.base.rgb, content);
|
||||
map_east(x1 as u16, width, Fixed::x(width, Align::n(styled))) })))
|
||||
}
|
||||
fn wrap (bg: Color, fg: Color, content: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
||||
Bsp::e(Tui::fg_bg(bg, Reset, "▐"), Bsp::w(Tui::fg_bg(bg, Reset, "▌"), Tui::fg_bg(fg, bg, content)))
|
||||
}
|
||||
fn view_header <'a> (
|
||||
&'a self, key: &'a str, label: &str, count: usize, content: impl Content<TuiOut> + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fill::xy(Align::nw(Bsp::s(
|
||||
self.button(key, format!("{:10} ({})", label, count)),
|
||||
content,
|
||||
)))
|
||||
}
|
||||
fn view_io_header <'a, T: PortsSizes<'a>> (
|
||||
&'a self,
|
||||
key: &'a str,
|
||||
|
|
@ -236,24 +256,30 @@ impl Tek {
|
|||
) -> impl Content<TuiOut> + 'a {
|
||||
self.view_header(key, label, count, Map::new(iter,
|
||||
move|(index, name, connections, y, y2), _|map_south(y as u16, (y2-y) as u16, Bsp::s(
|
||||
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(name)))),
|
||||
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(Bsp::e(" ", name))))),
|
||||
Map::new(||connections.iter(), move|connect, index|map_south(index as u16, 1,
|
||||
Fill::x(Align::w(Tui::bold(false, Tui::fg_bg(fg, bg, connect.info()))))))))))
|
||||
}
|
||||
fn button <'a> (
|
||||
&'a self, key: impl Content<TuiOut> + 'a, label: impl Content<TuiOut> + 'a
|
||||
fn view_header <'a> (
|
||||
&'a self, key: &'a str, label: &str, count: usize, content: impl Content<TuiOut> + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fill::xy(Align::nw(Bsp::s(
|
||||
self.button(key, format!("{:10} ({})", label, count)),
|
||||
content,
|
||||
)))
|
||||
}
|
||||
fn button <'a, K: Content<TuiOut> + 'a, L: Content<TuiOut> + 'a> (&'a self, key: K, label: L)
|
||||
-> impl Content<TuiOut> + 'a
|
||||
{
|
||||
let compact = !self.is_editing();
|
||||
Tui::bold(true, Bsp::e(
|
||||
Margin::x(1, Tui::fg_bg(Tui::g(0), Tui::orange(), key)),
|
||||
Tui::fg_bg(Tui::g(0), Tui::orange(), Bsp::e(key, Tui::fg(Tui::g(96), "▐"))),
|
||||
When::new(compact, Margin::x(1, Tui::fg_bg(Tui::g(255), Tui::g(96), label))),
|
||||
))
|
||||
}
|
||||
|
||||
// TRACKS /////////////////////////////////////////////////////////////////////////////////////
|
||||
fn w_tracks (&self, editing: bool, bigger: usize) -> u16 {
|
||||
self.tracks_sizes(editing, bigger).last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
|
||||
}
|
||||
const TRACK_SPACING: usize = 0;
|
||||
fn tracks_sizes <'a> (&'a self, editing: bool, bigger: usize) -> impl TracksSizes<'a> {
|
||||
let mut x = 0;
|
||||
let active = match self.selected() {
|
||||
|
|
@ -264,7 +290,7 @@ impl Tek {
|
|||
self.tracks().iter().enumerate().map(move |(index, track)|{
|
||||
let width = if Some(index) == active { bigger } else { track.width.max(8) };
|
||||
let data = (index, track, x, x + width);
|
||||
x += width + Self::WIDTH_OFFSET;
|
||||
x += width + Self::TRACK_SPACING;
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -284,6 +310,12 @@ impl Tek {
|
|||
});
|
||||
self.view_row(self.w(), height, header, content)
|
||||
}
|
||||
fn view_track_add (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let data = (self.selected.track().unwrap_or(0), self.tracks().len());
|
||||
self.fmtd.write().unwrap().trks.update(Some(data),
|
||||
rewrite!(buf, "({}/{})", data.0, data.1));
|
||||
self.button(" T", Bsp::e("track ", self.fmtd.read().unwrap().trks.view.clone()))
|
||||
}
|
||||
|
||||
// INPUTS /////////////////////////////////////////////////////////////////////////////////////
|
||||
fn inputs_sizes (&self) -> impl PortsSizes<'_> {
|
||||
|
|
@ -295,14 +327,11 @@ impl Tek {
|
|||
data
|
||||
})
|
||||
}
|
||||
fn h_inputs (&self) -> u16 {
|
||||
1 + self.inputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
fn view_inputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let fg = Tui::g(224);
|
||||
let bg = Tui::g(64);
|
||||
let header = self.view_io_header(" I ", " midi ins", self.midi_ins.len(), fg, bg, ||self.inputs_sizes());
|
||||
let cells: ThunkBox<_> = per_track_top!(self.size.w();|self, track, t|{
|
||||
let header = self.view_io_header(" I", "midi ins", self.midi_ins.len(), fg, bg, ||self.inputs_sizes());
|
||||
let cells = self.per_track_top(move|t, track|{
|
||||
let rec = track.player.recording;
|
||||
let mon = track.player.monitoring;
|
||||
let bg = if self.selected().track() == Some(t+1) { track.color.light.rgb } else { track.color.base.rgb };
|
||||
|
|
@ -317,17 +346,13 @@ impl Tek {
|
|||
Self::wrap(bg, fg, Bsp::e(
|
||||
Tui::fg_bg(if rec { White } else { track.color.darkest.rgb }, bg, "R▞▞▞▞"),
|
||||
Tui::fg_bg(if mon { White } else { track.color.darkest.rgb }, bg, "M▞▞▞▞"))))))))});
|
||||
|
||||
Bsp::<_, Push<u16, ThunkBox<_>>>::s(
|
||||
Tui::bg(Black, self.view_row_top(self.w(), self.h_inputs(), header, Tui::bg(Red, cells))),
|
||||
Push::xy(self.w_sidebar(), 1, per_track_top!(self.size.w();|self, track, t|"kyp"))
|
||||
Bsp::s(
|
||||
Tui::bg(Black, self.row_top(self.w(), self.h_inputs(), header, Tui::bg(Red, cells))),
|
||||
Tui::bg(Black, self.row_top(self.w(), self.h_inputs(), "Into:", self.per_track_top(|_, _|" --- ")))
|
||||
)
|
||||
}
|
||||
|
||||
// OUTPUTS ////////////////////////////////////////////////////////////////////////////////////
|
||||
fn h_outputs (&self) -> u16 {
|
||||
1 + self.outputs_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
fn outputs_sizes (&self) -> impl PortsSizes<'_> {
|
||||
let mut y = 0;
|
||||
self.midi_outs.iter().enumerate().map(move|(i, output)|{
|
||||
|
|
@ -340,10 +365,10 @@ impl Tek {
|
|||
fn view_outputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let fg = Tui::g(224);
|
||||
let bg = Tui::g(64);
|
||||
let header = self.view_io_header(" O ", " midi outs", self.midi_outs.len(), fg, bg, ||self.outputs_sizes());
|
||||
let mute = false;
|
||||
let solo = false;
|
||||
let cells: ThunkBox<_> = per_track_top!(self.size.w();|self, track, t|{
|
||||
let header = self.view_io_header(" O", "midi outs", self.midi_outs.len(), fg, bg, ||self.outputs_sizes());
|
||||
let cells = self.per_track_top(move |t, track|{
|
||||
let mute = false;
|
||||
let solo = false;
|
||||
let bg = if self.selected().track() == Some(t+1) { track.color.light.rgb } else { track.color.base.rgb };
|
||||
let bg2 = if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
|
||||
Bsp::s(
|
||||
|
|
@ -357,15 +382,10 @@ impl Tek {
|
|||
Tui::fg_bg(if mute { White } else { track.color.darkest.rgb }, bg, "P▞▞▞▞"),
|
||||
Tui::fg_bg(if solo { White } else { track.color.darkest.rgb }, bg, "S▞▞▞▞")))))))});
|
||||
|
||||
Tui::bg(Black, self.view_row_top(self.w(), self.h_outputs(),
|
||||
Tui::bg(Yellow, header),
|
||||
Tui::bg(Blue, cells)))
|
||||
Tui::bg(Black, self.row_top(self.w(), self.h_outputs(), header, cells))
|
||||
}
|
||||
|
||||
// SCENES /////////////////////////////////////////////////////////////////////////////////////
|
||||
fn h_scenes (&self, editing: bool, height: usize, larger: usize) -> u16 {
|
||||
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
fn scenes_sizes (&self, editing: bool, height: usize, larger: usize) -> impl ScenesSizes<'_> {
|
||||
let mut y = 0;
|
||||
let (selected_track, selected_scene) = match self.selected() {
|
||||
|
|
@ -466,43 +486,14 @@ impl Tek {
|
|||
let colors = colors(color, prev, selected, neighbor, is_last);
|
||||
Phat { width: 0, height: 0, selected, content, colors, }
|
||||
}
|
||||
fn w (&self) -> u16 {
|
||||
self.tracks_sizes(self.is_editing(), self.editor_w())
|
||||
.last()
|
||||
.map(|x|x.3 as u16)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
fn w_sidebar (&self) -> u16 {
|
||||
let w = (self.size.w() / 10);
|
||||
let w = w.min(if w > 80 { 20 } else if w > 70 { 18 } else if w > 60 { 16 }
|
||||
else if w > 50 { 14 } else if w > 40 { 12 } else { 10 });
|
||||
//let w = if self.is_editing() { w / 2 } else { w };
|
||||
w as u16
|
||||
}
|
||||
fn view_track_add (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let data = (self.selected.track().unwrap_or(0), self.tracks().len());
|
||||
self.fmtd.write().unwrap().trks.update(Some(data),
|
||||
rewrite!(buf, "({}/{})", data.0, data.1));
|
||||
button(" T ", Bsp::e(" track ",
|
||||
self.fmtd.read().unwrap().trks.view.clone()))
|
||||
}
|
||||
fn view_scene_add (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let data = (self.selected().scene().unwrap_or(0), self.scenes().len());
|
||||
self.fmtd.write().unwrap().scns.update(Some(data),
|
||||
rewrite!(buf, "({}/{})", data.0, data.1));
|
||||
button(" C-a ", Bsp::e(" add scene ",
|
||||
self.button(" C-a ", Bsp::e(" add scene ",
|
||||
self.fmtd.read().unwrap().scns.view.clone()))
|
||||
}
|
||||
}
|
||||
fn button <'a> (
|
||||
key: impl Content<TuiOut> + 'a,
|
||||
label: impl Content<TuiOut> + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Tui::bold(true, Bsp::e(
|
||||
Tui::fg_bg(Tui::g(0), Tui::orange(), key),
|
||||
Tui::fg_bg(Tui::g(255), Tui::g(96), label),
|
||||
))
|
||||
}
|
||||
fn colors (
|
||||
this: &ItemPalette,
|
||||
prev: Option<ItemPalette>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue