This commit is contained in:
i do not exist 2026-06-16 16:52:56 +03:00
parent 790e33b40c
commit 9283c54eec
4 changed files with 47 additions and 44 deletions

View file

@ -470,13 +470,12 @@ pub trait HasTrack: AsRefOpt<Track> + AsMutOpt<Track> {
tracks: impl Fn() -> U + Send + Sync + 'a, tracks: impl Fn() -> U + Send + Sync + 'a,
callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
) -> impl Draw<Tui> + 'a { ) -> impl Draw<Tui> + 'a {
iter(tracks, iter_east(tracks,
move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{ move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{
let width = (x2 - x1) as u16; w_exact((x2 - x1) as u16, fg_bg(
iter_east(x1 as u16, width, w_exact(width, fg_bg(
track.color.lightest.term, track.color.lightest.term,
track.color.base.term, track.color.base.term,
callback(index, track))))}) callback(index, track)))})
} }
/// Create a new track connecting the [Sequencer] to a [Sampler]. /// Create a new track connecting the [Sequencer] to a [Sampler].
#[cfg(feature = "sampler")] pub fn new_with_sampler ( #[cfg(feature = "sampler")] pub fn new_with_sampler (
@ -530,13 +529,12 @@ pub trait HasTrack: AsRefOpt<Track> + AsMutOpt<Track> {
tracks: impl Fn() -> U + Send + Sync + 'a, tracks: impl Fn() -> U + Send + Sync + 'a,
callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
) -> impl Draw<Tui> + 'a { ) -> impl Draw<Tui> + 'a {
origin_x(bg(Reset, iter(tracks, origin_x(bg(Reset, iter_east(tracks,
move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{ move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{
let width = (x2 - x1) as u16; w_exact((x2 - x1) as u16, fg_bg(
iter_east(x1 as u16, width, w_exact(width, fg_bg(
track.color.lightest.term, track.color.lightest.term,
track.color.base.term, track.color.base.term,
callback(index, track))))}))) callback(index, track))) })))
} }
#[cfg(all(feature = "select"))] impl_as_ref_opt!(Scene: |self: App| self.project.as_ref_opt()); #[cfg(all(feature = "select"))] impl_as_ref_opt!(Scene: |self: App| self.project.as_ref_opt());
#[cfg(all(feature = "select"))] impl_as_mut_opt!(Scene: |self: App| self.project.as_mut_opt()); #[cfg(all(feature = "select"))] impl_as_mut_opt!(Scene: |self: App| self.project.as_mut_opt());
@ -690,33 +688,40 @@ impl Arrangement {
h_exact(1, self.view_inputs_header()), h_exact(1, self.view_inputs_header()),
thunk(|to: &mut Tui|{ thunk(|to: &mut Tui|{
for (index, port) in self.midi_ins().iter().enumerate() { for (index, port) in self.midi_ins().iter().enumerate() {
x_push(index as u16 * 10, h_exact(1, self.view_inputs_row(port))).draw(to) x_push(index as u16 * 10, h_exact(1, self.view_inputs_row(port))).draw(to);
} }
todo!()
}) })
) )
} }
#[cfg(feature = "track")] fn view_inputs_header (&self) -> impl Draw<Tui> + '_ { #[cfg(feature = "track")] fn view_inputs_header (&self) -> impl Draw<Tui> + '_ {
east(w_exact(20, origin_w(button_3("i", "nput ", format!("{}", self.midi_ins.len()), false))), east(w_exact(20, origin_w(button_3("i", "nput ", format!("{}", self.midi_ins.len()), false))),
west(w_exact(4, button_2("I", "+", false)), thunk(move|to: &mut Tui|for (_index, track, x1, _x2) in self.tracks_with_sizes() { west(w_exact(4, button_2("I", "+", false)), thunk(move|to: &mut Tui|{
#[cfg(feature = "track")] for (_index, track, x1, _x2) in self.tracks_with_sizes() {
x_push(x1 as u16, bg(track.color.dark.term, origin_w(w_exact(track.width as u16, east!( #[cfg(feature = "track")]
either(track.sequencer.monitoring, fg(Green, "mon "), "mon "), x_push(x1 as u16, bg(track.color.dark.term, origin_w(w_exact(track.width as u16, east!(
either(track.sequencer.recording, fg(Red, "rec "), "rec "), either(track.sequencer.monitoring, fg(Green, "mon "), "mon "),
either(track.sequencer.overdub, fg(Yellow, "dub "), "dub "), either(track.sequencer.recording, fg(Red, "rec "), "rec "),
))))).draw(to) either(track.sequencer.overdub, fg(Yellow, "dub "), "dub "),
))))).draw(to);
}
todo!()
}))) })))
} }
#[cfg(feature = "track")] fn view_inputs_row (&self, port: &MidiInput) -> impl Draw<Tui> { #[cfg(feature = "track")] fn view_inputs_row (&self, port: &MidiInput) -> impl Draw<Tui> {
east(w_exact(20, origin_w(east("", bold(true, fg(Rgb(255,255,255), port.port_name()))))), east(w_exact(20, origin_w(east("", bold(true, fg(Rgb(255,255,255), port.port_name()))))),
west(w_exact(4, ()), thunk(move|to: &mut Tui|for (_index, track, _x1, _x2) in self.tracks_with_sizes() { west(w_exact(4, ()), thunk(move|to: &mut Tui|{
#[cfg(feature = "track")] for (_index, track, _x1, _x2) in self.tracks_with_sizes() {
bg(track.color.darker.term, origin_w(w_exact(track.width as u16, east!( #[cfg(feature = "track")]
either(track.sequencer.monitoring, fg(Green, ""), " · "), bg(track.color.darker.term, origin_w(w_exact(track.width as u16, east!(
either(track.sequencer.recording, fg(Red, ""), " · "), either(track.sequencer.monitoring, fg(Green, ""), " · "),
either(track.sequencer.overdub, fg(Yellow, ""), " · "), either(track.sequencer.recording, fg(Red, ""), " · "),
)))).draw(to) either(track.sequencer.overdub, fg(Yellow, ""), " · "),
)))).draw(to);
}
todo!()
}))) })))
} }
@ -745,6 +750,7 @@ impl Arrangement {
.draw(to); .draw(to);
} }
} }
todo!();
})))) }))))
); );
@ -767,9 +773,11 @@ impl Arrangement {
h_exact(1, w_full("")).draw(to); h_exact(1, w_full("")).draw(to);
} }
} }
todo!()
}) })
).draw(to) ).draw(to);
} }
todo!()
}) })
))) )))
)) ))

