From ae75019d973f689059905d84037fd7dbd9cb3bf3 Mon Sep 17 00:00:00 2001 From: i do not exist Date: Fri, 10 Jul 2026 18:24:56 +0300 Subject: [PATCH] use origin/align methods --- src/app/draw.rs | 163 +++++++++++++++++++++---------------------- src/device/browse.rs | 21 +++--- src/device/editor.rs | 27 ++++--- tengri | 2 +- 4 files changed, 104 insertions(+), 109 deletions(-) diff --git a/src/app/draw.rs b/src/app/draw.rs index f21fbba2..3c534514 100644 --- a/src/app/draw.rs +++ b/src/app/draw.rs @@ -73,8 +73,8 @@ fn tek_draw_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Drawn) -> Drawn { match frags.next() { - Some("input") => bg(Rgb(30, 30, 30), align_s("Input Meters").full_h()).draw(to), - Some("output") => bg(Rgb(30, 30, 30), align_s("Output 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), "Output Meters".align_s().full_h()).draw(to), _ => panic!() } } @@ -83,9 +83,9 @@ pub fn draw_tracks (to: &mut Tui, mut frags: std::str::Split<&str>, state: &App) match frags.next() { 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("inputs") => bg(Rgb(40, 40, 40), align_w("Track Inputs").full_w()).draw(to), - Some("devices") => bg(Rgb(40, 40, 40), align_w("Track Devices").full_w()).draw(to), - Some("outputs") => bg(Rgb(40, 40, 40), align_w("Track Outputs").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), "Track Devices".align_w().full_w()).draw(to), + Some("outputs") => bg(Rgb(40, 40, 40), "Track Outputs".align_w().full_w()).draw(to), _ => panic!() } } @@ -108,7 +108,7 @@ pub fn draw_dialog ( for (index, MenuItem(item, _)) in items.0.iter().enumerate() { 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) }; - 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)?; } 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(""); let fg1 = Rgb(224, 192, 128); let fg2 = Rgb(224, 128, 32); - let field_name = align_w(fg(fg1, name)).full_w(); - let field_id = align_e(fg(fg2, id)).full_w(); - let field_info = align_w(info).full_w(); + let field_name = fg(fg1, name).align_w().full_w(); + let field_id = fg(fg2, id).align_e().full_w(); + let field_info = info.align_w().full_w(); let _ = bg(b, south(above(field_name, field_id), field_info)) .full_w().exact_h(2).push_y((2 * index) as u16).draw(to); index += 1; @@ -162,12 +162,12 @@ pub fn view_logo () -> impl Draw { pub fn view_transport (play: bool, bpm: &str, beat: &str, time: &str) -> impl Draw { let theme = ItemTheme::G[96]; bg(Black, east!(above( - align_w(button_play_pause(play, false)).full_wh(), - align_e(east!( + button_play_pause(play, false).align_w().full_wh(), + east!( field_h(theme, "BPM", bpm), field_h(theme, "Beat", beat), 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 lat = field_h(theme, "Lat", lat); bg(Black, east!(above( - align_w(sel.map(|sel|field_h(theme, "Selected", sel))).full_wh(), - align_e(east!(sr, buf, lat)).full_wh(), + sel.map(|sel|field_h(theme, "Selected", sel)).align_w().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 { content: impl Draw, ) -> impl Draw { west( - align_nw(button_add).exact_w(4).full_h(), + button_add.align_nw().exact_w(4).full_h(), east( - align_nw(button).full_h().exact_w(20), - align_c(content).full_wh() + button.align_nw().full_h().exact_w(20), + content.align_c().full_wh() ) ) } @@ -286,12 +286,12 @@ pub fn view_sample_info_v (sample: Option<&Arc>>) -> impl Draw>>) -> impl Draw) -> impl Draw { - 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]) @@ -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 frame = Outer(true, Style::default().fg(g(96))); 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); 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, &'a [Connect], usize, usize); iter(items, 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|{ - 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)) } @@ -349,7 +349,7 @@ pub fn view_scenes_clips <'a, S: ScenesSizes<'a>> ( size: &Sizer, editing: bool, ) -> impl Draw { - 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 scenes = iter_once(scenes(), move|(scene_index, scene, _, _), _| { let (name, theme): (Arc, ItemTheme) = scene_name_theme(scene, track_index); @@ -363,7 +363,7 @@ pub fn view_scenes_clips <'a, S: ScenesSizes<'a>> ( below( below( 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() ).full_wh() @@ -446,10 +446,10 @@ pub fn view_track_names ( } else { track.color.base.term }; - bg(b, south(align_nw(east( + bg(b, south(east( format!("·t{index:02} "), fg(Rgb(255, 255, 255), bold(true, &track.name)) - )).full_w(), "")) + ).align_nw().full_w(), "")) .exact_w(track_width(index, track)) .push_x(x1 as u16) .draw(to)?; @@ -462,50 +462,49 @@ pub fn view_track_outputs ( theme: ItemTheme, tracks: impl TracksSizes<'_>, midi_outs: impl Iterator, ) -> impl Draw { 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|{ 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))) })), 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 { 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, align_w( - format!("·o{index:02} {}", port.port_name()).full_w() - )).exact_h(1)); - align_nw(iter_south(iter, draw).full_h()) + 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())) } pub fn view_track_inputs ( theme: ItemTheme, tracks: impl TracksSizes<'_>, height: u16, ) -> impl Draw { 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 { - align_nw(south( + south( bg(track.color.base.term, - align_w(east!( + 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 "), - )).full_w()), + ).align_w().full_w()), iter_south(||track.sequencer.midi_ins.iter(), |port, _|fg_bg(Rgb(255, 255, 255), track.color.dark.term, - align_w(format!("·i{index:02} {}", port.port_name())).full_w())) - )).exact_wh(track_width(index, track), height + 1).draw(to)?; + 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())) } pub fn view_scenes_names ( @@ -534,18 +533,17 @@ pub fn view_scene_name ( } else { H_SCENE as u16 }; - let a = align_w(east(format!("·s{index:02} "), - fg(g(255), bold(true, &scene.name)))).full_w(); - let b = when(select.scene() == Some(index) && editing, align_nw(south( + let a = east(format!("·s{index:02} "), + fg(g(255), bold(true, &scene.name))).align_w().full_w(); + let b = when(select.scene() == Some(index) && editing, south( 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) { scene.color.light.term } else { scene.color.base.term }; - bg(c, align_nw(south(a, b))) - .exact_wh(20, h) + bg(c, south(a, b).align_nw()).exact_wh(20, h) } pub fn view_midi_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw { @@ -582,31 +580,31 @@ pub fn view_per_track () -> impl Draw {} pub fn view_per_track_top () -> impl Draw {} pub fn view_inputs (tracks: impl TracksSizes<'_>, midi_ins: &[MidiInput]) -> impl Draw { - 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); east(title_1, west(title_2, thunk(move|to: &mut Tui|{ for (_index, track, x1, _x2) in tracks { 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.recording, fg(Red, "rec "), "rec "), 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|{ for (index, port) in midi_ins.iter().enumerate() { east( - align_w(east( + east( " ● ", bold(true, fg(Rgb(255,255,255), port.port_name())) - )).exact_w(20), + ).align_w().exact_w(20), west( ().exact_w(4), 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.recording, fg(Red, " ● "), " · "), 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!() })) ).push_x(index as u16 * 10).exact_h(1).draw(to); @@ -627,38 +625,37 @@ pub fn view_outputs ( ) -> impl Draw { let list = south( - align_w(button_3( + button_3( "o", "utput", format!("{}", midi_outs.len()), false - )).full_w().exact_h(1), - align_nw(thunk(|to: &mut Tui|{ + ).align_w().full_w().exact_h(1), + thunk(|to: &mut Tui|{ for (_index, port) in midi_outs.iter().enumerate() { east( - align_w(east(" ● ", fg(Rgb(255,255,255), bold(true, port.port_name())))), - align_e(format!("{}/{} ", + east(" ● ", fg(Rgb(255,255,255), bold(true, port.port_name()))).align_w(), + format!("{}/{} ", port.port().get_connections().len(), - port.connections.len()) - ).full_w().exact_h(1)).full_w().draw(to)?; + port.connections.len()).align_e().full_w().exact_h(1)).full_w().draw(to)?; 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!(); - })).full_wh().exact_h(height - 1) + }).align_nw().full_wh().exact_h(height - 1) ); 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 { thunk(|to: &mut Tui|{ - align_w(east( + east( either(true, fg(Green, "play "), "play "), 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() { - align_w(east( + east( either(true, fg(Green, " ● "), " · "), either(false, fg(Yellow, " ● "), " · "), - )).exact_h(1).draw(to)?; + ).align_w().exact_h(1).draw(to)?; for (_index, _conn) in port.connections.iter().enumerate() { "".full_w().exact_h(1).draw(to)?; } @@ -667,7 +664,7 @@ pub fn view_outputs ( }).exact_w(track_width(index, track)).draw(to); } todo!() - }).full_w()))).exact_h(height) + }).align_w().full_w())).exact_h(height) } pub fn view_track_devices ( @@ -681,13 +678,13 @@ pub fn view_track_devices ( button_2("D", "+", false), iter_once(tracks, move|(_, track, _x1, _x2), index|bg( track.color.dark.term, - align_nw(iter_south(move||0..h, + iter_south(move||0..h, |_, _index|fg_bg( ItemTheme::G[32].lightest.term, ItemTheme::G[32].dark.term, - align_nw(format!(" · {}", "--")) + format!(" · {}", "--").align_nw() ).exact_wh(track.width as u16, 2) - ))).exact_wh( + ).align_nw()).exact_wh( Some(track_width(index, track)), Some(h + 1), ))) @@ -697,21 +694,21 @@ pub fn per_track <'a, T: Draw + 'a, U: TracksSizes<'a>> ( tracks: impl Fn() -> U + Send + Sync + 'a, callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a ) -> impl Draw + '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 + 'a, U: TracksSizes<'a>> ( tracks: impl Fn() -> U + Send + Sync + 'a, callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a ) -> impl Draw + 'a { - align_x(bg(Reset, iter_east(tracks, + bg(Reset, iter_east(tracks, move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{ fg_bg( track.color.lightest.term, track.color.base.term, callback(index, track) ).exact_w((x2 - x1) as u16) - }))) + }).align_x()) } pub fn field_h (theme: ItemTheme, head: impl Draw, body: impl Draw) -> impl Draw { @@ -729,14 +726,14 @@ pub fn view_sessions () -> impl Draw { let b = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) }; let y = (2 * index) as u16; 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())) }).min_w(w).exact_h(h) } pub fn view_browse_title (state: &App) -> impl Draw { - align_w(field_v(ItemTheme::default(), + field_v(ItemTheme::default(), match state.dialog.browser_target().unwrap() { BrowseTarget::SaveProject => "Save project:", BrowseTarget::LoadProject => "Load project:", @@ -745,7 +742,7 @@ pub fn view_browse_title (state: &App) -> impl Draw { BrowseTarget::ImportClip(_) => "Import clip:", BrowseTarget::ExportClip(_) => "Export clip:", }, fg(g(96), x_repeat("🭻")).exact_h(1) - )).full_w() + ).align_w().full_w() } pub fn view_device (state: &App) -> impl Draw { diff --git a/src/device/browse.rs b/src/device/browse.rs index 5210a81a..7eccc2dd 100644 --- a/src/device/browse.rs +++ b/src/device/browse.rs @@ -241,7 +241,7 @@ impl<'a> PoolView<'a> { //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 height = pool.clips.read().unwrap().len() as u16; - origin_n(iter( + iter( ||pool.clips().clone().into_iter(), move|clip: Arc>, i: usize|{ 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 length = if false { String::default() } else { format!("{length} ") }; bg(b, below!( - origin_w(fg(f, bold(selected, name))).full_w(), - origin_e(fg(f, bold(selected, length))).full_w(), - origin_w(when(selected, bold(true, fg(g(255), "▶")))).full_w(), - origin_e(when(selected, bold(true, fg(g(255), "◀")))).full_w(), + fg(f, bold(selected, name)).origin_w().full_w(), + fg(f, bold(selected, length)).origin_e().full_w(), + when(selected, bold(true, fg(g(255), "▶"))).origin_w().full_w(), + when(selected, bold(true, fg(g(255), "◀"))).origin_e().full_w(), )).exact_h(1) - })).full_h().exact_w(20) + }).origin_n().full_h().exact_w(20) } } @@ -315,15 +315,16 @@ impl Browse { impl Browse { fn tui (&self) -> impl Draw { - let item = |entry, _index|origin_w(entry).full_w(); - let iterate = ||EntriesIterator { + iter_south_fixed(1, ||self.tui_entries(), |entry, _index|entry.origin_w().full_w()) + } + fn tui_entries (&self) -> EntriesIterator { + EntriesIterator { offset: 0, index: 0, length: self.dirs.len() + self.files.len(), browser: self, _screen: Default::default(), - }; - iter_south_fixed(1, iterate, item) + } } } diff --git a/src/device/editor.rs b/src/device/editor.rs index 31000a45..0abc07b5 100644 --- a/src/device/editor.rs +++ b/src/device/editor.rs @@ -99,12 +99,12 @@ impl MidiEditor { (clip.color, clip.name.clone(), clip.length, clip.looped) } else { (ItemTheme::G[64], String::new().into(), 0, false) }; south!( - origin_w(east(button_2("f2", "name ", false), - origin_e(fg(Rgb(255, 255, 255), format!("{name} "))).full_w())).full_w(), - origin_w(east(button_2("l", "ength ", false), - origin_e(fg(Rgb(255, 255, 255), format!("{length} "))).full_w())).full_w(), - origin_w(east(button_2("r", "epeat ", false), - origin_e(fg(Rgb(255, 255, 255), format!("{looped} "))).full_w())).full_w(), + east(button_2("f2", "name ", false), fg(Rgb(255, 255, 255), format!("{name} ")) + .origin_e().full_w()).origin_w().full_w(), + east(button_2("l", "ength ", false), fg(Rgb(255, 255, 255), format!("{length} ")).origin_e().full_w()) + .origin_w().full_w(), + east(button_2("r", "epeat ", false), fg(Rgb(255, 255, 255), format!("{looped} ")).origin_e().full_w()) + .origin_w().full_w(), ).exact_w(20) } pub fn edit_status (&self) -> impl Draw + '_ { @@ -119,15 +119,12 @@ impl MidiEditor { let note_pos = format!("{:>3}", note_pos); let note_len = format!("{:>4}", self.get_note_len()); south!( - origin_w(east(button_2("t", "ime ", false), - origin_e(fg(Rgb(255, 255, 255), - format!("{length} /{time_zoom} +{time_pos} "))).full_w())).full_w(), - origin_w(east(button_2("z", "lock ", false), - origin_e(fg(Rgb(255, 255, 255), - format!("{time_lock}"))).full_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(), + east(button_2("t", "ime ", false), + fg(Rgb(255, 255, 255), format!("{length} /{time_zoom} +{time_pos} ")).origin_e().full_w()).origin_w().full_w(), + east(button_2("z", "lock ", false), + fg(Rgb(255, 255, 255), format!("{time_lock}")).origin_e().full_w()).origin_w().full_w(), + east(button_2("x", "note ", false), + fg(Rgb(255, 255, 255), format!("{note_name} {note_pos} {note_len}")).origin_e().full_w()).origin_w().full_w(), ).exact_w(20) } } diff --git a/tengri b/tengri index 09463649..13c886d9 160000 --- a/tengri +++ b/tengri @@ -1 +1 @@ -Subproject commit 09463649c673b0d883ca18746a36aa86c6bd114f +Subproject commit 13c886d9e05a8df712461d44025196ae9be51b78