use origin/align methods

This commit is contained in:
i do not exist 2026-07-10 18:24:56 +03:00
parent d8a767326c
commit ae75019d97
4 changed files with 104 additions and 109 deletions

View file

@ -73,8 +73,8 @@ fn tek_draw_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Drawn<u16
pub fn draw_meter_section (to: &mut Tui, mut frags: std::str::Split<&str>) -> Drawn<u16> { pub fn draw_meter_section (to: &mut Tui, mut frags: std::str::Split<&str>) -> Drawn<u16> {
match frags.next() { match frags.next() {
Some("input") => bg(Rgb(30, 30, 30), align_s("Input Meters").full_h()).draw(to), Some("input") => bg(Rgb(30, 30, 30), "Input Meters".align_s().full_h()).draw(to),
Some("output") => bg(Rgb(30, 30, 30), align_s("Output Meters").full_h()).draw(to), Some("output") => bg(Rgb(30, 30, 30), "Output Meters".align_s().full_h()).draw(to),
_ => panic!() _ => panic!()
} }
} }
@ -83,9 +83,9 @@ pub fn draw_tracks (to: &mut Tui, mut frags: std::str::Split<&str>, state: &App)
match frags.next() { match frags.next() {
None => "TODO tracks".draw(to), None => "TODO tracks".draw(to),
Some("names") => state.project.view_track_names(state.color.clone()).draw(to),//bg(Rgb(40, 40, 40), full_w(align_w("Track Names")))), Some("names") => state.project.view_track_names(state.color.clone()).draw(to),//bg(Rgb(40, 40, 40), full_w(align_w("Track Names")))),
Some("inputs") => bg(Rgb(40, 40, 40), align_w("Track Inputs").full_w()).draw(to), Some("inputs") => bg(Rgb(40, 40, 40), "Track Inputs".align_w().full_w()).draw(to),
Some("devices") => bg(Rgb(40, 40, 40), align_w("Track Devices").full_w()).draw(to), Some("devices") => bg(Rgb(40, 40, 40), "Track Devices".align_w().full_w()).draw(to),
Some("outputs") => bg(Rgb(40, 40, 40), align_w("Track Outputs").full_w()).draw(to), Some("outputs") => bg(Rgb(40, 40, 40), "Track Outputs".align_w().full_w()).draw(to),
_ => panic!() _ => panic!()
} }
} }
@ -108,7 +108,7 @@ pub fn draw_dialog (
for (index, MenuItem(item, _)) in items.0.iter().enumerate() { for (index, MenuItem(item, _)) in items.0.iter().enumerate() {
let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) }; let f = if *selected == index { Rgb(240,200,180) } else { Rgb(200, 200, 200) };
let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) }; let b = if *selected == index { Rgb(80, 80, 50) } else { Rgb(30, 30, 30) };
fg_bg(f, b, align_n(item.full_w()).exact_h(2)) fg_bg(f, b, item.full_w().align_w().exact_h(2))
.push_y((2 * index) as u16).draw(to)?; .push_y((2 * index) as u16).draw(to)?;
} }
Ok(Some(to.area().into())) Ok(Some(to.area().into()))
@ -130,9 +130,9 @@ pub fn draw_templates (to: &mut Tui, frags: std::str::Split<&str>, state: &App)
let info = profile.info.get(0).map(|x|x.as_ref()).unwrap_or("<no info>"); let info = profile.info.get(0).map(|x|x.as_ref()).unwrap_or("<no info>");
let fg1 = Rgb(224, 192, 128); let fg1 = Rgb(224, 192, 128);
let fg2 = Rgb(224, 128, 32); let fg2 = Rgb(224, 128, 32);
let field_name = align_w(fg(fg1, name)).full_w(); let field_name = fg(fg1, name).align_w().full_w();
let field_id = align_e(fg(fg2, id)).full_w(); let field_id = fg(fg2, id).align_e().full_w();
let field_info = align_w(info).full_w(); let field_info = info.align_w().full_w();
let _ = bg(b, south(above(field_name, field_id), field_info)) let _ = bg(b, south(above(field_name, field_id), field_info))
.full_w().exact_h(2).push_y((2 * index) as u16).draw(to); .full_w().exact_h(2).push_y((2 * index) as u16).draw(to);
index += 1; index += 1;
@ -162,12 +162,12 @@ pub fn view_logo () -> impl Draw<Tui> {
pub fn view_transport (play: bool, bpm: &str, beat: &str, time: &str) -> impl Draw<Tui> { pub fn view_transport (play: bool, bpm: &str, beat: &str, time: &str) -> impl Draw<Tui> {
let theme = ItemTheme::G[96]; let theme = ItemTheme::G[96];
bg(Black, east!(above( bg(Black, east!(above(
align_w(button_play_pause(play, false)).full_wh(), button_play_pause(play, false).align_w().full_wh(),
align_e(east!( east!(
field_h(theme, "BPM", bpm), field_h(theme, "BPM", bpm),
field_h(theme, "Beat", beat), field_h(theme, "Beat", beat),
field_h(theme, "Time", time), field_h(theme, "Time", time),
)).full_wh() ).align_e().full_wh()
))) )))
} }
@ -182,8 +182,8 @@ pub fn view_status (sel: Option<&str>, sr: &str, buf: &str, lat: &str) -> impl D
let buf = field_h(theme, "Buf", buf); let buf = field_h(theme, "Buf", buf);
let lat = field_h(theme, "Lat", lat); let lat = field_h(theme, "Lat", lat);
bg(Black, east!(above( bg(Black, east!(above(
align_w(sel.map(|sel|field_h(theme, "Selected", sel))).full_wh(), sel.map(|sel|field_h(theme, "Selected", sel)).align_w().full_wh(),
align_e(east!(sr, buf, lat)).full_wh(), east!(sr, buf, lat).align_e().full_wh(),
))) )))
} }
@ -215,10 +215,10 @@ pub fn button_play_pause (playing: bool, compact: bool) -> impl Draw<Tui> {
content: impl Draw<Tui>, content: impl Draw<Tui>,
) -> impl Draw<Tui> { ) -> impl Draw<Tui> {
west( west(
align_nw(button_add).exact_w(4).full_h(), button_add.align_nw().exact_w(4).full_h(),
east( east(
align_nw(button).full_h().exact_w(20), button.align_nw().full_h().exact_w(20),
align_c(content).full_wh() content.align_c().full_wh()
) )
) )
} }
@ -286,12 +286,12 @@ pub fn view_sample_info_v (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tu
let sample = sample.unwrap().read().unwrap(); let sample = sample.unwrap().read().unwrap();
let theme = sample.color; let theme = sample.color;
south!( south!(
align_w(field_h(theme, "Name ", format!("{:<10}", sample.name.clone()))).full_w(), field_h(theme, "Name ", format!("{:<10}", sample.name.clone())) .align_w().full_w(),
align_w(field_h(theme, "Length", format!("{:<8}", sample.channels[0].len()))).full_w(), field_h(theme, "Length", format!("{:<8}", sample.channels[0].len())).align_w().full_w(),
align_w(field_h(theme, "Start ", format!("{:<8}", sample.start))).full_w(), field_h(theme, "Start ", format!("{:<8}", sample.start)) .align_w().full_w(),
align_w(field_h(theme, "End ", format!("{:<8}", sample.end))).full_w(), field_h(theme, "End ", format!("{:<8}", sample.end)) .align_w().full_w(),
align_w(field_h(theme, "Trans ", "0")).full_w(), field_h(theme, "Trans ", "0") .align_w().full_w(),
align_w(field_h(theme, "Gain ", format!("{}", sample.gain))).full_w(), field_h(theme, "Gain ", format!("{}", sample.gain)) .align_w().full_w(),
).exact_w(20).draw(to) ).exact_w(20).draw(to)
}); });
@ -314,7 +314,7 @@ pub fn view_sample_status (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tu
} }
pub fn view_track_header (theme: ItemTheme, content: impl Draw<Tui>) -> impl Draw<Tui> { pub fn view_track_header (theme: ItemTheme, content: impl Draw<Tui>) -> impl Draw<Tui> {
bg(theme.darker.term, align_e(content).full_w()).exact_w(12) bg(theme.darker.term, content.align_e().full_w()).exact_w(12)
} }
pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, ports: &'a [T]) pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, ports: &'a [T])
@ -323,7 +323,7 @@ pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, po
let ins = ports.len() as u16; let ins = ports.len() as u16;
let frame = Outer(true, Style::default().fg(g(96))); let frame = Outer(true, Style::default().fg(g(96)));
let iter = move||ports.iter(); let iter = move||ports.iter();
let names = iter_south(iter, move|port, index|align_w(format!(" {index} {}", port.port_name())).full_h()); let names = iter_south(iter, move|port, index|format!(" {index} {}", port.port_name()).align_w().full_h());
let field = field_v(theme, title, names); let field = field_v(theme, title, names);
border(true, frame, field.exact_wh(20, 1 + ins)).exact_wh(20, 1 + ins) border(true, frame, field.exact_wh(20, 1 + ins)).exact_wh(20, 1 + ins)
} }
@ -334,9 +334,9 @@ pub fn view_io_ports <'a, T: PortsSizes<'a>> (
type Item<'a> = (usize, &'a Arc<str>, &'a [Connect], usize, usize); type Item<'a> = (usize, &'a Arc<str>, &'a [Connect], usize, usize);
iter(items, iter(items,
move|(_index, name, connections, y, y2): Item<'a>, _| south( move|(_index, name, connections, y, y2): Item<'a>, _| south(
bold(true, fg_bg(fg, bg, align_w(east(" 󰣲 ", name)))).full_h(), bold(true, fg_bg(fg, bg, east(" 󰣲 ", name).align_w())).full_h(),
iter(||connections.iter(), move|connect: &'a Connect, index|{ iter(||connections.iter(), move|connect: &'a Connect, index|{
align_w(bold(false, fg_bg(fg, bg, &connect.info)).exact_h(1)).push_y(index as u16) bold(false, fg_bg(fg, bg, &connect.info)).exact_h(1).align_w().push_y(index as u16)
}) })
).exact_h((y2 - y) as u16).push_y(y as u16)) ).exact_h((y2 - y) as u16).push_y(y as u16))
} }
@ -349,7 +349,7 @@ pub fn view_scenes_clips <'a, S: ScenesSizes<'a>> (
size: &Sizer, size: &Sizer,
editing: bool, editing: bool,
) -> impl Draw<Tui> { ) -> impl Draw<Tui> {
let status = align_se(fg(Green, format!("{}x{}", size.w(), size.h()))).full_wh(); let status = fg(Green, format!("{}x{}", size.w(), size.h())).align_se().full_wh();
let tracks = iter_once(tracks, move|(track_index, track, _, _), _| { let tracks = iter_once(tracks, move|(track_index, track, _, _), _| {
let scenes = iter_once(scenes(), move|(scene_index, scene, _, _), _| { let scenes = iter_once(scenes(), move|(scene_index, scene, _, _), _| {
let (name, theme): (Arc<str>, ItemTheme) = scene_name_theme(scene, track_index); let (name, theme): (Arc<str>, ItemTheme) = scene_name_theme(scene, track_index);
@ -363,7 +363,7 @@ pub fn view_scenes_clips <'a, S: ScenesSizes<'a>> (
below( below(
below( below(
fg_bg(o, b, "".full_wh()), fg_bg(o, b, "".full_wh()),
align_nw(fg_bg(f, b, bold(true, name))).full_wh(), fg_bg(f, b, bold(true, name)).align_nw().full_wh(),
), ),
when(is_selected, editor.map(|e|e.view())).full_wh() when(is_selected, editor.map(|e|e.view())).full_wh()
).full_wh() ).full_wh()
@ -446,10 +446,10 @@ pub fn view_track_names (
} else { } else {
track.color.base.term track.color.base.term
}; };
bg(b, south(align_nw(east( bg(b, south(east(
format!("·t{index:02} "), format!("·t{index:02} "),
fg(Rgb(255, 255, 255), bold(true, &track.name)) fg(Rgb(255, 255, 255), bold(true, &track.name))
)).full_w(), "")) ).align_nw().full_w(), ""))
.exact_w(track_width(index, track)) .exact_w(track_width(index, track))
.push_x(x1 as u16) .push_x(x1 as u16)
.draw(to)?; .draw(to)?;
@ -462,50 +462,49 @@ pub fn view_track_outputs (
theme: ItemTheme, tracks: impl TracksSizes<'_>, midi_outs: impl Iterator<Item = &MidiOutput>, theme: ItemTheme, tracks: impl TracksSizes<'_>, midi_outs: impl Iterator<Item = &MidiOutput>,
) -> impl Draw<Tui> { ) -> impl Draw<Tui> {
view_track_row_section(theme, view_track_row_section(theme,
south(align_w(button_2("o", "utput", false)).full_w(), south(button_2("o", "utput", false).align_w().full_w(),
thunk(|to: &mut Tui|{ thunk(|to: &mut Tui|{
for port in midi_outs { for port in midi_outs {
align_w(port.port_name()).full_w().draw(to); port.port_name().align_w().full_w().draw(to);
} }
Ok(Some(XYWH(0, 0, 0, 0))) Ok(Some(XYWH(0, 0, 0, 0)))
})), })),
button_2("O", "+", false), button_2("O", "+", false),
bg(theme.darker.term, align_w(thunk(|to: &mut Tui|{ bg(theme.darker.term, thunk(|to: &mut Tui|{
for (index, track, _x1, _x2) in tracks { for (index, track, _x1, _x2) in tracks {
let f = Rgb(255, 255, 255); let f = Rgb(255, 255, 255);
let b = track.color.dark.term; let b = track.color.dark.term;
let iter = ||track.sequencer.midi_outs.iter(); let iter = ||track.sequencer.midi_outs.iter();
let draw = |port: &MidiOutput, _|fg(f, bg(b, align_w( let draw = |port: &MidiOutput, _|fg(f, bg(b,
format!("·o{index:02} {}", port.port_name()).full_w() format!("·o{index:02} {}", port.port_name()).full_w().align_w()).exact_h(1));
)).exact_h(1)); iter_south(iter, draw).full_h().align_nw()
align_nw(iter_south(iter, draw).full_h())
.exact_w(track_width(index, track)) .exact_w(track_width(index, track))
.draw(to)?; .draw(to)?;
} }
Ok(Some(XYWH(0, 0, 0, 0))) Ok(Some(XYWH(0, 0, 0, 0)))
})))) }).align_w()))
} }
pub fn view_track_inputs ( pub fn view_track_inputs (
theme: ItemTheme, tracks: impl TracksSizes<'_>, height: u16, theme: ItemTheme, tracks: impl TracksSizes<'_>, height: u16,
) -> impl Draw<Tui> { ) -> impl Draw<Tui> {
view_track_row_section(theme, button_2("i", "nput", false), button_2("I", "+", false), view_track_row_section(theme, button_2("i", "nput", false), button_2("I", "+", false),
bg(theme.darker.term, align_w(thunk(move|to: &mut Tui|{ bg(theme.darker.term, thunk(move|to: &mut Tui|{
for (index, track, _x1, _x2) in tracks { for (index, track, _x1, _x2) in tracks {
align_nw(south( south(
bg(track.color.base.term, bg(track.color.base.term,
align_w(east!( east!(
either(track.sequencer.monitoring, fg(Green, "●mon "), "·mon "), either(track.sequencer.monitoring, fg(Green, "●mon "), "·mon "),
either(track.sequencer.recording, fg(Red, "●rec "), "·rec "), either(track.sequencer.recording, fg(Red, "●rec "), "·rec "),
either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "), either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "),
)).full_w()), ).align_w().full_w()),
iter_south(||track.sequencer.midi_ins.iter(), iter_south(||track.sequencer.midi_ins.iter(),
|port, _|fg_bg(Rgb(255, 255, 255), track.color.dark.term, |port, _|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
align_w(format!("·i{index:02} {}", port.port_name())).full_w())) format!("·i{index:02} {}", port.port_name()).align_w().full_w()))
)).exact_wh(track_width(index, track), height + 1).draw(to)?; ).align_nw().exact_wh(track_width(index, track), height + 1).draw(to)?;
} }
Ok(Some(XYWH(0, 0, 0, 0))) Ok(Some(XYWH(0, 0, 0, 0)))
})))) }).align_w()))
} }
pub fn view_scenes_names ( pub fn view_scenes_names (
@ -534,18 +533,17 @@ pub fn view_scene_name (
} else { } else {
H_SCENE as u16 H_SCENE as u16
}; };
let a = align_w(east(format!("·s{index:02} "), let a = east(format!("·s{index:02} "),
fg(g(255), bold(true, &scene.name)))).full_w(); fg(g(255), bold(true, &scene.name))).align_w().full_w();
let b = when(select.scene() == Some(index) && editing, align_nw(south( let b = when(select.scene() == Some(index) && editing, south(
editor.as_ref().map(|e|e.clip_status()), editor.as_ref().map(|e|e.clip_status()),
editor.as_ref().map(|e|e.edit_status()))).full_wh()); editor.as_ref().map(|e|e.edit_status())).align_nw().full_wh());
let c = if select.scene() == Some(index) { let c = if select.scene() == Some(index) {
scene.color.light.term scene.color.light.term
} else { } else {
scene.color.base.term scene.color.base.term
}; };
bg(c, align_nw(south(a, b))) bg(c, south(a, b).align_nw()).exact_wh(20, h)
.exact_wh(20, h)
} }
pub fn view_midi_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw<Tui> { pub fn view_midi_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw<Tui> {
@ -582,31 +580,31 @@ pub fn view_per_track () -> impl Draw<Tui> {}
pub fn view_per_track_top () -> impl Draw<Tui> {} pub fn view_per_track_top () -> impl Draw<Tui> {}
pub fn view_inputs (tracks: impl TracksSizes<'_>, midi_ins: &[MidiInput]) -> impl Draw<Tui> { pub fn view_inputs (tracks: impl TracksSizes<'_>, midi_ins: &[MidiInput]) -> impl Draw<Tui> {
let title_1 = align_w(button_3("i", "nput ", format!("{}", midi_ins.len()), false)).exact_wh(20, 1); let title_1 = button_3("i", "nput ", format!("{}", midi_ins.len()), false).align_w().exact_wh(20, 1);
let title_2 = button_2("I", "+", false).exact_wh(4, 1); let title_2 = button_2("I", "+", false).exact_wh(4, 1);
east(title_1, west(title_2, thunk(move|to: &mut Tui|{ east(title_1, west(title_2, thunk(move|to: &mut Tui|{
for (_index, track, x1, _x2) in tracks { for (_index, track, x1, _x2) in tracks {
south( south(
bg(track.color.dark.term, align_w(east!( bg(track.color.dark.term, east!(
either(track.sequencer.monitoring, fg(Green, "mon "), "mon "), either(track.sequencer.monitoring, fg(Green, "mon "), "mon "),
either(track.sequencer.recording, fg(Red, "rec "), "rec "), either(track.sequencer.recording, fg(Red, "rec "), "rec "),
either(track.sequencer.overdub, fg(Yellow, "dub "), "dub "), either(track.sequencer.overdub, fg(Yellow, "dub "), "dub "),
).exact_w(track.width as u16))).push_x(x1 as u16), ).exact_w(track.width as u16)).align_w().push_x(x1 as u16),
thunk(move |to: &mut Tui|{ thunk(move |to: &mut Tui|{
for (index, port) in midi_ins.iter().enumerate() { for (index, port) in midi_ins.iter().enumerate() {
east( east(
align_w(east( east(
"", "",
bold(true, fg(Rgb(255,255,255), port.port_name())) bold(true, fg(Rgb(255,255,255), port.port_name()))
)).exact_w(20), ).align_w().exact_w(20),
west( west(
().exact_w(4), ().exact_w(4),
thunk(move|to: &mut Tui|{ thunk(move|to: &mut Tui|{
bg(track.color.darker.term, align_w(east!( bg(track.color.darker.term, east!(
either(track.sequencer.monitoring, fg(Green, ""), " · "), either(track.sequencer.monitoring, fg(Green, ""), " · "),
either(track.sequencer.recording, fg(Red, ""), " · "), either(track.sequencer.recording, fg(Red, ""), " · "),
either(track.sequencer.overdub, fg(Yellow, ""), " · "), either(track.sequencer.overdub, fg(Yellow, ""), " · "),
).exact_w(track.width as u16))).draw(to); ).exact_w(track.width as u16).align_w()).draw(to);
todo!() todo!()
})) }))
).push_x(index as u16 * 10).exact_h(1).draw(to); ).push_x(index as u16 * 10).exact_h(1).draw(to);
@ -627,38 +625,37 @@ pub fn view_outputs (
) -> impl Draw<Tui> { ) -> impl Draw<Tui> {
let list = south( let list = south(
align_w(button_3( button_3(
"o", "utput", format!("{}", midi_outs.len()), false "o", "utput", format!("{}", midi_outs.len()), false
)).full_w().exact_h(1), ).align_w().full_w().exact_h(1),
align_nw(thunk(|to: &mut Tui|{ thunk(|to: &mut Tui|{
for (_index, port) in midi_outs.iter().enumerate() { for (_index, port) in midi_outs.iter().enumerate() {
east( east(
align_w(east("", fg(Rgb(255,255,255), bold(true, port.port_name())))), east("", fg(Rgb(255,255,255), bold(true, port.port_name()))).align_w(),
align_e(format!("{}/{} ", format!("{}/{} ",
port.port().get_connections().len(), port.port().get_connections().len(),
port.connections.len()) port.connections.len()).align_e().full_w().exact_h(1)).full_w().draw(to)?;
).full_w().exact_h(1)).full_w().draw(to)?;
for (index, conn) in port.connections.iter().enumerate() { for (index, conn) in port.connections.iter().enumerate() {
align_w(format!(" c{index:02}{}", conn.info())).full_w().exact_h(1).draw(to)?; format!(" c{index:02}{}", conn.info()).align_w().full_w().exact_h(1).draw(to)?;
} }
} }
todo!(); todo!();
})).full_wh().exact_h(height - 1) }).align_nw().full_wh().exact_h(height - 1)
); );
view_track_row_section(theme, list, button_2("O", "+", false), view_track_row_section(theme, list, button_2("O", "+", false),
bg(theme.darker.term, align_w(thunk(|to: &mut Tui|{ bg(theme.darker.term, thunk(|to: &mut Tui|{
for (index, track, _x1, _x2) in tracks { for (index, track, _x1, _x2) in tracks {
thunk(|to: &mut Tui|{ thunk(|to: &mut Tui|{
align_w(east( east(
either(true, fg(Green, "play "), "play "), either(true, fg(Green, "play "), "play "),
either(false, fg(Yellow, "solo "), "solo "), either(false, fg(Yellow, "solo "), "solo "),
)).exact_h(1).draw(to)?; ).align_w().exact_h(1).draw(to)?;
for (_index, port) in midi_outs.iter().enumerate() { for (_index, port) in midi_outs.iter().enumerate() {
align_w(east( east(
either(true, fg(Green, ""), " · "), either(true, fg(Green, ""), " · "),
either(false, fg(Yellow, ""), " · "), either(false, fg(Yellow, ""), " · "),
)).exact_h(1).draw(to)?; ).align_w().exact_h(1).draw(to)?;
for (_index, _conn) in port.connections.iter().enumerate() { for (_index, _conn) in port.connections.iter().enumerate() {
"".full_w().exact_h(1).draw(to)?; "".full_w().exact_h(1).draw(to)?;
} }
@ -667,7 +664,7 @@ pub fn view_outputs (
}).exact_w(track_width(index, track)).draw(to); }).exact_w(track_width(index, track)).draw(to);
} }
todo!() todo!()
}).full_w()))).exact_h(height) }).align_w().full_w())).exact_h(height)
} }
pub fn view_track_devices ( pub fn view_track_devices (
@ -681,13 +678,13 @@ pub fn view_track_devices (
button_2("D", "+", false), button_2("D", "+", false),
iter_once(tracks, move|(_, track, _x1, _x2), index|bg( iter_once(tracks, move|(_, track, _x1, _x2), index|bg(
track.color.dark.term, track.color.dark.term,
align_nw(iter_south(move||0..h, iter_south(move||0..h,
|_, _index|fg_bg( |_, _index|fg_bg(
ItemTheme::G[32].lightest.term, ItemTheme::G[32].lightest.term,
ItemTheme::G[32].dark.term, ItemTheme::G[32].dark.term,
align_nw(format!(" · {}", "--")) format!(" · {}", "--").align_nw()
).exact_wh(track.width as u16, 2) ).exact_wh(track.width as u16, 2)
))).exact_wh( ).align_nw()).exact_wh(
Some(track_width(index, track)), Some(track_width(index, track)),
Some(h + 1), Some(h + 1),
))) )))
@ -697,21 +694,21 @@ pub fn per_track <'a, T: Draw<Tui> + 'a, U: TracksSizes<'a>> (
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 {
per_track_top(tracks, move|index, track|align_y(callback(index, track).full_h())) per_track_top(tracks, move|index, track|callback(index, track).full_h().align_y())
} }
pub fn per_track_top <'a, T: Draw<Tui> + 'a, U: TracksSizes<'a>> ( pub fn per_track_top <'a, T: Draw<Tui> + 'a, U: TracksSizes<'a>> (
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 {
align_x(bg(Reset, iter_east(tracks, 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), _|{
fg_bg( fg_bg(
track.color.lightest.term, track.color.lightest.term,
track.color.base.term, track.color.base.term,
callback(index, track) callback(index, track)
).exact_w((x2 - x1) as u16) ).exact_w((x2 - x1) as u16)
}))) }).align_x())
} }
pub fn field_h <T: Screen> (theme: ItemTheme, head: impl Draw<T>, body: impl Draw<T>) -> impl Draw<T> { pub fn field_h <T: Screen> (theme: ItemTheme, head: impl Draw<T>, body: impl Draw<T>) -> impl Draw<T> {
@ -729,14 +726,14 @@ pub fn view_sessions () -> impl Draw<Tui> {
let b = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) }; let b = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) };
let y = (2 * index) as u16; let y = (2 * index) as u16;
let h = 2; let h = 2;
bg(b, align_w(fg(f, *name))).full_w().exact_h(h).push_y(y).draw(to)?; bg(b, fg(f, *name).align_w()).full_w().exact_h(h).push_y(y).draw(to)?;
} }
Ok(Some(to.area().into())) Ok(Some(to.area().into()))
}).min_w(w).exact_h(h) }).min_w(w).exact_h(h)
} }
pub fn view_browse_title (state: &App) -> impl Draw<Tui> { pub fn view_browse_title (state: &App) -> impl Draw<Tui> {
align_w(field_v(ItemTheme::default(), field_v(ItemTheme::default(),
match state.dialog.browser_target().unwrap() { match state.dialog.browser_target().unwrap() {
BrowseTarget::SaveProject => "Save project:", BrowseTarget::SaveProject => "Save project:",
BrowseTarget::LoadProject => "Load project:", BrowseTarget::LoadProject => "Load project:",
@ -745,7 +742,7 @@ pub fn view_browse_title (state: &App) -> impl Draw<Tui> {
BrowseTarget::ImportClip(_) => "Import clip:", BrowseTarget::ImportClip(_) => "Import clip:",
BrowseTarget::ExportClip(_) => "Export clip:", BrowseTarget::ExportClip(_) => "Export clip:",
}, fg(g(96), x_repeat("🭻")).exact_h(1) }, fg(g(96), x_repeat("🭻")).exact_h(1)
)).full_w() ).align_w().full_w()
} }
pub fn view_device (state: &App) -> impl Draw<Tui> { pub fn view_device (state: &App) -> impl Draw<Tui> {

View file

@ -241,7 +241,7 @@ impl<'a> PoolView<'a> {
//let on_bg = |x|x;//below(Repeat(" "), bg(color.darkest.term, x)); //let on_bg = |x|x;//below(Repeat(" "), bg(color.darkest.term, x));
//let border = |x|x;//Outer(Style::default().fg(color.dark.term).bg(color.darkest.term)).enclose(x); //let border = |x|x;//Outer(Style::default().fg(color.dark.term).bg(color.darkest.term)).enclose(x);
//let height = pool.clips.read().unwrap().len() as u16; //let height = pool.clips.read().unwrap().len() as u16;
origin_n(iter( iter(
||pool.clips().clone().into_iter(), ||pool.clips().clone().into_iter(),
move|clip: Arc<RwLock<MidiClip>>, i: usize|{ move|clip: Arc<RwLock<MidiClip>>, i: usize|{
let MidiClip { ref name, color, length, .. } = *clip.read().unwrap(); let MidiClip { ref name, color, length, .. } = *clip.read().unwrap();
@ -253,12 +253,12 @@ impl<'a> PoolView<'a> {
let name = if false { format!(" {i:>3}") } else { format!(" {i:>3} {name}") }; let name = if false { format!(" {i:>3}") } else { format!(" {i:>3} {name}") };
let length = if false { String::default() } else { format!("{length} ") }; let length = if false { String::default() } else { format!("{length} ") };
bg(b, below!( bg(b, below!(
origin_w(fg(f, bold(selected, name))).full_w(), fg(f, bold(selected, name)).origin_w().full_w(),
origin_e(fg(f, bold(selected, length))).full_w(), fg(f, bold(selected, length)).origin_e().full_w(),
origin_w(when(selected, bold(true, fg(g(255), "")))).full_w(), when(selected, bold(true, fg(g(255), ""))).origin_w().full_w(),
origin_e(when(selected, bold(true, fg(g(255), "")))).full_w(), when(selected, bold(true, fg(g(255), ""))).origin_e().full_w(),
)).exact_h(1) )).exact_h(1)
})).full_h().exact_w(20) }).origin_n().full_h().exact_w(20)
} }
} }
@ -315,15 +315,16 @@ impl Browse {
impl Browse { impl Browse {
fn tui (&self) -> impl Draw<Tui> { fn tui (&self) -> impl Draw<Tui> {
let item = |entry, _index|origin_w(entry).full_w(); iter_south_fixed(1, ||self.tui_entries(), |entry, _index|entry.origin_w().full_w())
let iterate = ||EntriesIterator { }
fn tui_entries (&self) -> EntriesIterator<Tui> {
EntriesIterator {
offset: 0, offset: 0,
index: 0, index: 0,
length: self.dirs.len() + self.files.len(), length: self.dirs.len() + self.files.len(),
browser: self, browser: self,
_screen: Default::default(), _screen: Default::default(),
}; }
iter_south_fixed(1, iterate, item)
} }
} }

View file

@ -99,12 +99,12 @@ 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) };
south!( south!(
origin_w(east(button_2("f2", "name ", false), east(button_2("f2", "name ", false), fg(Rgb(255, 255, 255), format!("{name} "))
origin_e(fg(Rgb(255, 255, 255), format!("{name} "))).full_w())).full_w(), .origin_e().full_w()).origin_w().full_w(),
origin_w(east(button_2("l", "ength ", false), east(button_2("l", "ength ", false), fg(Rgb(255, 255, 255), format!("{length} ")).origin_e().full_w())
origin_e(fg(Rgb(255, 255, 255), format!("{length} "))).full_w())).full_w(), .origin_w().full_w(),
origin_w(east(button_2("r", "epeat ", false), east(button_2("r", "epeat ", false), fg(Rgb(255, 255, 255), format!("{looped} ")).origin_e().full_w())
origin_e(fg(Rgb(255, 255, 255), format!("{looped} "))).full_w())).full_w(), .origin_w().full_w(),
).exact_w(20) ).exact_w(20)
} }
pub fn edit_status (&self) -> impl Draw<Tui> + '_ { pub fn edit_status (&self) -> impl Draw<Tui> + '_ {
@ -119,15 +119,12 @@ 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());
south!( south!(
origin_w(east(button_2("t", "ime ", false), east(button_2("t", "ime ", false),
origin_e(fg(Rgb(255, 255, 255), fg(Rgb(255, 255, 255), format!("{length} /{time_zoom} +{time_pos} ")).origin_e().full_w()).origin_w().full_w(),
format!("{length} /{time_zoom} +{time_pos} "))).full_w())).full_w(), east(button_2("z", "lock ", false),
origin_w(east(button_2("z", "lock ", false), fg(Rgb(255, 255, 255), format!("{time_lock}")).origin_e().full_w()).origin_w().full_w(),
origin_e(fg(Rgb(255, 255, 255), east(button_2("x", "note ", false),
format!("{time_lock}"))).full_w())).full_w(), fg(Rgb(255, 255, 255), format!("{note_name} {note_pos} {note_len}")).origin_e().full_w()).origin_w().full_w(),
origin_w(east(button_2("x", "note ", false),
origin_e(fg(Rgb(255, 255, 255),
format!("{note_name} {note_pos} {note_len}"))).full_w())).full_w(),
).exact_w(20) ).exact_w(20)
} }
} }

2
tengri

@ -1 +1 @@
Subproject commit 09463649c673b0d883ca18746a36aa86c6bd114f Subproject commit 13c886d9e05a8df712461d44025196ae9be51b78