mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
arranger: tweaks, incl. remove unused rendering code
This commit is contained in:
parent
5ed69edd02
commit
ef6aa9ab07
7 changed files with 65 additions and 300 deletions
|
|
@ -26,5 +26,5 @@
|
||||||
(bsp/s :view-arranger-track-outputs
|
(bsp/s :view-arranger-track-outputs
|
||||||
(bsp/s :view-arranger-track-devices :view-arranger-track-inputs)))))))
|
(bsp/s :view-arranger-track-devices :view-arranger-track-inputs)))))))
|
||||||
(fill/xy (bsp/e
|
(fill/xy (bsp/e
|
||||||
(bsp/n (max/y 9 :view-editor-status) (fixed/x 20 (align/nw :view-arranger-scenes-names)))
|
(fixed/x 20 (align/nw :view-arranger-scenes-names))
|
||||||
:view-arranger-scenes-clips)))))
|
:view-arranger-scenes-clips)))))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
(@c color)
|
(@c color)
|
||||||
(@q launch)
|
(@q launch)
|
||||||
(@t select :select-track-header)
|
(@t select :select-track-header)
|
||||||
|
(@s select :select-scene-header)
|
||||||
(@tab edit :clip-selected)
|
(@tab edit :clip-selected)
|
||||||
(@shift-I input add)
|
(@shift-I input add)
|
||||||
(@shift-O output add)
|
(@shift-O output add)
|
||||||
|
|
|
||||||
|
|
@ -204,10 +204,10 @@ impl App {
|
||||||
6.max(self.height() as u16 * 3 / 9)
|
6.max(self.height() as u16 * 3 / 9)
|
||||||
}
|
}
|
||||||
fn focus_editor (&self) -> bool {
|
fn focus_editor (&self) -> bool {
|
||||||
self.is_editing()
|
self.project.editor.is_some()
|
||||||
}
|
}
|
||||||
fn is_editing (&self) -> bool {
|
fn is_editing (&self) -> bool {
|
||||||
HasEditor::is_editing(self)
|
self.project.editor.is_some()
|
||||||
}
|
}
|
||||||
fn focus_message (&self) -> bool {
|
fn focus_message (&self) -> bool {
|
||||||
matches!(self.dialog, Some(Dialog::Message(..)))
|
matches!(self.dialog, Some(Dialog::Message(..)))
|
||||||
|
|
|
||||||
|
|
@ -237,9 +237,6 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScenesView for App {
|
impl ScenesView for App {
|
||||||
fn arrangement (&self) -> &Arrangement {
|
|
||||||
&self.project
|
|
||||||
}
|
|
||||||
fn h_scenes (&self) -> u16 {
|
fn h_scenes (&self) -> u16 {
|
||||||
(self.height() as u16).saturating_sub(20)
|
(self.height() as u16).saturating_sub(20)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,16 +205,13 @@ impl Arrangement {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScenesView for Arrangement {
|
impl ScenesView for Arrangement {
|
||||||
fn arrangement (&self) -> &Arrangement {
|
fn h_scenes (&self) -> u16 {
|
||||||
self
|
|
||||||
}
|
|
||||||
fn h_scenes (&self) -> u16 {
|
|
||||||
(self.height() as u16).saturating_sub(20)
|
(self.height() as u16).saturating_sub(20)
|
||||||
}
|
}
|
||||||
fn w_side (&self) -> u16 {
|
fn w_side (&self) -> u16 {
|
||||||
(self.width() as u16 * 2 / 10).max(20)
|
(self.width() as u16 * 2 / 10).max(20)
|
||||||
}
|
}
|
||||||
fn w_mid (&self) -> u16 {
|
fn w_mid (&self) -> u16 {
|
||||||
(self.width() as u16).saturating_sub(2 * self.w_side()).max(40)
|
(self.width() as u16).saturating_sub(2 * self.w_side()).max(40)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,179 +6,6 @@ where T: ScenesView + HasMidiIns + HasMidiOuts + HasSize<TuiOut> + HasTrackScrol
|
||||||
pub trait TracksView:
|
pub trait TracksView:
|
||||||
ScenesView + HasMidiIns + HasMidiOuts + HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiIns + HasEditor
|
ScenesView + HasMidiIns + HasMidiOuts + HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiIns + HasEditor
|
||||||
{
|
{
|
||||||
/// Height taken by all inputs.
|
|
||||||
fn h_inputs (&self) -> u16 {
|
|
||||||
self.midi_ins_with_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
|
||||||
}
|
|
||||||
/// Height taken by all outputs.
|
|
||||||
fn h_outputs (&self) -> u16 {
|
|
||||||
self.midi_outs_with_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
|
||||||
}
|
|
||||||
/// Render input matrix.
|
|
||||||
fn view_inputs_0 (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tui::bg(Reset, Bsp::s(
|
|
||||||
self.view_input_intos(),
|
|
||||||
Bsp::s(self.view_input_routes(), self.view_input_ports()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn view_input_ports (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
let is_editing = self.is_editing();
|
|
||||||
Tryptich::top(1)
|
|
||||||
.left(20, button_3("i", "midi ins", format!("{}",
|
|
||||||
self.midi_ins().len()), is_editing))
|
|
||||||
.right(20, button_2("I", "add midi in", is_editing))
|
|
||||||
.middle(self.width().saturating_sub(40) as u16,
|
|
||||||
per_track_top(||self.tracks_with_sizes_scrolled(),
|
|
||||||
move|t, track|{
|
|
||||||
let rec = track.sequencer.recording;
|
|
||||||
let mon = track.sequencer.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.arrangement().selection().track() == Some(t) {
|
|
||||||
track.color.light.rgb
|
|
||||||
} else {
|
|
||||||
track.color.base.rgb
|
|
||||||
};
|
|
||||||
//let bg2 = if t > 0 { track.color.base.rgb } else { Reset };
|
|
||||||
wrap(bg, Tui::g(224), Tui::bold(true, Fill::x(Bsp::e(
|
|
||||||
Tui::fg_bg(rec, bg, "Rec "),
|
|
||||||
Tui::fg_bg(mon, bg, "Mon "),
|
|
||||||
))))
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
fn view_input_routes (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tryptich::top(self.h_inputs())
|
|
||||||
.left(self.w_side(),
|
|
||||||
io_ports(Tui::g(224), Tui::g(32), ||self.midi_ins_with_sizes()))
|
|
||||||
.middle(self.w_mid(),
|
|
||||||
per_track_top(||self.tracks_with_sizes_scrolled(),
|
|
||||||
move|_, &Track { color, .. }|io_conns(
|
|
||||||
color.dark.rgb, color.darker.rgb, ||self.midi_ins_with_sizes())))
|
|
||||||
}
|
|
||||||
fn view_input_intos (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tryptich::top(2)
|
|
||||||
.left(self.w_side(),
|
|
||||||
Bsp::s(Align::e("Input:"), Align::e("Into clip:")))
|
|
||||||
.middle(self.w_mid(),
|
|
||||||
per_track_top(||self.tracks_with_sizes_scrolled(),
|
|
||||||
|_, _|Tui::bg(Reset, Align::c(Bsp::s(OctaveVertical::default(), " ------ ")))))
|
|
||||||
}
|
|
||||||
/// Render output matrix.
|
|
||||||
fn view_outputs_0 (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tui::bg(Reset, Align::n(Bsp::s(
|
|
||||||
Bsp::s(self.view_output_ports(), self.view_output_conns()),
|
|
||||||
Bsp::s(self.view_output_nexts(), self.view_output_froms()),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
fn view_output_ports (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tryptich::top(1)
|
|
||||||
.left(self.w_side(), self.view_output_count())
|
|
||||||
.right(self.w_side(), self.view_output_add())
|
|
||||||
.middle(self.w_mid(), self.view_output_map())
|
|
||||||
}
|
|
||||||
fn view_output_count (&self) -> impl Content<TuiOut> {
|
|
||||||
button_3("o", "midi outs", format!("{}", self.midi_outs().len()),
|
|
||||||
self.is_editing()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn view_output_add (&self) -> impl Content<TuiOut> {
|
|
||||||
button_2("O", "add midi out", self.is_editing())
|
|
||||||
}
|
|
||||||
fn view_output_map (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
per_track_top(||self.tracks_with_sizes_scrolled(), move|i, t|{
|
|
||||||
let mute = false;
|
|
||||||
let solo = false;
|
|
||||||
let mute = if mute { White } else { t.color.darkest.rgb };
|
|
||||||
let solo = if solo { White } else { t.color.darkest.rgb };
|
|
||||||
let bg_1 = if self.arrangement().selection().track() == Some(i) {
|
|
||||||
t.color.light.rgb
|
|
||||||
} else {
|
|
||||||
t.color.base.rgb
|
|
||||||
};
|
|
||||||
let bg_2 = if i > 0 { t.color.base.rgb } else { Reset };
|
|
||||||
let mute = Tui::fg_bg(mute, bg_1, "Play ");
|
|
||||||
let solo = Tui::fg_bg(solo, bg_1, "Solo ");
|
|
||||||
wrap(bg_1, Tui::g(224), Tui::bold(true, Fill::x(Bsp::e(mute, solo))))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn view_output_conns (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tryptich::top(self.h_outputs())
|
|
||||||
.left(self.w_side(), io_ports(
|
|
||||||
Tui::g(224), Tui::g(32), ||self.midi_outs_with_sizes()))
|
|
||||||
.middle(self.w_mid(), per_track_top(||self.tracks_with_sizes_scrolled(),
|
|
||||||
|_, t|io_conns(
|
|
||||||
t.color.dark.rgb,
|
|
||||||
t.color.darker.rgb,
|
|
||||||
||self.midi_outs_with_sizes()
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
fn view_output_nexts (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
Tryptich::top(2).left(self.w_side(), Align::ne("From clip:"))
|
|
||||||
.middle(self.w_mid(), per_track_top(||self.tracks_with_sizes_scrolled(),
|
|
||||||
|_, _|Tui::bg(Reset, Align::c(Bsp::s(" ------ ", OctaveVertical::default())))))
|
|
||||||
}
|
|
||||||
fn view_output_froms (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
let label = Align::ne("Next clip:");
|
|
||||||
Tryptich::top(2).left(self.w_side(), label)
|
|
||||||
.middle(self.w_mid(), per_track_top(
|
|
||||||
||self.tracks_with_sizes_scrolled(), |t, track|{
|
|
||||||
let queued = track.sequencer.next_clip.is_some();
|
|
||||||
let queued_blank = Thunk::new(||Tui::bg(Reset, " ------ "));
|
|
||||||
let queued_clip = Thunk::new(||{
|
|
||||||
Tui::bg(Reset, if let Some((_, clip)) = track.sequencer.next_clip.as_ref() {
|
|
||||||
if let Some(clip) = clip {
|
|
||||||
clip.read().unwrap().name.clone()
|
|
||||||
} else {
|
|
||||||
"Stop".into()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
"".into()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
Either(queued, queued_clip, queued_blank)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/// Render track headers
|
|
||||||
fn view_tracks_0 (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
let w_side = self.w_side();
|
|
||||||
let w_mid = self.w_mid();
|
|
||||||
let is_editing = self.is_editing();
|
|
||||||
let track_selected = self.arrangement().selection().track();
|
|
||||||
Tryptich::center(3)
|
|
||||||
.left(w_side,
|
|
||||||
button_3("t", "track", format!("{}", self.tracks().len()), is_editing))
|
|
||||||
.right(w_side, button_2("T", "add track", is_editing))
|
|
||||||
.middle(w_mid, per_track(||self.tracks_with_sizes_scrolled(),
|
|
||||||
move|index, track|wrap(
|
|
||||||
if track_selected == Some(index) {
|
|
||||||
track.color.light
|
|
||||||
} else {
|
|
||||||
track.color.base
|
|
||||||
}.rgb,
|
|
||||||
track.color.lightest.rgb,
|
|
||||||
Tui::bold(true, Fill::xy(Align::nw(&track.name)))
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
/// Render device switches.
|
|
||||||
fn view_devices_0 (&self) -> impl Content<TuiOut> + '_ {
|
|
||||||
let w_side = self.w_side();
|
|
||||||
let w_mid = self.w_mid();
|
|
||||||
let is_editing = self.is_editing();
|
|
||||||
let track_selected = self.arrangement().selection().track();
|
|
||||||
Tryptich::top(1)
|
|
||||||
.left(w_side, button_3("d", "devices", format!("{}", 0), is_editing))
|
|
||||||
.right(w_side, button_2("D", "add device", is_editing))
|
|
||||||
.middle(w_mid, per_track_top(||self.tracks_with_sizes_scrolled(),
|
|
||||||
move|index, track|{
|
|
||||||
let bg = if track_selected == Some(index) {
|
|
||||||
track.color.light
|
|
||||||
} else {
|
|
||||||
track.color.base
|
|
||||||
};
|
|
||||||
let fg = Tui::g(224);
|
|
||||||
track.devices.get(0).map(|device|wrap(bg.rgb, fg, device.name()))
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
fn tracks_width_available (&self) -> u16 {
|
fn tracks_width_available (&self) -> u16 {
|
||||||
(self.width() as u16).saturating_sub(40)
|
(self.width() as u16).saturating_sub(40)
|
||||||
}
|
}
|
||||||
|
|
@ -188,6 +15,11 @@ pub trait TracksView:
|
||||||
((x2 as u16) < self.tracks_width_available())
|
((x2 as u16) < self.tracks_width_available())
|
||||||
.then_some((t, track, x1, x2)))
|
.then_some((t, track, x1, x2)))
|
||||||
}
|
}
|
||||||
|
fn view_track_header <'a, T: Content<TuiOut>> (
|
||||||
|
&'a self, theme: ItemTheme, content: T
|
||||||
|
) -> impl Content<TuiOut> {
|
||||||
|
Fixed::x(12, Tui::bg(theme.darker.rgb, Fill::x(Align::e(content))))
|
||||||
|
}
|
||||||
fn view_track_names (&self, theme: ItemTheme) -> impl Content<TuiOut> {
|
fn view_track_names (&self, theme: ItemTheme) -> impl Content<TuiOut> {
|
||||||
let content = Fixed::y(1, Align::w(Tui::bg(theme.darker.rgb, Align::w(Fill::x(
|
let content = Fixed::y(1, Align::w(Tui::bg(theme.darker.rgb, Align::w(Fill::x(
|
||||||
Stack::east(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
Stack::east(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||||
|
|
@ -230,11 +62,11 @@ pub trait TracksView:
|
||||||
track.color.light.rgb
|
track.color.light.rgb
|
||||||
} else {
|
} else {
|
||||||
track.color.base.rgb
|
track.color.base.rgb
|
||||||
}, Fill::x(Align::w(format!("[mut] [sol]")))),
|
}, Fill::x(Align::w(format!("·mute ·solo")))),
|
||||||
Map::south(2, ||track.sequencer.midi_outs.iter(),
|
Map::south(2, ||track.sequencer.midi_outs.iter(),
|
||||||
|port, index|Tui::fg(Rgb(255, 255, 255),
|
|port, index|Tui::fg(Rgb(255, 255, 255),
|
||||||
Fixed::y(2, Tui::bg(track.color.dark.rgb, Fill::x(Align::w(
|
Fixed::y(2, Tui::bg(track.color.dark.rgb, Fill::x(Align::w(
|
||||||
format!("o{index}: {}", port.name())))))))))));
|
format!("·o{index}: {}", port.name())))))))))));
|
||||||
}
|
}
|
||||||
}))))));
|
}))))));
|
||||||
Bsp::w(
|
Bsp::w(
|
||||||
|
|
@ -245,35 +77,6 @@ pub trait TracksView:
|
||||||
content
|
content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Content<TuiOut> {
|
|
||||||
let mut h = 0u16;
|
|
||||||
for track in self.tracks().iter() {
|
|
||||||
h = h.max(track.sequencer.midi_ins.len() as u16);
|
|
||||||
}
|
|
||||||
let content = Tui::bg(theme.darker.rgb, Align::w(Fill::x(
|
|
||||||
Stack::east(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
|
||||||
for (index, track, x1, x2) in self
|
|
||||||
.tracks_with_sizes(&self.selection(), None)
|
|
||||||
.skip(self.track_scroll())
|
|
||||||
{
|
|
||||||
add(&Fixed::xy(track.width as u16, h + 1,
|
|
||||||
Align::nw(Bsp::s(
|
|
||||||
Tui::bg(track.color.base.rgb,
|
|
||||||
Fill::x(Align::w(format!("[rec] [mon]")))),
|
|
||||||
Map::south(1, ||track.sequencer.midi_ins.iter(),
|
|
||||||
|port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb,
|
|
||||||
Fill::x(Align::w(format!("i{index}: {}", port.name())))))))));
|
|
||||||
}
|
|
||||||
|
|
||||||
}))));
|
|
||||||
Bsp::w(
|
|
||||||
self.view_track_header(theme, row!(
|
|
||||||
Tui::bold(true, button_2("i", "nputs", false)),
|
|
||||||
button_2("I", "+", false)
|
|
||||||
)),
|
|
||||||
Fixed::y(h, Fill::x(Align::w(Fixed::y(h + 1, content)))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn view_track_devices <'a> (&'a self, theme: ItemTheme) -> impl Content<TuiOut> {
|
fn view_track_devices <'a> (&'a self, theme: ItemTheme) -> impl Content<TuiOut> {
|
||||||
let mut h = 2u16;
|
let mut h = 2u16;
|
||||||
for track in self.tracks().iter() {
|
for track in self.tracks().iter() {
|
||||||
|
|
@ -292,14 +95,38 @@ pub trait TracksView:
|
||||||
{
|
{
|
||||||
add(&Fixed::xy(track.width as u16, h + 1,
|
add(&Fixed::xy(track.width as u16, h + 1,
|
||||||
Tui::bg(track.color.dark.rgb, Align::nw(Map::south(1, move||0..h,
|
Tui::bg(track.color.dark.rgb, Align::nw(Map::south(1, move||0..h,
|
||||||
|_, index|format!("d{index}: {}", "--------"))))));
|
|_, index|format!("·d{index}: {}", "--------"))))));
|
||||||
}
|
}
|
||||||
}))))))
|
}))))))
|
||||||
}
|
}
|
||||||
fn view_track_header <'a, T: Content<TuiOut>> (
|
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Content<TuiOut> {
|
||||||
&'a self, theme: ItemTheme, content: T
|
let mut h = 0u16;
|
||||||
) -> impl Content<TuiOut> {
|
for track in self.tracks().iter() {
|
||||||
Fixed::x(12, Tui::bg(theme.darker.rgb, Fill::x(Align::e(content))))
|
h = h.max(track.sequencer.midi_ins.len() as u16);
|
||||||
|
}
|
||||||
|
let content = Tui::bg(theme.darker.rgb, Align::w(Fill::x(
|
||||||
|
Stack::east(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||||
|
for (index, track, x1, x2) in self
|
||||||
|
.tracks_with_sizes(&self.selection(), None)
|
||||||
|
.skip(self.track_scroll())
|
||||||
|
{
|
||||||
|
add(&Fixed::xy(track.width as u16, h + 1,
|
||||||
|
Align::nw(Bsp::n(
|
||||||
|
Tui::bg(track.color.base.rgb,
|
||||||
|
Fill::x(Align::w(format!("·mon ·rec ·dub")))),
|
||||||
|
Map::south(1, ||track.sequencer.midi_ins.iter(),
|
||||||
|
|port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb,
|
||||||
|
Fill::x(Align::w(format!("·i{index}: {}", port.name())))))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
}))));
|
||||||
|
Bsp::w(
|
||||||
|
self.view_track_header(theme, row!(
|
||||||
|
Tui::bold(true, button_2("i", "nputs", false)),
|
||||||
|
button_2("I", "+", false)
|
||||||
|
)),
|
||||||
|
Fixed::y(h, Fill::x(Align::w(Fixed::y(h + 1, content)))),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,10 +135,9 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
||||||
const H_SCENE: usize = 2;
|
const H_SCENE: usize = 2;
|
||||||
/// Default editor height.
|
/// Default editor height.
|
||||||
const H_EDITOR: usize = 15;
|
const H_EDITOR: usize = 15;
|
||||||
fn arrangement (&self) -> &Arrangement;
|
fn h_scenes (&self) -> u16;
|
||||||
fn h_scenes (&self) -> u16;
|
fn w_side (&self) -> u16;
|
||||||
fn w_side (&self) -> u16;
|
fn w_mid (&self) -> u16;
|
||||||
fn w_mid (&self) -> u16;
|
|
||||||
fn view_scenes_names (&self) -> impl Content<TuiOut> {
|
fn view_scenes_names (&self) -> impl Content<TuiOut> {
|
||||||
Stack::south(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
Stack::south(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||||
for (index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) {
|
for (index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) {
|
||||||
|
|
@ -320,81 +146,25 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn view_scene_name (&self, index: usize, scene: &Scene) -> impl Content<TuiOut> {
|
fn view_scene_name (&self, index: usize, scene: &Scene) -> impl Content<TuiOut> {
|
||||||
Fixed::xy(20, if self.selection().scene() == Some(index) && let Some(editor) = self.editor () {
|
let h = if self.selection().scene() == Some(index) && let Some(editor) = self.editor() {
|
||||||
(editor.height() as u16).max(12)
|
(editor.height() as u16).max(12)
|
||||||
} else {
|
} else {
|
||||||
Self::H_SCENE as u16
|
Self::H_SCENE as u16
|
||||||
}, Tui::bg(if self.selection().scene() == Some(index) {
|
};
|
||||||
|
let bg = if self.selection().scene() == Some(index) {
|
||||||
scene.color.light.rgb
|
scene.color.light.rgb
|
||||||
} else {
|
} else {
|
||||||
scene.color.base.rgb
|
scene.color.base.rgb
|
||||||
}, Align::nw(Bsp::e(
|
};
|
||||||
format!(" {index:2} "),
|
Fixed::xy(20, h, Tui::bg(bg, Align::nw(Bsp::s(
|
||||||
Tui::fg(Rgb(255, 255, 255),
|
Fill::x(Align::w(Bsp::e(
|
||||||
Tui::bold(true, format!("{}", scene.name)))))))
|
format!(" {index:2} "),
|
||||||
//let height = (1 + y2 - y1 as u16;
|
Tui::fg(Rgb(255, 255, 255), Tui::bold(true, format!("{}", scene.name)))
|
||||||
//let name = Some(scene.name.clone());
|
))),
|
||||||
//let content = Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⯈ ", name))));
|
When(self.selection().scene() == Some(index) && self.is_editing(),
|
||||||
//let selected = self.scene_selected() == Some(s);
|
Fill::xy(Align::nw(Bsp::s(
|
||||||
//let neighbor = s > 0 && self.scene_selected() == Some(s - 1);
|
self.editor().as_ref().map(|e|e.clip_status()),
|
||||||
//let is_last = self.scenes().len().saturating_sub(1) == s;
|
self.editor().as_ref().map(|e|e.edit_status())))))))))
|
||||||
//let theme = scene.color;
|
|
||||||
//let fg = theme.lightest.rgb;
|
|
||||||
//let bg = if selected { theme.light } else { theme.base }.rgb;
|
|
||||||
//let hi = if let Some(previous) = previous {
|
|
||||||
//if neighbor { previous.light.rgb } else { previous.base.rgb }
|
|
||||||
//} else {
|
|
||||||
//Reset
|
|
||||||
//};
|
|
||||||
//let lo = if is_last { Reset } else if selected {
|
|
||||||
//theme.light.rgb
|
|
||||||
//} else {
|
|
||||||
//theme.base.rgb
|
|
||||||
//};
|
|
||||||
//add(&Fill::x(map_south(y1 as u16, height, Fixed::y(height, Phat {
|
|
||||||
//width: 0, height: 0, content, colors: [fg, bg, hi, lo]
|
|
||||||
//}))))
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
fn scenes_with_prev_color (&self) -> impl Iterator<Item=SceneWith<Option<ItemTheme>>> + Send + Sync {
|
|
||||||
self.scenes_iter().map(|(s, scene, y1, y2)|(s, scene, y1, y2,
|
|
||||||
(s>0).then(||self.arrangement().scenes()[s-1].color)))
|
|
||||||
}
|
|
||||||
fn per_track <'a, T: Content<TuiOut> + 'a, U: TracksSizes<'a>> (
|
|
||||||
tracks: impl Fn() -> U + Send + Sync + 'a,
|
|
||||||
callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
|
|
||||||
) -> impl Content<TuiOut> + 'a {
|
|
||||||
Map::new(tracks, move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{
|
|
||||||
Tui::fg_bg(track.color.lightest.rgb, track.color.darker.rgb,
|
|
||||||
map_east(x1 as u16, (x2 - x1) as u16, callback(index, track))) })
|
|
||||||
}
|
|
||||||
fn scenes_with_clip (&self, track_index: usize) -> impl Iterator<Item=SceneWith<'_, Option<ItemTheme>>> + Send + Sync {
|
|
||||||
self.scenes_iter().map(move|(s, scene, y1, y2)|(s, scene, y1, y2,
|
|
||||||
(s>0).then(||self.arrangement().scenes()[s-1].clips[track_index].as_ref()
|
|
||||||
.map(|c|c.read().unwrap().color)
|
|
||||||
.unwrap_or(ItemTheme::G[32]))))
|
|
||||||
}
|
|
||||||
/// A scene with size and color.
|
|
||||||
fn scenes_iter (&self) -> impl Iterator<Item=(usize, &Scene, usize, usize,)> + Send + Sync {
|
|
||||||
let selection = Has::<Selection>::get(self.arrangement());
|
|
||||||
self.arrangement().scenes_with_sizes(
|
|
||||||
false, // FIXME self.is_editing(),
|
|
||||||
Self::H_SCENE, Self::H_EDITOR,
|
|
||||||
selection.track(), selection.scene(),
|
|
||||||
).map_while(|(s, scene, y1, y2)|(y2<=self.h_scenes() as usize)
|
|
||||||
.then_some((s, scene, y1, y2)))
|
|
||||||
}
|
|
||||||
/// Height required to display all scenes.
|
|
||||||
fn h_scenes_total (&self) -> u16 {
|
|
||||||
self.scenes_with_sizes(
|
|
||||||
self.is_editing(),
|
|
||||||
Self::H_SCENE,
|
|
||||||
Self::H_EDITOR,
|
|
||||||
self.selection().track(),
|
|
||||||
self.selection().scene(),
|
|
||||||
)
|
|
||||||
.last()
|
|
||||||
.map(|(_, _, _, y)|y as u16).unwrap_or(0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ impl MidiEditor {
|
||||||
(clip.color, clip.name.clone(), clip.length, clip.looped)
|
(clip.color, clip.name.clone(), clip.length, clip.looped)
|
||||||
} else { (ItemTheme::G[64], String::new().into(), 0, false) };
|
} else { (ItemTheme::G[64], String::new().into(), 0, false) };
|
||||||
Fixed::x(20, col!(
|
Fixed::x(20, col!(
|
||||||
Fill::x(Align::w(FieldV(color, "Clip ", format!("{name}")))),
|
Fill::x(Align::w(Bsp::e(" Clip ", format!("{name}")))),
|
||||||
Fill::x(Align::w(FieldH(color, "Length", format!("{length}")))),
|
Fill::x(Align::w(Bsp::e(" Length ", format!("{length}")))),
|
||||||
Fill::x(Align::w(FieldH(color, "Loop ", looped.to_string()))),
|
Fill::x(Align::w(Bsp::e(" Loop ", looped.to_string()))),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,9 +31,9 @@ impl MidiEditor {
|
||||||
let note_pos = format!("{:>3}", note_pos);
|
let note_pos = format!("{:>3}", note_pos);
|
||||||
let note_len = format!("{:>4}", self.get_note_len());
|
let note_len = format!("{:>4}", self.get_note_len());
|
||||||
Fixed::x(20, col!(
|
Fixed::x(20, col!(
|
||||||
Fill::x(Align::w(FieldH(color, "Time", format!("{length}/{time_zoom}+{time_pos}")))),
|
Fill::x(Align::w(Bsp::e(" Time ", format!("{length}/{time_zoom}+{time_pos}")))),
|
||||||
Fill::x(Align::w(FieldH(color, "Lock", format!("{time_lock}")))),
|
Fill::x(Align::w(Bsp::e(" Lock ", format!("{time_lock}")))),
|
||||||
Fill::x(Align::w(FieldH(color, "Note", format!("{note_name} {note_pos} {note_len}")))),
|
Fill::x(Align::w(Bsp::e(" Note ", format!("{note_name} {note_pos} {note_len}")))),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue