fix outputs outer positioning

This commit is contained in:
🪞👃🪞 2025-01-25 20:42:59 +01:00
parent 821f373bd2
commit 2270eb8cb3
3 changed files with 204 additions and 212 deletions

View file

@ -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()
} }

View file

@ -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<'_> {

View file

@ -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)))))))