mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
fix outputs outer positioning
This commit is contained in:
parent
821f373bd2
commit
2270eb8cb3
3 changed files with 204 additions and 212 deletions
|
|
@ -269,7 +269,6 @@ pub trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync
|
||||||
fn track_longest (&self) -> usize {
|
fn track_longest (&self) -> usize {
|
||||||
self.tracks().iter().map(|s|s.name.len()).fold(0, usize::max)
|
self.tracks().iter().map(|s|s.name.len()).fold(0, usize::max)
|
||||||
}
|
}
|
||||||
const WIDTH_OFFSET: usize = 1;
|
|
||||||
fn track_next_name (&self) -> Arc<str> {
|
fn track_next_name (&self) -> Arc<str> {
|
||||||
format!("Track{:02}", self.tracks().len() + 1).into()
|
format!("Track{:02}", self.tracks().len() + 1).into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
342
tek/src/view.rs
342
tek/src/view.rs
|
|
@ -175,14 +175,6 @@ impl Tek {
|
||||||
self.pool.as_ref()
|
self.pool.as_ref()
|
||||||
.map(|pool|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), pool)))
|
.map(|pool|Fixed::x(self.w_sidebar(), PoolView(self.is_editing(), pool)))
|
||||||
}
|
}
|
||||||
fn view_row <'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(
|
|
||||||
Fill::xy(Align::w(Fixed::x(self.w_sidebar() as u16, a))),
|
|
||||||
Fill::xy(Align::c(Fixed::x(w, b)))
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
macro_rules! per_track {
|
macro_rules! per_track {
|
||||||
($area:expr;|$self:ident,$track:ident,$index:ident|$content:expr) => {{
|
($area:expr;|$self:ident,$track:ident,$index:ident|$content:expr) => {{
|
||||||
|
|
@ -197,12 +189,10 @@ macro_rules! per_track {
|
||||||
impl Tek {
|
impl Tek {
|
||||||
|
|
||||||
// SIZES //////////////////////////////////////////////////////////////////////////////////////
|
// SIZES //////////////////////////////////////////////////////////////////////////////////////
|
||||||
fn w (&self) -> u16 {
|
fn w (&self) -> u16 { self.size.w() as u16 }
|
||||||
self.tracks_sizes(self.is_editing(), self.editor_w())
|
fn h (&self) -> u16 { self.size.h() as u16 }
|
||||||
.last().map(|x|x.3 as u16) .unwrap_or(0)
|
|
||||||
}
|
|
||||||
fn w_sidebar (&self) -> u16 {
|
fn w_sidebar (&self) -> u16 {
|
||||||
let w = (self.size.w() / 10);
|
let w = self.w() / 10;
|
||||||
let w = w.min(if w > 80 { 20 } else if w > 70 { 18 } else if w > 60 { 16 }
|
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 });
|
else if w > 50 { 14 } else if w > 40 { 12 } else { 10 });
|
||||||
//let w = if self.is_editing() { w / 2 } else { w };
|
//let w = if self.is_editing() { w / 2 } else { w };
|
||||||
|
|
@ -221,64 +211,7 @@ impl Tek {
|
||||||
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
self.scenes_sizes(editing, height, larger).last().map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// COMPONENTS ////////////////////////////////////////////////////////////////////////////////
|
// THINGS WITH SIZES //////////////////////////////////////////////////////////////////////////
|
||||||
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(
|
|
||||||
Fill::xy(Align::nw(Fixed::xy(self.w_sidebar() as u16, h, a))),
|
|
||||||
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);
|
|
||||||
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, 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_io_header <'a, T: PortsSizes<'a>> (
|
|
||||||
&'a self,
|
|
||||||
key: &'a str,
|
|
||||||
label: &str,
|
|
||||||
count: usize,
|
|
||||||
fg: Color,
|
|
||||||
bg: Color,
|
|
||||||
iter: impl Fn()->T + Send + Sync + 'a,
|
|
||||||
) -> 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(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 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(
|
|
||||||
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 /////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
const TRACK_SPACING: usize = 0;
|
const TRACK_SPACING: usize = 0;
|
||||||
fn tracks_sizes <'a> (&'a self, editing: bool, bigger: usize) -> impl TracksSizes<'a> {
|
fn tracks_sizes <'a> (&'a self, editing: bool, bigger: usize) -> impl TracksSizes<'a> {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
|
|
@ -294,30 +227,6 @@ impl Tek {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn view_tracks (&self) -> impl Content<TuiOut> + use<'_> {
|
|
||||||
let height = 3;
|
|
||||||
let header: ThunkBox<_> =
|
|
||||||
(move||Tui::bg(Tui::g(32), Fill::x(Align::w(self.view_track_add()))).boxed()).into();
|
|
||||||
let content: ThunkBox<_> = per_track!(self.size.w();|self, track, t|{
|
|
||||||
let active = self.selected().track() == Some(t+1);
|
|
||||||
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) };
|
|
||||||
Outer(active, Style::default().fg(bfg).bg(bg))
|
|
||||||
.enclose(Self::wrap(bg, fg, Tui::bold(true, Fill::x(Align::nw(name)))))
|
|
||||||
});
|
|
||||||
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<'_> {
|
fn inputs_sizes (&self) -> impl PortsSizes<'_> {
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
self.midi_ins.iter().enumerate().map(move|(i, input)|{
|
self.midi_ins.iter().enumerate().map(move|(i, input)|{
|
||||||
|
|
@ -327,32 +236,6 @@ impl Tek {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
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 = 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 };
|
|
||||||
let bg2 = if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
|
|
||||||
Bsp::s(
|
|
||||||
Fixed::y(1, Align::n(Self::wrap(bg, fg, Tui::bold(true, Bsp::e(
|
|
||||||
Tui::fg_bg(if rec { White } else { track.color.darkest.rgb }, bg, "Rec "),
|
|
||||||
Tui::fg_bg(if mon { White } else { track.color.darkest.rgb }, bg, "Mon ")))))),
|
|
||||||
Fill::y(Tui::bg(Green, Map::new(
|
|
||||||
||self.inputs_sizes(),
|
|
||||||
move|(index, name, conn, y, y2), _|map_south(y as u16, (y2-y) as u16,
|
|
||||||
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::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(), 1, "Into:", self.per_track_top(|_, _|" --- ")))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OUTPUTS ////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
fn outputs_sizes (&self) -> impl PortsSizes<'_> {
|
fn outputs_sizes (&self) -> impl PortsSizes<'_> {
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
self.midi_outs.iter().enumerate().map(move|(i, output)|{
|
self.midi_outs.iter().enumerate().map(move|(i, output)|{
|
||||||
|
|
@ -362,30 +245,6 @@ impl Tek {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
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 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(
|
|
||||||
Fixed::y(1, Self::wrap(bg, fg, Tui::bold(true, Bsp::e(
|
|
||||||
Tui::fg_bg(if mute { White } else { track.color.darkest.rgb }, bg, "Play "),
|
|
||||||
Tui::fg_bg(if solo { White } else { track.color.darkest.rgb }, bg, "Solo "),)))),
|
|
||||||
Fill::y(Map::new(
|
|
||||||
||self.outputs_sizes(),
|
|
||||||
move|(index, name, conn, y, y2), _|map_south(y as u16, (y2-y) as u16,
|
|
||||||
Self::wrap(bg, fg, Bsp::e(
|
|
||||||
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.row_top(self.w(), self.h_outputs(), header, cells))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SCENES /////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
fn scenes_sizes (&self, editing: bool, height: usize, larger: usize) -> impl ScenesSizes<'_> {
|
fn scenes_sizes (&self, editing: bool, height: usize, larger: usize) -> impl ScenesSizes<'_> {
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
let (selected_track, selected_scene) = match self.selected() {
|
let (selected_track, selected_scene) = match self.selected() {
|
||||||
|
|
@ -400,22 +259,168 @@ impl Tek {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// COMPONENTS ////////////////////////////////////////////////////////////////////////////////
|
||||||
|
fn row <'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(
|
||||||
|
Fill::xy(Align::w(Fixed::x(self.w_sidebar() as u16, a))),
|
||||||
|
Fill::xy(Align::c(Fixed::x(w, b)))))}
|
||||||
|
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(
|
||||||
|
Fill::xy(Align::nw(Fixed::xy(self.w_sidebar() as u16, h, a))),
|
||||||
|
Fill::xy(Align::n(Fixed::xy(w, h, b)))))}
|
||||||
|
fn per_track <'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);
|
||||||
|
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, Align::y(Fixed::x(width, styled))) }) }
|
||||||
|
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);
|
||||||
|
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, styled)) }) }
|
||||||
|
fn io_heading <'a, T: PortsSizes<'a>> (
|
||||||
|
&'a self,
|
||||||
|
key: &'a str, label: &str, count: usize,
|
||||||
|
fg: Color, bg: Color,
|
||||||
|
iter: impl Fn()->T + Send + Sync + 'a,
|
||||||
|
) -> impl Content<TuiOut> + 'a {
|
||||||
|
self.heading(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(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 heading <'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(
|
||||||
|
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))))) }
|
||||||
|
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))) }
|
||||||
|
|
||||||
|
// TRACKS /////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
fn view_tracks (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let height = 3;
|
||||||
|
let heading: ThunkBox<_> =
|
||||||
|
(move||Tui::bg(Tui::g(32), Fill::x(Align::w(self.view_track_add()))).boxed()).into();
|
||||||
|
let content = self.per_track(|t, track|{
|
||||||
|
let active = self.selected().track() == Some(t+1);
|
||||||
|
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))))
|
||||||
|
});
|
||||||
|
self.row(self.w(), height, heading, 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()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ACTIVE CLIPS ///////////////////////////////////////////////////////////////////////////////
|
||||||
|
fn view_clips_into (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let heading = "Into:";
|
||||||
|
let content = self.per_track_top(|_, _|" --- ");
|
||||||
|
self.row_top(self.w(), 1, heading, content)
|
||||||
|
}
|
||||||
|
fn view_clips_from (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let heading = "From:";
|
||||||
|
let content = self.per_track_top(|_, _|" --- ");
|
||||||
|
self.row_top(self.w(), 1, heading, content)
|
||||||
|
}
|
||||||
|
fn view_clips_next (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let heading = "Next:";
|
||||||
|
let content = self.per_track_top(|_, _|" --- ");
|
||||||
|
self.row_top(self.w(), 1, heading, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// INPUTS /////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
fn view_inputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let fg = Tui::g(224);
|
||||||
|
let heading = self.io_heading(" I", "midi ins", self.midi_ins.len(), fg, Tui::g(64),
|
||||||
|
||self.inputs_sizes());
|
||||||
|
let content = self.per_track_top(move|t, track|{
|
||||||
|
let rec = track.player.recording;
|
||||||
|
let mon = track.player.monitoring;
|
||||||
|
let rec = if rec { White } else { track.color.darkest.rgb };
|
||||||
|
let mon = if mon { White } else { track.color.darkest.rgb };
|
||||||
|
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 };
|
||||||
|
let headers = Self::wrap(bg, fg, Tui::bold(true, Bsp::e(Tui::fg_bg(rec, bg, "Rec "), Tui::fg_bg(rec, bg, "Mon "))));
|
||||||
|
let toggles = Map::new(||self.inputs_sizes(), move|(index, name, conn, y, y2), _|
|
||||||
|
map_south(y as u16, (y2-y) as u16, Self::wrap(bg, fg, Bsp::e(Tui::fg_bg(rec, bg, "R▞▞▞▞"), Tui::fg_bg(mon, bg, "M▞▞▞▞")))));
|
||||||
|
Bsp::a(Fill::y(Align::n(headers)), toggles)});
|
||||||
|
|
||||||
|
let row = self.row_top(self.w(), self.h_inputs(), heading, content);
|
||||||
|
|
||||||
|
row
|
||||||
|
//Bsp::s(Tui::bg(Black, row), self.view_clips_into())
|
||||||
|
}
|
||||||
|
|
||||||
|
// OUTPUTS ////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
fn view_outputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let fg = Tui::g(224);
|
||||||
|
let heading = self.io_heading(" O", "midi outs", self.midi_outs.len(), fg, Tui::g(64),
|
||||||
|
||self.outputs_sizes());
|
||||||
|
let content = 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+1) { track.color.light.rgb } else { track.color.base.rgb };
|
||||||
|
let bg2 = if t > 0 { self.tracks()[t - 1].color.base.rgb } else { Reset };
|
||||||
|
let headers = Self::wrap(bg, fg, Tui::bold(true, Bsp::e(Tui::fg_bg(mute, bg, "Play "), Tui::fg_bg(solo, bg, "Solo "))));
|
||||||
|
let toggles = Map::new(||self.outputs_sizes(), move|(index, name, conn, y, y2), _|
|
||||||
|
map_south(y as u16, (y2-y) as u16, Self::wrap(bg, fg, Bsp::e(Tui::fg_bg(mute, bg, "P▞▞▞▞"), Tui::fg_bg(solo, bg, "S▞▞▞▞")))));
|
||||||
|
Bsp::s(Fill::y(Align::n(headers)), toggles)});
|
||||||
|
|
||||||
|
let row = self.row_top(self.w(), self.h_outputs(), heading, content);
|
||||||
|
|
||||||
|
row
|
||||||
|
//Bsp::s(Bsp::s(self.view_clips_next(), self.view_clips_from()), Tui::bg(Black, row))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCENES /////////////////////////////////////////////////////////////////////////////////////
|
||||||
fn view_scenes (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_scenes (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
let w = self.size.w() as u16;
|
let w = self.size.w() as u16;
|
||||||
let h = self.size.h() as u16;
|
let h = self.size.h() as u16;
|
||||||
let editing = self.is_editing();
|
let editing = self.is_editing();
|
||||||
let tracks = move||self.tracks_sizes(editing, self.editor_w());
|
let selected_track = self.selected().track();
|
||||||
let header = move||self.view_scenes_header(editing);
|
let selected_scene = self.selected().scene();
|
||||||
let content = move||self.view_scenes_content(editing, h);
|
self.row(w, h,
|
||||||
self.view_row(w, h,
|
|
||||||
<_ as Into<ThunkBox<_>>>::into(header),
|
|
||||||
<_ as Into<ThunkBox<_>>>::into(content))
|
|
||||||
}
|
|
||||||
fn view_scenes_header (&self, editing: bool) -> impl Content<TuiOut> + use<'_> {
|
|
||||||
let size_h = self.size.h();
|
|
||||||
Align::y(Map::new(
|
Align::y(Map::new(
|
||||||
move||self.scenes_sizes(editing, 2, 15).map_while(
|
move||self.scenes_sizes(editing, 2, 15).map_while(
|
||||||
move|(s, scene, y1, y2)|if y2 > size_h {
|
move|(s, scene, y1, y2)|if y2 as u16 > h {
|
||||||
None
|
None
|
||||||
} else { Some((s, scene, y1, y2, if s == 0 {
|
} else { Some((s, scene, y1, y2, if s == 0 {
|
||||||
None
|
None
|
||||||
|
|
@ -429,17 +434,12 @@ impl Tek {
|
||||||
let name = Some(scene.name.clone());
|
let name = Some(scene.name.clone());
|
||||||
map_south(y1 as u16, height, Fixed::y(height, self.view_clip_cell(
|
map_south(y1 as u16, height, Fixed::y(height, self.view_clip_cell(
|
||||||
true, s, &bg, prev, name, " ⯈ ", fg)))
|
true, s, &bg, prev, name, " ⯈ ", fg)))
|
||||||
})).boxed()
|
})).boxed(),
|
||||||
}
|
self.per_track(move|t, track|{
|
||||||
fn view_scenes_content (&self, editing: bool, height: u16) -> ThunkBox<TuiOut> {
|
|
||||||
let selected_track = self.selected().track();
|
|
||||||
let selected_scene = self.selected().scene();
|
|
||||||
per_track!(self.size.w(); |self, track, t|{
|
|
||||||
let tab = " Tab ";
|
|
||||||
let same_track = selected_track == Some(t+1);
|
let same_track = selected_track == Some(t+1);
|
||||||
Map::new(
|
Map::new(
|
||||||
move||self.scenes_sizes(editing, 2, 15).map_while(
|
move||self.scenes_sizes(editing, 2, 15).map_while(
|
||||||
move|(s, scene, y1, y2)|if y2 as u16 > height { None } else { Some((s, scene, y1, y2, if s == 0 {
|
move|(s, scene, y1, y2)|if y2 as u16 > h { None } else { Some((s, scene, y1, y2, if s == 0 {
|
||||||
None } else { Some(self.scenes[s-1].clips[t].as_ref()
|
None } else { Some(self.scenes[s-1].clips[t].as_ref()
|
||||||
.map(|c|c.read().unwrap().color)
|
.map(|c|c.read().unwrap().color)
|
||||||
.unwrap_or(ItemPalette::G[32])) })) }),
|
.unwrap_or(ItemPalette::G[32])) })) }),
|
||||||
|
|
@ -455,8 +455,9 @@ impl Tek {
|
||||||
let edit = |x|Bsp::b(x, When(active, &self.editor));
|
let edit = |x|Bsp::b(x, When(active, &self.editor));
|
||||||
map_south(y1 as u16, height, edit(Fixed::y(height, self.view_clip_cell(
|
map_south(y1 as u16, height, edit(Fixed::y(height, self.view_clip_cell(
|
||||||
same_track, s, &bg, prev, name, " ⏹ ", fg))))})
|
same_track, s, &bg, prev, name, " ⏹ ", fg))))})
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
const TAB: &str = " Tab";
|
||||||
fn view_clip_cell <'a> (
|
fn view_clip_cell <'a> (
|
||||||
&self,
|
&self,
|
||||||
same_track: bool,
|
same_track: bool,
|
||||||
|
|
@ -470,20 +471,9 @@ impl Tek {
|
||||||
let selected_scene = self.selected().scene();
|
let selected_scene = self.selected().scene();
|
||||||
let selected = same_track && selected_scene == Some(scene+1);
|
let selected = same_track && selected_scene == Some(scene+1);
|
||||||
let neighbor = same_track && selected_scene == Some(scene);
|
let neighbor = same_track && selected_scene == Some(scene);
|
||||||
self.view_cell(scene, color, prev, selected, neighbor,
|
|
||||||
Fill::x(Align::w(Tui::fg(fg, Tui::bold(true, Bsp::e(icon, name))))))
|
|
||||||
}
|
|
||||||
fn view_cell <T: Content<TuiOut>> (
|
|
||||||
&self,
|
|
||||||
scene: usize,
|
|
||||||
color: &ItemPalette,
|
|
||||||
prev: Option<ItemPalette>,
|
|
||||||
selected: bool,
|
|
||||||
neighbor: bool,
|
|
||||||
content: T,
|
|
||||||
) -> Phat<T> {
|
|
||||||
let is_last = scene == self.scenes.len().saturating_sub(1);
|
let is_last = scene == self.scenes.len().saturating_sub(1);
|
||||||
let colors = colors(color, prev, selected, neighbor, is_last);
|
let colors = colors(color, prev, selected, neighbor, is_last);
|
||||||
|
let content = Fill::x(Align::w(Tui::fg(fg, Tui::bold(true, Bsp::e(icon, name)))));
|
||||||
Phat { width: 0, height: 0, selected, content, colors, }
|
Phat { width: 0, height: 0, selected, content, colors, }
|
||||||
}
|
}
|
||||||
fn view_scene_add (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_scene_add (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
(bsp/s (max/y 1 :toolbar)
|
(bsp/s
|
||||||
|
(max/y 1 :toolbar)
|
||||||
(fill/x (align/c (bsp/a (fill/xy (align/e :pool))
|
(fill/x (align/c (bsp/a (fill/xy (align/e :pool))
|
||||||
(bsp/a (fill/xy (align/n (bsp/s :tracks :inputs)))
|
(bsp/a
|
||||||
(bsp/a (fill/x (fixed/y :y-outs (align/s :outputs)))
|
(fill/xy (align/n (bsp/s :tracks :inputs)))
|
||||||
|
(bsp/a
|
||||||
|
(fill/xy (align/s :outputs))
|
||||||
(bsp/s :scenes :scene-add)))))))
|
(bsp/s :scenes :scene-add)))))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue