From 790e33b40c917edff706c808c1cc7fee6bd29b29 Mon Sep 17 00:00:00 2001 From: i do not exist Date: Tue, 16 Jun 2026 14:23:29 +0300 Subject: [PATCH] phocking wip (weep) --- src/arrange.rs | 66 +++++++++++++++-------------- src/tek.rs | 110 +++++++++++++++++++++++++------------------------ tengri | 2 +- 3 files changed, 92 insertions(+), 86 deletions(-) diff --git a/src/arrange.rs b/src/arrange.rs index 31b01809..de20fbbe 100644 --- a/src/arrange.rs +++ b/src/arrange.rs @@ -115,8 +115,9 @@ pub trait ClipsView: TracksView + ScenesView { 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)))) + let w = track.width as u16; + let v = self.view_track_clips(track_index, track); + w_exact(w, h_full(v)).draw(to); } Ok(XYWH(0, 0, 0, 0)) })))) @@ -166,14 +167,14 @@ pub trait ClipsView: TracksView + ScenesView { self.selection().scene() == Some(scene_index) && self.is_editing(); - to.place(&wh_exact(Some(w), Some(y), below( + 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())))))))); + wh_full(when(is_selected, self.editor().map(|e|e.view()))))))).draw(to); } Ok(XYWH(0, 0, 0, 0)) }) @@ -219,7 +220,7 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll { view_track_row_section(theme, button, button_2, bg(theme.darker.term, h_exact(2, thunk(|to: &mut Tui|{ for (index, track, x1, _x2) in self.tracks_with_sizes() { - to.place(&x_push(x1 as u16, w_exact(track_width(index, track), + x_push(x1 as u16, w_exact(track_width(index, track), bg(if selected.track() == Some(index) { track.color.light.term } else { @@ -227,7 +228,8 @@ 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)) - ))), ""))) ));} + ))), ""))) ).draw(to); + } Ok(XYWH(0, 0, 0, 0)) })))) } @@ -237,7 +239,7 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll { 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()))); + w_full(origin_w(port.port_name())).draw(to); } Ok(XYWH(0, 0, 0, 0)) })), @@ -245,11 +247,11 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll { bg(theme.darker.term, origin_w(thunk(|to: &mut Tui|{ for (index, track, _x1, _x2) in self.tracks_with_sizes() { let iter = ||track.sequencer.midi_outs.iter(); - let draw = |port: &MidiOutput|fg(Rgb(255, 255, 255), + let draw = |port: &MidiOutput, _|fg(Rgb(255, 255, 255), h_exact(1, bg(track.color.dark.term, w_full(origin_w( format!("·o{index:02} {}", port.port_name())))))); - to.place(&w_exact(track_width(index, track), - origin_nw(h_full(iter_south(iter, draw))))); + w_exact(track_width(index, track), + origin_nw(h_full(iter_south(iter, draw)))).draw(to); } Ok(XYWH(0, 0, 0, 0)) })))) @@ -262,7 +264,7 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll { } let content = thunk(move|to: &mut Tui|{ for (index, track, _x1, _x2) in self.tracks_with_sizes() { - to.place(&wh_exact(Some(track_width(index, track)), Some(h + 1), + wh_exact(Some(track_width(index, track)), Some(h + 1), origin_nw(south( bg(track.color.base.term, w_full(origin_w(east!( @@ -271,8 +273,9 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll { either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "), )))), iter_south(||track.sequencer.midi_ins.iter(), - |port|fg_bg(Rgb(255, 255, 255), track.color.dark.term, - w_full(origin_w(format!("·i{index:02} {}", port.port_name()))))))))); + |port, _|fg_bg(Rgb(255, 255, 255), track.color.dark.term, + w_full(origin_w(format!("·i{index:02} {}", port.port_name())))))))) + .draw(to); } Ok(XYWH(0, 0, 0, 0)) }); @@ -311,7 +314,7 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + HasClipsSize + fn view_scenes_names (&self) -> impl Draw { w_exact(20, thunk(|to: &mut Tui|{ for (index, scene, ..) in self.scenes_with_sizes() { - to.place(&self.view_scene_name(index, scene)); + self.view_scene_name(index, scene).draw(to); } Ok(XYWH(1, 1, 1, 1)) })) @@ -687,7 +690,7 @@ impl Arrangement { h_exact(1, self.view_inputs_header()), thunk(|to: &mut Tui|{ for (index, port) in self.midi_ins().iter().enumerate() { - to.place(&x_push(index as u16 * 10, h_exact(1, self.view_inputs_row(port)))) + x_push(index as u16 * 10, h_exact(1, self.view_inputs_row(port))).draw(to) } }) ) @@ -697,11 +700,11 @@ impl Arrangement { 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() { #[cfg(feature = "track")] - to.place(&x_push(x1 as u16, bg(track.color.dark.term, origin_w(w_exact(track.width as u16, east!( + x_push(x1 as u16, bg(track.color.dark.term, origin_w(w_exact(track.width as u16, 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 "), - )))))) + ))))).draw(to) }))) } @@ -709,11 +712,11 @@ impl Arrangement { 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() { #[cfg(feature = "track")] - to.place(&bg(track.color.darker.term, origin_w(w_exact(track.width as u16, east!( + bg(track.color.darker.term, origin_w(w_exact(track.width as u16, east!( either(track.sequencer.monitoring, fg(Green, " ● "), " · "), either(track.sequencer.recording, fg(Red, " ● "), " · "), either(track.sequencer.overdub, fg(Yellow, " ● "), " · "), - ))))) + )))).draw(to) }))) } @@ -732,13 +735,14 @@ impl Arrangement { )))), h_exact(h - 1, wh_full(origin_nw(thunk(|to: &mut Tui|{ for (_index, port) in self.midi_outs().iter().enumerate() { - to.place(&h_exact(1,w_full(east( + h_exact(1,w_full(east( origin_w(east(" ● ", fg(Rgb(255,255,255), bold(true, port.port_name())))), w_full(origin_e(format!("{}/{} ", port.port().get_connections().len(), - port.connections.len()))))))); + port.connections.len())))))).draw(to); for (index, conn) in port.connections.iter().enumerate() { - to.place(&h_exact(1, w_full(origin_w(format!(" c{index:02}{}", conn.info()))))); + h_exact(1, w_full(origin_w(format!(" c{index:02}{}", conn.info())))) + .draw(to); } } })))) @@ -748,23 +752,23 @@ impl Arrangement { bg(theme.darker.term, origin_w(w_full( thunk(|to: &mut Tui|{ for (index, track, _x1, _x2) in self.tracks_with_sizes() { - to.place(&w_exact(track_width(index, track), + w_exact(track_width(index, track), thunk(|to: &mut Tui|{ - to.place(&h_exact(1, origin_w(east( + h_exact(1, origin_w(east( either(true, fg(Green, "play "), "play "), either(false, fg(Yellow, "solo "), "solo "), - )))); + ))).draw(to); for (_index, port) in self.midi_outs().iter().enumerate() { - to.place(&h_exact(1, origin_w(east( + h_exact(1, origin_w(east( either(true, fg(Green, " ● "), " · "), either(false, fg(Yellow, " ● "), " · "), - )))); + ))).draw(to); for (_index, _conn) in port.connections.iter().enumerate() { - to.place(&h_exact(1, w_full(""))); + h_exact(1, w_full("")).draw(to); } } }) - )) + ).draw(to) } }) ))) @@ -779,7 +783,7 @@ impl Arrangement { button_3("d", "evice", format!("{}", self.track().map(|t|t.devices.len()).unwrap_or(0)), false), button_2("D", "+", false), 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, + wh_exact(track_width(index, track), h + 1, bg(track.color.dark.term, origin_nw(iter_south(2, move||0..h, |_, _index|wh_exact(track.width as u16, 2, fg_bg( @@ -789,7 +793,7 @@ impl Arrangement { ) ))) ) - )); + ).draw(to); }) ) } diff --git a/src/tek.rs b/src/tek.rs index 90955b66..fb27be6f 100644 --- a/src/tek.rs +++ b/src/tek.rs @@ -426,14 +426,14 @@ pub fn button_play_pause (playing: bool) -> impl Draw { let compact = true;//self.is_editing(); bg(if playing { Rgb(0, 128, 0) } else { Rgb(128, 64, 0) }, either(compact, - thunk(move|to: &mut Tui|to.place(&w_exact(9, either(playing, + thunk(move|to: &mut Tui|w_exact(9, either(playing, fg(Rgb(0, 255, 0), " PLAYING "), - fg(Rgb(255, 128, 0), " STOPPED "))) - )), - thunk(move|to: &mut Tui|to.place(&w_exact(5, either(playing, + fg(Rgb(255, 128, 0), " STOPPED ")) + ).draw(to)), + thunk(move|to: &mut Tui|w_exact(5, either(playing, fg(Rgb(0, 255, 0), south(" 🭍🭑🬽 ", " 🭞🭜🭘 ",)), - fg(Rgb(255, 128, 0), south(" ▗▄▖ ", " ▝▀▘ ",)))) - )) + fg(Rgb(255, 128, 0), south(" ▗▄▖ ", " ▝▀▘ ",))) + ).draw(to)), ) ) } @@ -494,34 +494,36 @@ pub fn draw_info (sample: Option<&Arc>>) -> impl Draw + use< when(sample.is_some(), thunk(move|to: &mut Tui|{ let sample = sample.unwrap().read().unwrap(); let theme = sample.color; - to.place(&east!( + east!( field_h(theme, "Name", format!("{:<10}", sample.name.clone())), field_h(theme, "Length", format!("{:<8}", sample.channels[0].len())), field_h(theme, "Start", format!("{:<8}", sample.start)), field_h(theme, "End", format!("{:<8}", sample.end)), field_h(theme, "Trans", "0"), field_h(theme, "Gain", format!("{}", sample.gain)), - )) + ).draw(to) })) } pub fn draw_info_v (sample: Option<&Arc>>) -> impl Draw + use<'_> { - either(sample.is_some(), thunk(move|to: &mut Tui|{ + let a = thunk(move|to: &mut Tui|{ let sample = sample.unwrap().read().unwrap(); let theme = sample.color; - to.place(&w_exact(20, south!( + w_exact(20, south!( w_full(origin_w(field_h(theme, "Name ", format!("{:<10}", sample.name.clone())))), w_full(origin_w(field_h(theme, "Length", format!("{:<8}", sample.channels[0].len())))), w_full(origin_w(field_h(theme, "Start ", format!("{:<8}", sample.start)))), w_full(origin_w(field_h(theme, "End ", format!("{:<8}", sample.end)))), w_full(origin_w(field_h(theme, "Trans ", "0"))), w_full(origin_w(field_h(theme, "Gain ", format!("{}", sample.gain)))), - ))) - }), thunk(|to: &mut Tui|to.place(&fg(Red, south!( + )).draw(to) + }); + let b = thunk(|to: &mut Tui|fg(Red, south!( bold(true, "× No sample."), "[r] record", "[Shift-F9] import", - ))))) + ))); + either(sample.is_some(), a, b) } pub fn draw_status (sample: Option<&Arc>>) -> impl Draw { @@ -726,47 +728,47 @@ impl<'a> Namespace<'a, AppCommand> for App { "cancel" => AppCommand::Cancel, }); } -impl Understand for App { - fn understand_expr <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Usually<()> { - app_understand_expr(self, to, lang) +impl Interpret for App { + fn interpret_expr <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Usually<()> { + app_interpret_expr(self, to, lang) } - fn understand_word <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Usually<()> { - app_understand_word(self, to, lang) + fn interpret_word <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Usually<()> { + app_interpret_word(self, to, lang) } } -fn app_understand_expr (state: &App, to: &mut Tui, lang: &impl Expression) -> Usually<()> { +fn app_interpret_expr (state: &App, to: &mut Tui, lang: &impl Expression) -> Usually<()> { if eval_view(state, to, lang)? || eval_view_tui(state, to, lang)? { Ok(()) } else { - Err(format!("App::understand_expr: unexpected: {lang:?}").into()) + Err(format!("App::interpret_expr: unexpected: {lang:?}").into()) } } -fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usually<()> { +fn app_interpret_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usually<()> { let mut frags = dsl.src()?.unwrap().split("/"); match frags.next() { - Some(":logo") => to.place(&view_logo()), - Some(":status") => to.place(&h_exact(1, "TODO: Status Bar")), + Some(":logo") => view_logo().draw(to), + Some(":status") => h_exact(1, "TODO: Status Bar").draw(to), Some(":meters") => match frags.next() { - Some("input") => to.place(&bg(Rgb(30, 30, 30), h_full(origin_s("Input Meters")))), - Some("output") => to.place(&bg(Rgb(30, 30, 30), h_full(origin_s("Output Meters")))), + Some("input") => bg(Rgb(30, 30, 30), h_full(origin_s("Input Meters"))).draw(to), + Some("output") => bg(Rgb(30, 30, 30), h_full(origin_s("Output Meters"))).draw(to), _ => panic!() }, Some(":tracks") => match frags.next() { - None => to.place(&"TODO tracks"), - Some("names") => to.place(&state.project.view_track_names(state.color.clone())),//bg(Rgb(40, 40, 40), w_full(origin_w("Track Names")))), - Some("inputs") => to.place(&bg(Rgb(40, 40, 40), w_full(origin_w("Track Inputs")))), - Some("devices") => to.place(&bg(Rgb(40, 40, 40), w_full(origin_w("Track Devices")))), - Some("outputs") => to.place(&bg(Rgb(40, 40, 40), w_full(origin_w("Track Outputs")))), + None => "TODO tracks".draw(to), + Some("names") => state.project.view_track_names(state.color.clone()).draw(to),//bg(Rgb(40, 40, 40), w_full(origin_w("Track Names")))), + Some("inputs") => bg(Rgb(40, 40, 40), w_full(origin_w("Track Inputs"))).draw(to), + Some("devices") => bg(Rgb(40, 40, 40), w_full(origin_w("Track Devices"))).draw(to), + Some("outputs") => bg(Rgb(40, 40, 40), w_full(origin_w("Track Outputs"))).draw(to), _ => panic!() }, Some(":scenes") => match frags.next() { - None => to.place(&"TODO scenes"), - Some(":scenes/names") => to.place(&"TODO Scene Names"), + None => "TODO scenes".draw(to), + Some(":scenes/names") => "TODO Scene Names".draw(to), _ => panic!() }, - Some(":editor") => to.place(&"TODO Editor"), + Some(":editor") => "TODO Editor".draw(to), Some(":dialog") => match frags.next() { - Some("menu") => to.place(&if let Dialog::Menu(selected, items) = &state.dialog { + Some("menu") => if let Dialog::Menu(selected, items) = &state.dialog { let items = items.clone(); let selected = selected; Some(wh_full(thunk(move|to: &mut Tui|{ @@ -781,10 +783,10 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu }))) } else { None - }), - _ => unimplemented!("App::understand_word: {dsl:?} ({frags:?})"), + }.draw(to), + _ => unimplemented!("App::interpret_word: {dsl:?} ({frags:?})"), }, - Some(":templates") => to.place(&{ + Some(":templates") => { let modes = state.config.modes.clone(); let height = (modes.read().unwrap().len() * 2) as u16; h_exact(height, w_min(30, thunk(move |to: &mut Tui|{ @@ -797,21 +799,21 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu let field_name = w_full(origin_w(fg(fg1, name))); let field_id = w_full(origin_e(fg(fg2, id))); let field_info = w_full(origin_w(info)); - to.place(&y_push((2 * index) as u16, + y_push((2 * index) as u16, h_exact(2, w_full(bg(bg, south( - above(field_name, field_id), field_info)))))); + above(field_name, field_id), field_info))))).draw(to); } }))) - }), - Some(":sessions") => to.place(&h_exact(6, w_min(30, thunk(|to: &mut Tui|{ + }.draw(to), + Some(":sessions") => h_exact(6, w_min(30, thunk(|to: &mut Tui|{ let fg = Rgb(224, 192, 128); for (index, name) in ["session1", "session2", "session3"].iter().enumerate() { let bg = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) }; - to.place(&y_push((2 * index) as u16, - &h_exact(2, w_full(bg(bg, origin_w(fg(fg, name))))))); + y_push((2 * index) as u16, + &h_exact(2, w_full(bg(bg, origin_w(fg(fg, name)))))).draw(to); } - })))), - Some(":browse/title") => to.place(&w_full(origin_w(field_v(ItemColor::default(), + }))).draw(to), + Some(":browse/title") => w_full(origin_w(field_v(ItemColor::default(), match state.dialog.browser_target().unwrap() { BrowseTarget::SaveProject => "Save project:", BrowseTarget::LoadProject => "Load project:", @@ -819,24 +821,24 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu BrowseTarget::ExportSample(_) => "Export sample:", BrowseTarget::ImportClip(_) => "Import clip:", BrowseTarget::ExportClip(_) => "Export clip:", - }, w_shrink(3, h_exact(1, fg(g(96), x_repeat("🭻")))))))), + }, w_shrink(3, h_exact(1, fg(g(96), x_repeat("🭻"))))))).draw(to), Some(":device") => { let selected = state.dialog.device_kind().unwrap(); - to.place(&south(bold(true, "Add device"), iter_south( + south(bold(true, "Add device"), iter_south( move||device_kinds().iter(), move|_label: &&'static str, i|{ let bg = if i == selected { Rgb(64,128,32) } else { Rgb(0,0,0) }; let lb = if i == selected { "[ " } else { " " }; let rb = if i == selected { " ]" } else { " " }; - w_full(bg(bg, east(lb, west(rb, "FIXME device name")))) }))) + w_full(bg(bg, east(lb, west(rb, "FIXME device name")))) })).draw(to) }, - Some(":debug") => to.place(&h_exact(1, format!("[{:?}]", to.area()))), + Some(":debug") => h_exact(1, format!("[{:?}]", to.area())).draw(to), Some(_) => { let views = state.config.views.read().unwrap(); if let Some(dsl) = views.get(dsl.src()?.unwrap()) { let dsl = dsl.clone(); std::mem::drop(views); - state.understand(to, &dsl)? + state.interpret(to, &dsl)? } else { unimplemented!("{dsl:?}"); } @@ -968,10 +970,10 @@ impl App { impl Draw for App { fn draw (self, to: &mut Tui) -> Usually> { if let Some(e) = self.error.read().unwrap().as_ref() { - to.place_at(to.area().into(), e.as_ref()); + to.show(to.area().into(), e.as_ref()); } for (index, dsl) in self.mode.view.iter().enumerate() { - if let Err(e) = self.understand(to, dsl) { + if let Err(e) = self.interpret(to, dsl) { *self.error.write().unwrap() = Some(format!("view #{index}: {e}").into()); break; } @@ -986,8 +988,8 @@ primitive!(u16: try_to_u16); primitive!(usize: try_to_usize); primitive!(isize: try_to_isize); -fn field_h (theme: ItemTheme, head: impl Draw, body: impl Draw) -> impl Draw { +fn field_h (theme: ItemTheme, head: impl Draw, body: impl Draw) -> impl Draw { } -fn field_v (theme: ItemTheme, head: impl Draw, body: impl Draw) -> impl Draw { +fn field_v (theme: ItemTheme, head: impl Draw, body: impl Draw) -> impl Draw { } diff --git a/tengri b/tengri index c9b9ff15..2dc501c1 160000 --- a/tengri +++ b/tengri @@ -1 +1 @@ -Subproject commit c9b9ff15191ec3a37e8da35f382ce0d4af74d0d8 +Subproject commit 2dc501c184c0404a50b220a9fe9f756b87e4635b