mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-05-03 07:10:13 +02:00
flatten more fns
This commit is contained in:
parent
fe9d5a309e
commit
e0f4ec9a15
|
@ -6,8 +6,8 @@ mod keymap; pub use self::keymap::*;
|
|||
pub(crate) use ::tek_edn::*;
|
||||
/// Standard error trait.
|
||||
pub(crate) use std::error::Error;
|
||||
///// Standard result type.
|
||||
//pub(crate) type Usually<T> = Result<T, Box<dyn Error>>;
|
||||
/// Standard result type.
|
||||
#[cfg(test)] pub(crate) type Usually<T> = Result<T, Box<dyn Error>>;
|
||||
/// Standard optional result type.
|
||||
pub(crate) type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||
#[cfg(test)] #[test] fn test_stub_input () -> Usually<()> {
|
||||
|
|
143
tek/src/view.rs
143
tek/src/view.rs
|
@ -47,68 +47,50 @@ impl Tek {
|
|||
.map(|pool|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), pool)))
|
||||
}
|
||||
|
||||
pub(crate) fn w (&self) -> u16 { self.size.w() as u16 }
|
||||
pub(crate) fn h (&self) -> u16 { self.size.h() as u16 }
|
||||
pub(crate) fn w_sidebar (&self) -> u16 { self.w() / if self.is_editing() { 16 } else { 8 } as u16 }
|
||||
pub(crate) fn row <'a> (
|
||||
&'a self,
|
||||
w: u16,
|
||||
h: u16,
|
||||
a: impl Content<TuiOut> + 'a,
|
||||
b: impl Content<TuiOut> + 'a,
|
||||
c: impl Content<TuiOut> + 'a,
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fixed::y(h, Bsp::a(
|
||||
Fill::xy(Align::c(Fixed::x(w, Align::x(b)))),
|
||||
Bsp::a(
|
||||
Fill::xy(Align::w(Fixed::x(self.w_sidebar() as u16, a))),
|
||||
Fill::xy(Align::e(Fixed::x(self.w_sidebar() as u16, c))),
|
||||
),
|
||||
))
|
||||
}
|
||||
pub(crate) fn row_top <'a> (
|
||||
&'a self,
|
||||
w: u16,
|
||||
h: u16,
|
||||
a: impl Content<TuiOut> + 'a,
|
||||
b: impl Content<TuiOut> + 'a,
|
||||
c: impl Content<TuiOut> + 'a,
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fixed::y(h, Bsp::a(
|
||||
Fill::x(Align::n(Fixed::x(w, Align::x(Tui::bg(Reset, b))))),
|
||||
Bsp::a(
|
||||
Fill::x(Align::nw(Fixed::x(self.w_sidebar() as u16, Tui::bg(Reset, a)))),
|
||||
Fill::x(Align::ne(Fixed::x(self.w_sidebar() as u16, Tui::bg(Reset, c)))),
|
||||
),
|
||||
))
|
||||
}
|
||||
pub(crate) fn io_ports <'a, T: PortsSizes<'a>> (
|
||||
&'a self, fg: Color, bg: Color, iter: impl Fn()->T + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
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(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)))))))))}
|
||||
pub(crate) fn io_connections <'a, T: PortsSizes<'a>> (
|
||||
&'a self, fg: Color, bg: Color, iter: impl Fn()->T + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
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, Self::wrap(bg, fg, Fill::x(Align::w("▞▞▞▞ ▞▞▞▞"))))),
|
||||
Map::new(||connections.iter(), move|connect, index|map_south(index as u16, 1,
|
||||
Fill::x(Align::w(Tui::bold(false, Self::wrap(bg, fg, Fill::x(""))))))))))}
|
||||
fn heading <'a> (
|
||||
&'a self, key: &'a str, label: &'a str, count: usize,
|
||||
content: impl Content<TuiOut> + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
let count = format!("{count}");
|
||||
Fill::xy(Align::w(Bsp::s(Fill::x(Align::w(button_3(key, label, count, self.is_editing()))), content)))
|
||||
}
|
||||
pub(crate) 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))) }
|
||||
}
|
||||
|
||||
pub(crate) fn row <'a> (
|
||||
w: u16,
|
||||
h: u16,
|
||||
s: u16,
|
||||
a: impl Content<TuiOut> + 'a,
|
||||
b: impl Content<TuiOut> + 'a,
|
||||
c: impl Content<TuiOut> + 'a,
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fixed::y(h, Bsp::a(
|
||||
Fill::xy(Align::c(Fixed::x(w, Align::x(b)))),
|
||||
Bsp::a(
|
||||
Fill::xy(Align::w(Fixed::x(s, a))),
|
||||
Fill::xy(Align::e(Fixed::x(s, c))),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn row_top <'a> (
|
||||
w: u16,
|
||||
h: u16,
|
||||
s: u16,
|
||||
a: impl Content<TuiOut> + 'a,
|
||||
b: impl Content<TuiOut> + 'a,
|
||||
c: impl Content<TuiOut> + 'a,
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
Fixed::y(h, Bsp::a(
|
||||
Fill::x(Align::n(Fixed::x(w, Align::x(Tui::bg(Reset, b))))),
|
||||
Bsp::a(
|
||||
Fill::x(Align::nw(Fixed::x(s, Tui::bg(Reset, a)))),
|
||||
Fill::x(Align::ne(Fixed::x(s, Tui::bg(Reset, c)))),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) 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)))
|
||||
}
|
||||
|
||||
pub(crate) fn button_2 <'a, K, L> (
|
||||
|
@ -154,26 +136,27 @@ pub(crate) fn button_3 <'a, K, L, V> (
|
|||
));
|
||||
Tui::bold(true, Bsp::e(key, label))
|
||||
}
|
||||
|
||||
fn heading <'a> (
|
||||
key: &'a str,
|
||||
label: &'a str,
|
||||
count: usize,
|
||||
content: impl Content<TuiOut> + Send + Sync + 'a,
|
||||
editing: bool,
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
let count = format!("{count}");
|
||||
Fill::xy(Align::w(Bsp::s(Fill::x(Align::w(button_3(key, label, count, editing))), content)))
|
||||
}
|
||||
|
||||
#[cfg(test)] mod test {
|
||||
use super::*;
|
||||
#[test] fn test_view () {
|
||||
let app = Tek::default();
|
||||
let _ = app.view_editor();
|
||||
let _ = app.view_pool();
|
||||
let _ = app.w();
|
||||
let _ = app.w_sidebar();
|
||||
let _ = app.w_tracks_area();
|
||||
let _ = app.h();
|
||||
let _ = app.h_tracks_area();
|
||||
let _ = app.row(0, 0, "", "", "");
|
||||
let _ = app.row_top(0, 0, "", "", "");
|
||||
//let _ = app.io_ports(Reset, Reset, ||[].iter());
|
||||
//let _ = app.io_connections(Reset, Reset, ||[].iter());
|
||||
let _ = app.button_2("", "", true);
|
||||
let _ = app.button_2("", "", false);
|
||||
let _ = app.button_3("", "", "", true);
|
||||
let _ = app.button_3("", "", "", false);
|
||||
let _ = app.heading("", "", 0, "");
|
||||
let _ = Tek::wrap(Reset, Reset, "");
|
||||
let _ = button_2("", "", true);
|
||||
let _ = button_2("", "", false);
|
||||
let _ = button_3("", "", "", true);
|
||||
let _ = button_3("", "", "", false);
|
||||
let _ = heading("", "", 0, "", true);
|
||||
let _ = heading("", "", 0, "", false);
|
||||
let _ = wrap(Reset, Reset, "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use crate::*;
|
||||
impl Tek {
|
||||
const TAB: &str = " Tab";
|
||||
|
||||
/// Blit the currently visible section of the arranger to the output.
|
||||
///
|
||||
/// If the arranger is larger than the available display area,
|
||||
/// the scrollbars determine the portion that will be shown.
|
||||
pub fn view_arranger (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
()
|
||||
() // TODO
|
||||
}
|
||||
|
||||
/// Draw the full arranger to the arranger view buffer.
|
||||
///
|
||||
/// This should happen on changes to the arrangement view
|
||||
|
@ -19,27 +19,25 @@ impl Tek {
|
|||
let height = self.h_scenes() + self.h_inputs() + self.h_outputs();
|
||||
let buffer = Buffer::empty(ratatui::prelude::Rect { x: 0, y: 0, width, height });
|
||||
let mut output = TuiOut { buffer, area: [0, 0, width, height] };
|
||||
let content = Bsp::s(self.view_inputs(),
|
||||
Bsp::s(self.view_tracks(),
|
||||
Bsp::n(self.view_outputs(), self.view_scenes())));
|
||||
Content::render(&content, &mut output);
|
||||
Content::render(&Bsp::s(self.view_inputs(), Bsp::s(self.view_tracks(),
|
||||
Bsp::n(self.view_outputs(), self.view_scenes()))), &mut output);
|
||||
*self.arranger.write().unwrap() = output.buffer;
|
||||
}
|
||||
|
||||
/// Display the current scene scroll state.
|
||||
fn scene_scrollbar (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
Fill::y(Fixed::x(1, ScrollbarV {
|
||||
offset: self.scene_scroll,
|
||||
length: self.h_tracks_area() as usize,
|
||||
total: self.h_scenes() as usize,
|
||||
}))
|
||||
let offset = self.scene_scroll;
|
||||
let length = self.h_tracks_area() as usize;
|
||||
let total = self.h_scenes() as usize;
|
||||
Fill::y(Fixed::x(1, ScrollbarV { offset, length, total }))
|
||||
}
|
||||
|
||||
/// Display the current track scroll state.
|
||||
fn track_scrollbar (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
Fill::x(Fixed::y(1, ScrollbarH {
|
||||
offset: self.track_scroll,
|
||||
length: self.w_tracks_area() as usize,
|
||||
total: self.w_tracks() as usize,
|
||||
}))
|
||||
let offset = self.track_scroll;
|
||||
let length = self.w_tracks_area() as usize;
|
||||
let total = self.w_tracks() as usize;
|
||||
Fill::x(Fixed::y(1, ScrollbarH { offset, length, total }))
|
||||
}
|
||||
|
||||
fn per_track <'a, T: Content<TuiOut> + 'a> (
|
||||
|
@ -47,11 +45,16 @@ impl Tek {
|
|||
) -> impl Content<TuiOut> + 'a {
|
||||
self.per_track_top(move|index, track|Fill::y(Align::y(f(index, track))))
|
||||
}
|
||||
|
||||
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.w_tracks_area();
|
||||
let filter = move|(t, track, x1, x2)|if x2 as u16 >= width {None} else {Some((t, track, x1, x2))};
|
||||
let filter = move|(t, track, x1, x2)|if x2 as u16 >= width {
|
||||
None
|
||||
} else {
|
||||
Some((t, track, x1, x2))
|
||||
};
|
||||
let tracks = move||self.tracks_sizes().map_while(filter);
|
||||
Align::x(Tui::bg(Reset, Map::new(tracks, move|(index, track, x1, x2), _|{
|
||||
let width = (x2 - x1) as u16;
|
||||
|
@ -64,26 +67,18 @@ impl Tek {
|
|||
|
||||
pub fn view_tracks (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let w = (self.size.w() as u16).saturating_sub(2 * self.w_sidebar());
|
||||
let s = self.w_sidebar() as u16;
|
||||
let data = (self.selected.track().unwrap_or(0), self.tracks().len());
|
||||
let editing = self.is_editing();
|
||||
self.fmtd.write().unwrap().trks.update(Some(data), rewrite!(buf, "{}/{}", data.0, data.1));
|
||||
self.row(w, 1, button_3("t", "track", self.fmtd.read().unwrap().trks.view.clone(), editing),
|
||||
self.per_track(|t, track|self.view_track_header(t, track)),
|
||||
button_2("T", "add track", editing))
|
||||
}
|
||||
|
||||
fn view_track_header <'a> (&self, t: usize, track: &'a Track) -> impl Content<TuiOut> + use<'a> {
|
||||
let active = self.selected().track() == Some(t);
|
||||
let name = &track.name;
|
||||
let fg = track.color.lightest.rgb;
|
||||
let bg = if active { track.color.light.rgb } else { track.color.base.rgb };
|
||||
let bg2 = Reset;//if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
|
||||
let bfg = if active { Rgb(255,255,255) } else { Rgb(0,0,0) };
|
||||
Self::wrap(bg, fg, Tui::bold(true, Fill::x(Align::nw(name))))
|
||||
row(w, 1, s, button_3("t", "track", self.fmtd.read().unwrap().trks.view.clone(), editing),
|
||||
self.per_track(|t, track|track_header(t, track, self.selected().track() == Some(t))),
|
||||
button_2("T", "add track", editing))
|
||||
}
|
||||
|
||||
pub fn view_scenes (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let editing = self.is_editing();
|
||||
let s = self.w_sidebar() as u16;
|
||||
let w = self.w_tracks_area();
|
||||
let w_full = self.w();
|
||||
let h = self.h_scenes();
|
||||
|
@ -91,7 +86,7 @@ impl Tek {
|
|||
let selected_track = self.selected().track();
|
||||
let selected_scene = self.selected().scene();
|
||||
Tui::bg(Reset, Bsp::s(self.track_scrollbar(), Bsp::e(self.scene_scrollbar(),
|
||||
Fixed::y(self.h_tracks_area(), self.row(self.w_tracks_area(), h,
|
||||
Fixed::y(self.h_tracks_area(), row(self.w_tracks_area(), h, s,
|
||||
Map::new(
|
||||
move||self.scenes_with_colors(editing, h_area),
|
||||
move|(s, scene, y1, y2, prev): SceneColor, _|self.view_scene_name(
|
||||
|
@ -105,8 +100,13 @@ impl Tek {
|
|||
}
|
||||
|
||||
fn view_scene_name (
|
||||
&self, width: u16, height: u16, offset: u16,
|
||||
s: usize, scene: &Scene, prev: Option<ItemPalette>,
|
||||
&self,
|
||||
width: u16,
|
||||
height: u16,
|
||||
offset: u16,
|
||||
s: usize,
|
||||
scene: &Scene,
|
||||
prev: Option<ItemPalette>,
|
||||
) -> impl Content<TuiOut> + use<'_> {
|
||||
let bg = scene.color;
|
||||
let fg = scene.color.lightest.rgb;
|
||||
|
@ -168,9 +168,11 @@ impl Tek {
|
|||
self.fmtd.write().unwrap().scns.update(Some(data), rewrite!(buf, "({}/{})", data.0, data.1));
|
||||
button_3("S", "add scene", self.fmtd.read().unwrap().scns.view.clone(), editing)
|
||||
}
|
||||
|
||||
pub fn view_outputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let editing = self.is_editing();
|
||||
let w = self.w_tracks_area();
|
||||
let s = self.w_sidebar() as u16;
|
||||
let fg = Tui::g(224);
|
||||
let nexts = self.per_track_top(|t, track|Either(
|
||||
track.player.next_clip.is_some(),
|
||||
|
@ -180,41 +182,46 @@ impl Tek {
|
|||
.map(|clip|clip.read().unwrap().name.clone()))
|
||||
.flatten().as_ref()))),
|
||||
Thunk::new(||Tui::bg(Reset, " ------ "))));
|
||||
let nexts = self.row_top(w, 2, Align::ne("Next:"), nexts, ());
|
||||
let nexts = row_top(w, 2, s, Align::ne("Next:"), nexts, ());
|
||||
let froms = self.per_track_top(|_, _|Tui::bg(Reset, Align::c(Bsp::s(" ------ ", OctaveVertical::default(),))));
|
||||
let froms = self.row_top(w, 2, Align::ne("From:"), froms, ());
|
||||
let ports = self.row_top(w, 1,
|
||||
let froms = row_top(w, 2, s, Align::ne("From:"), froms, ());
|
||||
let ports = row_top(w, 1, s,
|
||||
button_3("o", "midi outs", format!("{}", self.midi_outs.len()), editing),
|
||||
self.per_track_top(move|t, track|{
|
||||
let mute = false;
|
||||
let solo = false;
|
||||
let mute = if mute { White } else { track.color.darkest.rgb };
|
||||
let solo = if solo { White } else { track.color.darkest.rgb };
|
||||
let bg = if self.selected().track() == Some(t) { track.color.light.rgb } else { track.color.base.rgb };
|
||||
let bg2 = if t > 0 { self.tracks()[t].color.base.rgb } else { Reset };
|
||||
Self::wrap(bg, fg, Tui::bold(true, Fill::x(Bsp::e(
|
||||
let bg = if self.selected().track() == Some(t) {
|
||||
track.color.light.rgb
|
||||
} else {
|
||||
track.color.base.rgb
|
||||
};
|
||||
let bg2 = if t > 0 { self.tracks()[t].color.base.rgb } else { Reset };
|
||||
wrap(bg, fg, Tui::bold(true, Fill::x(Bsp::e(
|
||||
Tui::fg_bg(mute, bg, "Play "),
|
||||
Tui::fg_bg(solo, bg, "Solo ")))))}),
|
||||
button_2("O", "add midi out", editing));
|
||||
let routes = self.row_top(w, self.h_outputs() - 1,
|
||||
self.io_ports(fg, Tui::g(32), ||self.outputs_sizes()),
|
||||
self.per_track_top(move|t, track|self.io_connections(
|
||||
let routes = row_top(w, self.h_outputs() - 1, s,
|
||||
io_ports(fg, Tui::g(32), ||self.outputs_sizes()),
|
||||
self.per_track_top(move|t, track|io_conns(
|
||||
track.color.dark.rgb, track.color.darker.rgb, ||self.outputs_sizes())), ());
|
||||
|
||||
Align::n(Bsp::s(Bsp::s(nexts, froms), Bsp::s(ports, routes)))
|
||||
}
|
||||
|
||||
pub fn view_inputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let editing = self.is_editing();
|
||||
let w = (self.size.w() as u16).saturating_sub(2 * self.w_sidebar());
|
||||
let s = self.w_sidebar() as u16;
|
||||
let fg = Tui::g(224);
|
||||
let routes = self.row_top(w, self.h_inputs() - 1,
|
||||
self.io_ports(fg, Tui::g(32), ||self.inputs_sizes()),
|
||||
self.per_track_top(move|t, track|self.io_connections(
|
||||
let routes = row_top(w, self.h_inputs() - 1, s,
|
||||
io_ports(fg, Tui::g(32), ||self.inputs_sizes()),
|
||||
self.per_track_top(move|t, track|io_conns(
|
||||
track.color.dark.rgb,
|
||||
track.color.darker.rgb,
|
||||
||self.inputs_sizes()
|
||||
)), ());
|
||||
let ports = self.row_top(w, 1,
|
||||
let ports = row_top(w, 1, s,
|
||||
button_3("i", "midi ins", format!("{}", self.midi_ins.len()), editing),
|
||||
self.per_track_top(move|t, track|{
|
||||
let rec = track.player.recording;
|
||||
|
@ -227,18 +234,71 @@ impl Tek {
|
|||
track.color.base.rgb
|
||||
};
|
||||
let bg2 = if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
|
||||
Self::wrap(bg, fg, Tui::bold(true, Fill::x(Bsp::e(
|
||||
wrap(bg, fg, Tui::bold(true, Fill::x(Bsp::e(
|
||||
Tui::fg_bg(rec, bg, "Rec "),
|
||||
Tui::fg_bg(mon, bg, "Mon ")))))
|
||||
}),
|
||||
button_2("I", "add midi in", editing));
|
||||
Bsp::s(
|
||||
Bsp::s(routes, ports),
|
||||
self.row_top(w, 2,
|
||||
row_top(w, 2, s,
|
||||
Bsp::s(Align::e("Input:"), Align::e("Into:")),
|
||||
self.per_track_top(|_, _|Tui::bg(Reset, Align::c(Bsp::s(
|
||||
OctaveVertical::default(),
|
||||
" ------ ")))), ())
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn track_header <'a> (t: usize, track: &'a Track, active: bool) -> impl Content<TuiOut> + use<'a> {
|
||||
let name = &track.name;
|
||||
let fg = track.color.lightest.rgb;
|
||||
let bg = if active { track.color.light.rgb } else { track.color.base.rgb };
|
||||
let bg2 = Reset;//if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
|
||||
let bfg = if active { Rgb(255,255,255) } else { Rgb(0,0,0) };
|
||||
wrap(bg, fg, Tui::bold(true, Fill::x(Align::nw(name))))
|
||||
}
|
||||
|
||||
fn io_ports <'a, T: PortsSizes<'a>> (
|
||||
fg: Color,
|
||||
bg: Color,
|
||||
iter: impl Fn()->T + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
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(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 io_conns <'a, T: PortsSizes<'a>> (
|
||||
fg: Color,
|
||||
bg: Color,
|
||||
iter: impl Fn()->T + Send + Sync + 'a
|
||||
) -> impl Content<TuiOut> + 'a {
|
||||
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, wrap(bg, fg, Fill::x(Align::w("▞▞▞▞ ▞▞▞▞"))))),
|
||||
Map::new(||connections.iter(), move|connect, index|map_south(index as u16, 1,
|
||||
Fill::x(Align::w(Tui::bold(false, wrap(bg, fg, Fill::x(""))))))))))
|
||||
}
|
||||
|
||||
#[cfg(test)] mod test {
|
||||
use super::*;
|
||||
#[test] fn test_view_arranger () {
|
||||
let app = Tek::default();
|
||||
let _ = io_ports(Reset, Reset, ||app.inputs_sizes());
|
||||
let _ = io_conns(Reset, Reset, ||app.outputs_sizes());
|
||||
let _ = app.per_track(|_, _|());
|
||||
let _ = app.per_track_top(|_, _|());
|
||||
let _ = app.redraw_arranger();
|
||||
//let _ = app.view_editor();
|
||||
//let _ = app.view_pool();
|
||||
//let _ = app.row(0, 0, "", "", "");
|
||||
//let _ = app.row_top(0, 0, "", "", "");
|
||||
//let _ = app.io_ports(Reset, Reset, ||[].iter());
|
||||
//let _ = app.io_conns(Reset, Reset, ||[].iter());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,14 @@ impl Tek {
|
|||
pub(crate) const H_SCENE: usize = 2;
|
||||
/// Default editor height.
|
||||
pub(crate) const H_EDITOR: usize = 15;
|
||||
|
||||
/// Width of display
|
||||
pub(crate) fn w (&self) -> u16 {
|
||||
self.size.w() as u16
|
||||
}
|
||||
pub(crate) fn w_sidebar (&self) -> u16 {
|
||||
self.w() / if self.is_editing() { 16 } else { 8 } as u16
|
||||
}
|
||||
/// Width taken by all tracks.
|
||||
pub(crate) fn w_tracks (&self) -> u16 {
|
||||
self.tracks_sizes().last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
|
||||
|
@ -14,6 +22,10 @@ impl Tek {
|
|||
pub(crate) fn w_tracks_area (&self) -> u16 {
|
||||
self.w().saturating_sub(2 * self.w_sidebar())
|
||||
}
|
||||
/// Height of display
|
||||
pub(crate) fn h (&self) -> u16 {
|
||||
self.size.h() as u16
|
||||
}
|
||||
/// Height available to display tracks.
|
||||
pub(crate) fn h_tracks_area (&self) -> u16 {
|
||||
self.h().saturating_sub(self.h_inputs() + self.h_outputs() + 10)
|
||||
|
@ -28,6 +40,21 @@ impl Tek {
|
|||
}
|
||||
/// Height taken by all scenes.
|
||||
pub(crate) fn h_scenes (&self) -> u16 {
|
||||
self.scenes_sizes(self.is_editing(), Self::H_SCENE, Self::H_EDITOR).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
||||
self.scenes_sizes(self.is_editing(), Self::H_SCENE, Self::H_EDITOR).last()
|
||||
.map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
||||
}
|
||||
}
|
||||
#[cfg(test)] mod test {
|
||||
use super::*;
|
||||
#[test] fn test_view_size () {
|
||||
let app = Tek::default();
|
||||
let _ = app.w();
|
||||
let _ = app.w_sidebar();
|
||||
let _ = app.w_tracks_area();
|
||||
let _ = app.h();
|
||||
let _ = app.h_tracks_area();
|
||||
let _ = app.h_inputs();
|
||||
let _ = app.h_outputs();
|
||||
let _ = app.h_scenes();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ pub(crate) use std::ffi::OsString;
|
|||
use std::sync::{Arc, RwLock};
|
||||
struct TestComponent(String);
|
||||
impl Content<TuiOut> for TestComponent {
|
||||
fn content (&self) -> Option<impl Content<TuiOut>> {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
Some(self.0.as_str())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue