'197e' is as much as i can tell ya

This commit is contained in:
i do not exist 2026-04-13 17:31:15 +03:00
parent dcca74a649
commit 5ffa9472e1
7 changed files with 975 additions and 948 deletions

View file

@ -1,8 +1,7 @@
use ::std::sync::{Arc, RwLock};
use ::tengri::{space::east, color::ItemTheme};
use ::tengri::{draw::*, term::*};
use crate::{*, device::*, sequence::*, clock::*, select::*, sample::*};
impl HasJack<'static> for Arrangement { fn jack (&self) -> &Jack<'static> { &self.jack } }
use crate::{*, device::*, editor::*, sequence::*, clock::*, select::*, sample::*};
/// Arranger.
///
@ -20,9 +19,9 @@ impl HasJack<'static> for Arrangement { fn jack (&self) -> &Jack<'static> { &sel
/// TODO rename to "render_cache" or smth
pub arranger: Arc<RwLock<Buffer>>,
/// Display size
pub size: [AtomicUsize; 2],
pub size: Size,
/// Display size of clips area
pub size_inner: [AtomicUsize; 2],
pub size_inner: Size,
/// Source of time
#[cfg(feature = "clock")] pub clock: Clock,
/// Allows one MIDI clip to be edited
@ -84,7 +83,11 @@ impl HasJack<'static> for Arrangement { fn jack (&self) -> &Jack<'static> { &sel
}
impl_has!(Jack<'static>: |self: Arrangement| self.jack);
impl_has!([AtomicUsize; 2]: |self: Arrangement| self.size);
impl HasJack<'static> for Arrangement {
fn jack (&self) -> &Jack<'static> { &self.jack }
}
impl_has!(Size: |self: Arrangement| self.size);
impl_has!(Vec<Track>: |self: Arrangement| self.tracks);
impl_has!(Vec<Scene>: |self: Arrangement| self.scenes);
impl_has!(Vec<MidiInput>: |self: Arrangement| self.midi_ins);
@ -110,67 +113,69 @@ pub trait ClipsView: TracksView + ScenesView {
{
self.clips_size().of(wh_full(above(
wh_full(origin_se(fg(Green, format!("{}x{}", self.clips_size().w(), self.clips_size().h())))),
thunk(|to: &mut Tui|for (
track_index, track, _, _
) in self.tracks_with_sizes() {
to.place(&w_exact(track.width as u16,
h_full(self.view_track_clips(track_index, track))))
thunk(|to: &mut Tui|{
for (track_index, track, _, _) in self.tracks_with_sizes() {
to.place(&w_exact(track.width as u16,
h_full(self.view_track_clips(track_index, track))))
}
Ok(XYWH(0, 0, 0, 0))
}))))
}
fn view_track_clips <'a> (&'a self, track_index: usize, track: &'a Track) -> impl Draw<Tui> + 'a {
thunk(move|to: &mut Tui|for (
scene_index, scene, ..
) in self.scenes_with_sizes() {
let (name, theme): (Arc<str>, ItemTheme) = if let Some(Some(clip)) = &scene.clips.get(track_index) {
let clip = clip.read().unwrap();
(format!("{}", &clip.name).into(), clip.color)
} else {
(" ⏹ -- ".into(), ItemTheme::G[32])
};
let fg = theme.lightest.term;
let mut outline = theme.base.term;
let bg = if self.selection().track() == Some(track_index)
&& self.selection().scene() == Some(scene_index)
{
outline = theme.lighter.term;
theme.light.term
} else if self.selection().track() == Some(track_index)
|| self.selection().scene() == Some(scene_index)
{
outline = theme.darkest.term;
theme.base.term
} else {
theme.dark.term
};
let w = if self.selection().track() == Some(track_index)
&& let Some(editor) = self.editor ()
{
(editor.measure_width() as usize).max(24).max(track.width)
} else {
track.width
} as u16;
let y = if self.selection().scene() == Some(scene_index)
&& let Some(editor) = self.editor ()
{
(editor.measure_height() as usize).max(12)
} else {
Self::H_SCENE as usize
} as u16;
thunk(move|to: &mut Tui|{
for (scene_index, scene, ..) in self.scenes_with_sizes() {
let (name, theme): (Arc<str>, ItemTheme) = if let Some(Some(clip)) = &scene.clips.get(track_index) {
let clip = clip.read().unwrap();
(format!("{}", &clip.name).into(), clip.color)
} else {
(" ⏹ -- ".into(), ItemTheme::G[32])
};
let fg = theme.lightest.term;
let mut outline = theme.base.term;
let bg = if self.selection().track() == Some(track_index)
&& self.selection().scene() == Some(scene_index)
{
outline = theme.lighter.term;
theme.light.term
} else if self.selection().track() == Some(track_index)
|| self.selection().scene() == Some(scene_index)
{
outline = theme.darkest.term;
theme.base.term
} else {
theme.dark.term
};
let w = if self.selection().track() == Some(track_index)
&& let Some(editor) = self.editor ()
{
(editor.size.w() as usize).max(24).max(track.width)
} else {
track.width
} as u16;
let y = if self.selection().scene() == Some(scene_index)
&& let Some(editor) = self.editor ()
{
(editor.size.h() as usize).max(12)
} else {
Self::H_SCENE as usize
} as u16;
let is_selected =
self.selection().track() == Some(track_index) &&
self.selection().scene() == Some(scene_index) &&
self.is_editing();
let is_selected =
self.selection().track() == Some(track_index) &&
self.selection().scene() == Some(scene_index) &&
self.is_editing();
to.place(&wh_exact(w, y, below(
wh_full(Outer(true, Style::default().fg(outline))),
wh_full(below(
below(
fg_bg(outline, bg, wh_full("")),
wh_full(origin_nw(fg_bg(fg, bg, bold(true, name)))),
),
wh_full(when(is_selected, self.editor().view())))))));
to.place(&wh_exact(Some(w), Some(y), below(
wh_full(Outer(true, Style::default().fg(outline))),
wh_full(below(
below(
fg_bg(outline, bg, wh_full("")),
wh_full(origin_nw(fg_bg(fg, bg, bold(true, &name)))),
),
wh_full(when(is_selected, self.editor().map(|e|e.view()))))))));
}
Ok(XYWH(0, 0, 0, 0))
})
}
@ -179,12 +184,12 @@ pub trait ClipsView: TracksView + ScenesView {
pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
fn tracks_width_available (&self) -> u16 {
(self.measure_width() as u16).saturating_sub(40)
(self.size.width() as u16).saturating_sub(40)
}
/// Iterate over tracks with their corresponding sizes.
fn tracks_with_sizes (&self) -> impl TracksSizes<'_> {
let _editor_width = self.editor().map(|e|e.measure_width());
let _editor_width = self.editor().map(|e|e.size.w());
let _active_track = self.selection().track();
let mut x = 0;
self.tracks().iter().enumerate().map_while(move |(index, track)|{
@ -222,23 +227,31 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
}, south(w_full(origin_nw(east(
format!("·t{index:02} "),
fg(Rgb(255, 255, 255), bold(true, &track.name))
))), ""))) ));}}))))
))), ""))) ));}
Ok(XYWH(0, 0, 0, 0))
}))))
}
fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw<Tui> {
view_track_row_section(theme,
south(w_full(origin_w(button_2("o", "utput", false))),
thunk(|to: &mut Tui|for port in self.midi_outs().iter() {
to.place(&w_full(origin_w(port.port_name())));
thunk(|to: &mut Tui|{
for port in self.midi_outs().iter() {
to.place(&w_full(origin_w(port.port_name())));
}
Ok(XYWH(0, 0, 0, 0))
})),
button_2("O", "+", false),
bg(theme.darker.term, origin_w(thunk(|to: &mut Tui|{
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
to.place(&w_exact(track_width(index, track),
origin_nw(h_full(iter_south(1, ||track.sequencer.midi_outs.iter(),
origin_nw(h_full(iter_south(||track.sequencer.midi_outs.iter(),
|port, index|fg(Rgb(255, 255, 255),
h_exact(1, bg(track.color.dark.term, w_full(origin_w(
format!("·o{index:02} {}", port.port_name())))))))))));}}))))
format!("·o{index:02} {}", port.port_name())))))))))));
}
Ok(XYWH(0, 0, 0, 0))
}))))
}
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> {
@ -246,18 +259,21 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
for track in self.tracks().iter() {
h = h.max(track.sequencer.midi_ins.len() as u16);
}
let content = thunk(move|to: &mut Tui|for (index, track, _x1, _x2) in self.tracks_with_sizes() {
to.place(&wh_exact(track_width(index, track), h + 1,
origin_nw(south(
bg(track.color.base.term,
w_full(origin_w(east!(
either(track.sequencer.monitoring, fg(Green, "●mon "), "·mon "),
either(track.sequencer.recording, fg(Red, "●rec "), "·rec "),
either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "),
)))),
iter_south(1, ||track.sequencer.midi_ins.iter(),
|port, index|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
w_full(origin_w(format!("·i{index:02} {}", port.port_name())))))))));
let content = thunk(move|to: &mut Tui|{
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
to.place(&wh_exact(track_width(index, track), h + 1,
origin_nw(south(
bg(track.color.base.term,
w_full(origin_w(east!(
either(track.sequencer.monitoring, fg(Green, "●mon "), "·mon "),
either(track.sequencer.recording, fg(Red, "●rec "), "·rec "),
either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "),
)))),
iter_south(1, ||track.sequencer.midi_ins.iter(),
|port, index|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
w_full(origin_w(format!("·i{index:02} {}", port.port_name())))))))));
}
Ok(XYWH(0, 0, 0, 0))
});
view_track_row_section(theme, button_2("i", "nput", false), button_2("I", "+", false),
bg(theme.darker.term, origin_w(content)))
@ -522,9 +538,9 @@ pub trait HasTrack: AsRefOpt<Track> + AsMutOpt<Track> {
impl HasSceneScroll for App { fn scene_scroll (&self) -> usize { self.project.scene_scroll() } }
impl HasSceneScroll for Arrangement { fn scene_scroll (&self) -> usize { self.scene_scroll } }
impl ScenesView for App {
fn w_mid (&self) -> u16 { (self.measure_width() as u16).saturating_sub(self.w_side()) }
fn w_mid (&self) -> u16 { (self.size.w() as u16).saturating_sub(self.w_side()) }
fn w_side (&self) -> u16 { 20 }
fn h_scenes (&self) -> u16 { (self.measure_height() as u16).saturating_sub(20) }
fn h_scenes (&self) -> u16 { (self.size.h() as u16).saturating_sub(20) }
}
impl Scene {
/// Returns the pulse length of the longest clip in the scene
@ -780,17 +796,17 @@ impl Arrangement {
}
impl ScenesView for Arrangement {
fn h_scenes (&self) -> u16 {
(self.measure_height() as u16).saturating_sub(20)
(self.size.h() as u16).saturating_sub(20)
}
fn w_side (&self) -> u16 {
(self.measure_width() as u16 * 2 / 10).max(20)
(self.size.w() as u16 * 2 / 10).max(20)
}
fn w_mid (&self) -> u16 {
(self.measure_width() as u16).saturating_sub(2 * self.w_side()).max(40)
(self.size.width() as u16).saturating_sub(2 * self.w_side()).max(40)
}
}
impl HasClipsSize for Arrangement {
fn clips_size (&self) -> &[AtomicUsize; 2] { &self.size_inner }
fn clips_size (&self) -> &Size { &self.size_inner }
}
pub type SceneWith<'a, T> =