View file

@ -215,15 +215,6 @@ impl ClipLength {
pub fn ticks (&self) -> usize { pub fn ticks (&self) -> usize {
self.pulses % self.ppq self.pulses % self.ppq
} }
pub fn bars_string (&self) -> Arc<str> {
format!("{}", self.bars()).into()
}
pub fn beats_string (&self) -> Arc<str> {
format!("{}", self.beats()).into()
}
pub fn ticks_string (&self) -> Arc<str> {
format!("{:>02}", self.ticks()).into()
}
} }
impl Pool { impl Pool {
@ -272,14 +263,14 @@ impl<'a> PoolView<'a> {
impl ClipLength { impl ClipLength {
fn tui (&self) -> impl Draw<Tui> { fn tui (&self) -> impl Draw<Tui> {
use ClipLengthFocus::*; use ClipLengthFocus::*;
let bars = ||self.bars_string(); let bars = format!("{}", self.bars());
let beats = ||self.beats_string(); let beats = format!("{}", self.beats());
let ticks = ||self.ticks_string(); let ticks = format!("{:>02}", self.ticks());
match self.focus { match self.focus {
None => east!(" ", bars(), ".", beats(), ".", ticks()), None => east!(" ", bars, ".", beats, ".", ticks),
Some(Bar) => east!("[", bars(), "]", beats(), ".", ticks()), Some(Bar) => east!("[", bars, "]", beats, ".", ticks),
Some(Beat) => east!(" ", bars(), "[", beats(), "]", ticks()), Some(Beat) => east!(" ", bars, "[", beats, "]", ticks),
Some(Tick) => east!(" ", bars(), ".", beats(), "[", ticks()), Some(Tick) => east!(" ", bars, ".", beats, "[", ticks),
} }
} }
} }

View file

@ -25,6 +25,8 @@
} }
} }
/// TODO: Preserve the generic passthru syntax;
/// remove this macro (only used twice) and potentially the trait.
#[macro_export] macro_rules! impl_has_clips { #[macro_export] macro_rules! impl_has_clips {
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
impl $(<$($L),*$($T $(: $U)?),*>)? HasClips for $Struct $(<$($L),*$($T),*>)? { impl $(<$($L),*$($T $(: $U)?),*>)? HasClips for $Struct $(<$($L),*$($T),*>)? {
@ -139,8 +141,8 @@ pub(crate) use tengri::{
})); }));
// TODO: Sync these timings with main clock, so that things // TODO: Sync these timings with main clock, so that things
// "accidentally" fall on the beat in overload conditions. // "accidentally" fall on the beat in overload conditions.
let keyboard = run_tui_in(&exit, &state, Duration::from_millis(100))?; let keyboard = tui_keyboard(&exit, &state, Duration::from_millis(100))?;
let terminal = run_tui_out(&exit, &state, Duration::from_millis(10))?; let terminal = tui_output(&exit, &state, Duration::from_millis(10))?;
(keyboard, terminal) (keyboard, terminal)
}) })
}) })
@ -518,11 +520,13 @@ pub fn draw_info_v (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + us
w_full(origin_w(field_h(theme, "Gain ", format!("{}", sample.gain)))), w_full(origin_w(field_h(theme, "Gain ", format!("{}", sample.gain)))),
)).draw(to) )).draw(to)
}); });
let b = thunk(|to: &mut Tui|fg(Red, south!( let b = thunk(|to: &mut Tui|fg(Red, south!(
bold(true, "× No sample."), bold(true, "× No sample."),
"[r] record", "[r] record",
"[Shift-F9] import", "[Shift-F9] import",
))); )));
either(sample.is_some(), a, b) either(sample.is_some(), a, b)
} }
@ -547,7 +551,7 @@ pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, po
let iter = move||ports.iter(); let iter = move||ports.iter();
let names = iter_south(iter, move|port, index|h_full(origin_w(format!(" {index} {}", port.port_name())))); let names = iter_south(iter, move|port, index|h_full(origin_w(format!(" {index} {}", port.port_name()))));
let field = field_v(theme, title, names); let field = field_v(theme, title, names);
wh_exact(Some(20), Some(1 + ins), frame.enclose(wh_exact(Some(20), Some(1 + ins), field))) wh_exact(Some(20), Some(1 + ins), border(true, frame, wh_exact(Some(20), Some(1 + ins), field)))
} }
pub fn io_ports <'a, T: PortsSizes<'a>> ( pub fn io_ports <'a, T: PortsSizes<'a>> (

2
tengri

@ -1 +1 @@
Subproject commit 2dc501c184c0404a50b220a9fe9f756b87e4635b Subproject commit 29035d0b36221f43902ead396a5e94c423f0581d