update for unowned draw
Some checks failed
/ build (push) Has been cancelled

This commit is contained in:
i do not exist 2026-08-04 12:24:39 +03:00
parent 8de62463c0
commit a938b68980
5 changed files with 262 additions and 336 deletions

View file

@ -439,10 +439,18 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + HasClipsSize +
fn w_mid (&self) -> u16;
fn view_scenes_names (&self) -> impl Draw<Tui> {
view_scenes_names(
self.scenes_with_sizes(), self.selection(), self.editor(), self.is_editing()
)
let select = self.selection();
let editor = self.editor();
let editing = self.is_editing();
draw(move |to: &mut Tui|{
for (index, scene, ..) in self.scenes_with_sizes() {
view_scene_name(select, editor, index, scene, editing).draw(to)?;
}
Ok(Some(XYWH(1, 1, 1, 1)))
})
.exact_w(20)
}
fn scenes_with_sizes (&self) -> impl ScenesSizes<'_> {
let mut y = 0;
self.scenes().iter().enumerate().skip(self.scene_scroll()).map_while(move|(s, scene)|{
@ -733,23 +741,84 @@ pub trait HasTrackScroll: HasTracks {
pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
/// Draw name of each track
fn view_track_names (&self, theme: ItemTheme) -> impl Draw<Tui> {
view_track_names(
theme, self.tracks_with_sizes(), self.tracks().len(), self.scenes().len(), self.selection()
)
let track_count = self.tracks().len();
let scene_count = self.scenes().len();
let selected = self.selection();
let button = south(
button_3("t", "rack ", format!("{}{track_count}", selected.track()
.map(|track|format!("{track}/")).unwrap_or_default()), false),
button_3("s", "cene ", format!("{}{scene_count}", selected.scene()
.map(|scene|format!("{scene}/")).unwrap_or_default()), false));
let button_2 = south(
button_2("T", "+", false),
button_2("S", "+", false));
view_track_row_section(theme, button, button_2, bg(theme.darker.term,
draw(|to: &mut Tui|{
for (index, track, x1, _x2) in self.tracks_with_sizes() {
let b = if selected.track() == Some(index) {
track.color.light.term
} else {
track.color.base.term
};
bg(b, south(east(
format!("·t{index:02} "),
fg(Rgb(255, 255, 255), bold(true, &track.name))
).align_nw().full_w(), ""))
.exact_w(track_width(index, track))
.push_x(x1 as u16)
.draw(to)?;
}
Ok(Some(XYWH(0, 0, 0, 0)))
}).exact_h(2)))
}
/// Draw outputs per track
fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw<Tui> {
view_track_outputs(
theme, self.tracks_with_sizes(), self.midi_outs().iter()
)
view_track_row_section(theme,
south(button_2("o", "utput", false).align_w().full_w(),
draw(|to: &mut Tui|{
for port in self.midi_outs().iter() {
let _ = port.port_name().align_w().full_w().draw(to)?;
}
Ok(Some(XYWH(0, 0, 0, 0)))
})),
button_2("O", "+", false),
bg(theme.darker.term, draw(|to: &mut Tui|{
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
let f = Rgb(255, 255, 255);
let b = track.color.dark.term;
let iter = ||track.sequencer.midi_outs.iter();
let draw = |port: &MidiOutput, _|fg(f, bg(b,
format!("·o{index:02} {}", port.port_name()).full_w().align_w()).exact_h(1));
iter_south(iter, draw).full_h().align_nw()
.exact_w(track_width(index, track))
.draw(to)?;
}
Ok(Some(XYWH(0, 0, 0, 0)))
}).align_w()))
}
/// Draw inputs per track
fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<Tui> {
let mut h = 0u16;
let mut height = 0u16;
for track in self.tracks().iter() {
h = h.max(track.sequencer.midi_ins.len() as u16);
height = height.max(track.sequencer.midi_ins.len() as u16);
}
view_track_inputs(theme, self.tracks_with_sizes(), h)
view_track_row_section(theme, button_2("i", "nput", false), button_2("I", "+", false),
bg(theme.darker.term, draw(move|to: &mut Tui|{
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
south(
bg(track.color.base.term,
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 "),
).align_w().full_w()),
iter_south(||track.sequencer.midi_ins.iter(),
|port, _|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
format!("·i{index:02} {}", port.port_name()).align_w().full_w()))
).align_nw().exact_wh(track_width(index, track), height + 1).draw(to)?;
}
Ok(Some(XYWH(0, 0, 0, 0)))
}).align_w()))
}
/// Iterate over tracks with their corresponding sizes.
fn tracks_with_sizes (&self) -> impl TracksSizes<'_> {
@ -801,21 +870,102 @@ impl_as_mut!(Vec<Track>: |self: App| self.project.as_mut());
impl Arrangement {
pub fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
view_inputs(
self.tracks_with_sizes(), self.midi_ins().as_slice()
)
let title_1 = button_3("i", "nput ", format!("{}", self.midi_ins().len()), false).align_w().exact_wh(20, 1);
let title_2 = button_2("I", "+", false).exact_wh(4, 1);
east(title_1, west(title_2, draw(move|to: &mut Tui|{
for (_index, track, x1, _x2) in self.tracks_with_sizes() {
let _ = south(
bg(track.color.dark.term, 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 "),
).exact_w(track.width as u16)).align_w().push_x(x1 as u16),
draw(move |to: &mut Tui|{
for (index, port) in self.midi_ins().as_slice().iter().enumerate() {
let _ = east(
east(
"",
bold(true, fg(Rgb(255,255,255), port.port_name()))
).align_w().exact_w(20),
west(
().exact_w(4),
bg(track.color.darker.term, east!(
either(track.sequencer.monitoring, fg(Green, ""), " · "),
either(track.sequencer.recording, fg(Red, ""), " · "),
either(track.sequencer.overdub, fg(Yellow, ""), " · "),
).exact_w(track.width as u16).align_w())
)
).push_x(index as u16 * 10).exact_h(1).draw(to)?;
}
todo!()
})
).draw(to)?;
}
Ok(Some(to.area()))
})))
}
pub fn view_outputs (&self, theme: ItemTheme) -> impl Draw<Tui> {
view_outputs(
theme, self.tracks_with_sizes(), self.midi_outs(), self.outputs_height()
)
let height = self.outputs_height();
let list = south(
button_3(
"o", "utput", format!("{}", self.midi_outs().len()), false
).align_w().full_w().exact_h(1),
draw(|to: &mut Tui|{
for (_index, port) in self.midi_outs().iter().enumerate() {
east(
east("", fg(Rgb(255,255,255), bold(true, port.port_name()))).align_w(),
format!("{}/{} ",
port.port().get_connections().len(),
port.connections.len()).align_e().full_w().exact_h(1)).full_w().draw(to)?;
for (index, conn) in port.connections.iter().enumerate() {
format!(" c{index:02}{}", conn.info()).align_w().full_w().exact_h(1).draw(to)?;
}
}
todo!();
}).align_nw().full_wh().exact_h(height - 1)
);
view_track_row_section(theme, list, button_2("O", "+", false),
bg(theme.darker.term, draw(|to: &mut Tui|{
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
let _ = draw(|to: &mut Tui|{
east(
either(true, fg(Green, "play "), "play "),
either(false, fg(Yellow, "solo "), "solo "),
).align_w().exact_h(1).draw(to)?;
for (_index, port) in self.midi_outs().iter().enumerate() {
east(
either(true, fg(Green, ""), " · "),
either(false, fg(Yellow, ""), " · "),
).align_w().exact_h(1).draw(to)?;
for (_index, _conn) in port.connections.iter().enumerate() {
"".full_w().exact_h(1).draw(to)?;
}
}
todo!()
}).exact_w(track_width(index, track)).draw(to)?;
}
todo!()
}).align_w().full_w())).exact_h(height)
}
pub fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
view_track_devices(
theme, self.tracks_with_sizes(), self.track(), self.devices_height()
)
let height = self.devices_height();
view_track_row_section(theme,
button_3("d", "evice", format!("{}", self.track().map(|t|t.devices.len()).unwrap_or(0)), false),
button_2("D", "+", false),
iter_once(self.tracks_with_sizes(), move|(_, track, _x1, _x2), index|bg(
track.color.dark.term,
iter_south(move||0..height,
|_, _index|fg_bg(
ItemTheme::G[32].lightest.term,
ItemTheme::G[32].dark.term,
format!(" · {}", "--").align_nw()
).exact_wh(track.width as u16, 2)
).align_nw()).exact_wh(
Some(track_width(index, track)),
Some(height + 1),
)))
}
fn devices_height (&self) -> u16 {
@ -898,3 +1048,15 @@ impl HasTrackScroll for App {
pub(crate) fn track_width (_index: usize, track: &Track) -> u16 {
track.width as u16
}
/// Define a type alias for iterators of sized items (columns).
macro_rules! def_sizes_iter {
($Type:ident => $($Item:ty),+) => {
pub trait $Type<'a>: Iterator<Item=(usize, $(&'a $Item,)+ usize, usize)> + Send + Sync + 'a {}
impl<'a, T: Iterator<Item=(usize, $(&'a $Item,)+ usize, usize)> + Send + Sync + 'a> $Type<'a> for T {}
}
}
def_sizes_iter!(PortsSizes => Arc<str>, [Connect]);
def_sizes_iter!(ScenesSizes => Scene);
def_sizes_iter!(TracksSizes => Track);