From e50c4a5eefb24b01b47b21f5a604359f96f514ff Mon Sep 17 00:00:00 2001 From: i do not exist Date: Thu, 13 Aug 2026 07:44:10 +0300 Subject: [PATCH] draw clips; begin removing format! allocs --- Cargo.lock | 283 +++++++++++++++++++++++++++++++++++- Cargo.toml | 14 +- src/device/arrange/clip.rs | 178 +++++++++++------------ src/device/arrange/track.rs | 120 ++++++++++----- src/tek.edn | 12 +- src/tek.rs | 16 +- tengri | 2 +- 7 files changed, 479 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45ccc393..e233b251 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -151,6 +160,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -169,6 +187,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +[[package]] +name = "ascii" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" + [[package]] name = "atk" version = "0.18.2" @@ -220,7 +244,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.37.3", "rustc-demangle", "windows-link", ] @@ -311,6 +335,12 @@ version = "1.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.12.1" @@ -423,6 +453,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" +[[package]] +name = "chunked_transfer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" + [[package]] name = "clap" version = "4.6.5" @@ -585,6 +621,24 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.7" @@ -715,6 +769,27 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -846,6 +921,16 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1249,6 +1334,16 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +[[package]] +name = "hdrhistogram" +version = "7.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d1053f4708f0af3cf9fc5bffc7e68a914a3c45becb231c80068c9c3f78bea" +dependencies = [ + "byteorder", + "num-traits", +] + [[package]] name = "heck" version = "0.4.1" @@ -1267,6 +1362,65 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +[[package]] +name = "hotpath" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e810bedda5a467ef5c9b5c8a20763fefebc89b63ef36f7ee44a143085204a2" +dependencies = [ + "arc-swap", + "cfg-if", + "crossbeam-channel", + "flate2", + "futures-util", + "hdrhistogram", + "hotpath-macros", + "hotpath-meta", + "libc", + "object 0.36.7", + "pin-project-lite", + "prettytable-rs", + "quanta", + "regex", + "rustc-demangle", + "serde", + "serde_json", + "tiny_http", + "tokio", +] + +[[package]] +name = "hotpath-macros" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01bdc59bfc1a9984bee2ff5da63b2f6fccbaa57cd9a4119d709524632bddf341" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "hotpath-macros-meta" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9216e8a01abe1e1671c376dc8736fb1bf772d7a889538d25f9e1200120ced38" + +[[package]] +name = "hotpath-meta" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f22a9d20435fb79511b19dae37b3607224cd98f342a410702d84657cc38fc72f" +dependencies = [ + "hotpath-macros-meta", +] + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "i24" version = "1.0.1" @@ -1344,6 +1498,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1688,6 +1853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -2006,6 +2172,15 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + [[package]] name = "object" version = "0.37.3" @@ -2268,6 +2443,19 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +dependencies = [ + "encode_unicode", + "is-terminal", + "lazy_static", + "term", + "unicode-width 0.1.14", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -2571,6 +2759,40 @@ dependencies = [ "bitflags 2.13.1", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.8.11" @@ -2698,6 +2920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", + "serde_derive", ] [[package]] @@ -2720,6 +2943,19 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "serde_spanned" version = "0.6.9" @@ -2775,6 +3011,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + [[package]] name = "simd_cesu8" version = "1.2.0" @@ -3141,6 +3383,7 @@ dependencies = [ "bumpalo", "clap", "gtk", + "hotpath", "konst", "livi", "notify-debouncer-full", @@ -3201,6 +3444,17 @@ dependencies = [ "unicode-width 0.2.0", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -3266,6 +3520,27 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tiny_http" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" +dependencies = [ + "ascii", + "chunked_transfer", + "httpdate", + "log", +] + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "pin-project-lite", +] + [[package]] name = "toml" version = "0.8.2" @@ -4081,3 +4356,9 @@ dependencies = [ "quote", "syn 2.0.119", ] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Cargo.toml b/Cargo.toml index 1b93bd3a..25e2ece0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,10 +10,6 @@ path = "src/tek.rs" name = "tek" path = "src/tek.rs" -[target.'cfg(target_os = "linux")'] -linker = "clang" -rustflags = ["-Clink-arg=-fuse-ld=mold", "-Clink-arg=-Wl,--no-rosegment"] - [dependencies] tek_proc = { path = "./proc" } tengri = { path = "./tengri", features = [ "term", "lang" ] } @@ -39,6 +35,7 @@ uuid = { optional = true, version = "1.10.0", features = [ "v4" ] } gtk = { optional = true, version = "0.18.1" } notify-debouncer-full = "0.7.0" +hotpath = "0.23" #once_cell = "1.19.0" #no_deadlocks = "1.3.2" @@ -54,6 +51,10 @@ proptest-derive = { version = "^0.5.1" } [features] default = ["cli", "arranger", "sampler"] +hotpath = ["hotpath/hotpath"] +hotpath-cpu = ["hotpath/hotpath-cpu"] +hotpath-alloc = ["hotpath/hotpath-alloc"] + arranger = ["port", "editor", "sequencer", "track", "scene", "clip", "select"] browse = [] clap = [] @@ -79,7 +80,12 @@ vst3 = [] [profile.release] lto = true +debug = "line-tables-only" [profile.coverage] inherits = "test" lto = false + +[target.'cfg(target_os = "linux")'] +linker = "clang" +rustflags = ["-Clink-arg=-fuse-ld=mold,-Clink-arg=-Wl,--no-rosegment,-Cforceframe-pointers=yes" ] diff --git a/src/device/arrange/clip.rs b/src/device/arrange/clip.rs index 207ad15d..2210da42 100644 --- a/src/device/arrange/clip.rs +++ b/src/device/arrange/clip.rs @@ -54,8 +54,6 @@ impl Arrangement { } } -impl ClipsView for T {} - pub trait HasClipsSize { fn clips_size (&self) -> &Sizer; } @@ -68,98 +66,98 @@ impl HasClipsSize for Arrangement { fn clips_size (&self) -> &Sizer { &self.size_inner } } +impl ClipsView for T {} + pub trait ClipsView: TracksView + ScenesView { /// Draw clips per scene - fn view_scenes_clips <'a> (&'a self) -> impl Draw + 'a { - view_scenes_clips( - ||self.scenes_with_sizes(), - self.tracks_with_sizes(), - self.selection(), - self.editor(), - self.clips_size(), - self.is_editing(), - ) + fn view_scenes_clips (&self) -> impl Draw { + let select = self.selection(); + let editor = self.editor(); + let size = self.clips_size(); + let editing = self.is_editing(); + return size.of( + above( + fg(Green, format!("{}x{}", size.w(), size.h())).align_se().full_wh(), + iter_east(move||self.tracks_with_sizes().map(move|( + track_index, track, _, _ + )| { + iter_south(move||self.scenes_with_sizes().map(move|( + scene_index, scene, _, _ + )| { + let (name, theme): (Arc, ItemTheme) = view_scene_name_theme(scene, track_index); + let f = theme.lightest.term; + let (b, o) = view_scene_bg( + theme, select, track_index, scene_index + ); + let w = view_scene_w( + track, select, track_index, editor + ); + let y = view_scene_y( + select, scene_index, editor + ); + let is_selected = view_scene_sel( + select, track_index, scene_index, editing + ); + below( + Outer(true, Style::default().fg(o)).full_wh(), + below( + below( + fg_bg(o, b, "".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() + ).exact_wh(w, y) + })).full_h().exact_w(track.width as u16) + })) + ).full_wh()); } } -pub fn view_scenes_clips <'a, S: ScenesSizes<'a>> ( - scenes: impl Fn()->S, - tracks: impl TracksSizes<'a>, - select: &Selection, - editor: Option<&MidiEditor>, - size: &Sizer, - editing: bool, -) -> impl Draw { - 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); - let f = theme.lightest.term; - let (b, o) = scene_bg(theme, select, track_index, scene_index); - let w = scene_w(track, select, track_index, editor); - let y = scene_y(select, scene_index, editor); - let is_selected = scene_sel(select, track_index, scene_index, editing); - below( - Outer(true, Style::default().fg(o)).full_wh(), - below( - below( - fg_bg(o, b, "".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() - ).exact_wh(w, y) - }); - scenes.full_h().exact_w(track.width as u16) - }); - - return size.of(above(status, tracks).full_wh()); - - fn scene_name_theme (scene: &Scene, track_index: usize) -> (Arc, 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]) - } - } - - fn scene_bg ( - theme: ItemTheme, select: &Selection, track_index: usize, scene_index: usize - ) -> (Color, Color) { - let mut outline = theme.base.term; - (if select.track() == Some(track_index) && select.scene() == Some(scene_index) { - outline = theme.lighter.term; - theme.light.term - } else if select.track() == Some(track_index) || select.scene() == Some(scene_index) { - outline = theme.darkest.term; - theme.base.term - } else { - theme.dark.term - }, outline) - } - - fn scene_w ( - track: &Track, select: &Selection, track_index: usize, editor: Option<&MidiEditor> - ) -> u16 { - if select.track() == Some(track_index) && let Some(editor) = editor { - (editor.size.w() as usize).max(24).max(track.width) as u16 - } else { - track.width as u16 - } - } - - fn scene_y ( - select: &Selection, scene_index: usize, editor: Option<&MidiEditor> - ) -> u16 { - if select.scene() == Some(scene_index) && let Some(editor) = editor { - editor.size.h().max(12) - } else { - Scene::DEFAULT_HEIGHT as u16 - } - } - - fn scene_sel (select: &Selection, track_index: usize, scene_index: usize, editing: bool) -> bool { - editing && select.track() == Some(track_index) && select.scene() == Some(scene_index) +fn view_scene_name_theme (scene: &Scene, track_index: usize) -> (Arc, 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]) } } + +fn view_scene_bg ( + theme: ItemTheme, select: &Selection, track_index: usize, scene_index: usize +) -> (Color, Color) { + let mut outline = theme.base.term; + (if select.track() == Some(track_index) && select.scene() == Some(scene_index) { + outline = theme.lighter.term; + theme.light.term + } else if select.track() == Some(track_index) || select.scene() == Some(scene_index) { + outline = theme.darkest.term; + theme.base.term + } else { + theme.dark.term + }, outline) +} + +fn view_scene_w ( + track: &Track, select: &Selection, track_index: usize, editor: Option<&MidiEditor> +) -> u16 { + if select.track() == Some(track_index) && let Some(editor) = editor { + (editor.size.w() as usize).max(24).max(track.width) as u16 + } else { + track.width as u16 + } +} + +fn view_scene_y ( + select: &Selection, scene_index: usize, editor: Option<&MidiEditor> +) -> u16 { + if select.scene() == Some(scene_index) && let Some(editor) = editor { + editor.size.h().max(12) + } else { + Scene::DEFAULT_HEIGHT as u16 + } +} + +fn view_scene_sel (select: &Selection, track_index: usize, scene_index: usize, editing: bool) -> bool { + editing && select.track() == Some(track_index) && select.scene() == Some(scene_index) +} diff --git a/src/device/arrange/track.rs b/src/device/arrange/track.rs index 4dbdd540..e01802d1 100644 --- a/src/device/arrange/track.rs +++ b/src/device/arrange/track.rs @@ -34,7 +34,8 @@ impl Track { name: name.as_ref().into(), color: color.unwrap_or_default(), sequencer: Sequencer::new( - format!("{}/sequencer", name.as_ref()), jack, clock, clip, midi_from, midi_to + format!("{}/sequencer", name.as_ref()), + jack, clock, clip, midi_from, midi_to )?, ..Default::default() }) @@ -224,7 +225,7 @@ pub trait HasTracks: AsRef> + AsMut> + HasClock + HasTrack where Self: HasJack<'static> + HasScenes { let name: Arc = name.map_or_else( - ||format!("trk{:02}", self.tracks_last()).into(), + ||format!("trk{}", self.tracks_last()).into(), |x|x.to_string().into() ); *self.tracks_last_mut() += 1; @@ -232,7 +233,7 @@ pub trait HasTracks: AsRef> + AsMut> + HasClock + HasTrack width: (name.len() + 2).max(12), color: color.unwrap_or_else(ItemTheme::random), sequencer: Sequencer::new( - &format!("{name}"), + &name, self.jack(), Some(self.clock()), None, @@ -282,7 +283,6 @@ pub trait TracksController: HasTracks + Namespace>> + Namespace>>>>> { - #[command(Stop = "stop")] /// Stop all playing clips fn tracks_stop_all (&mut self) -> Perhaps { @@ -344,35 +344,55 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra /// Draw name of each track fn view_track_names (&self, theme: ItemTheme) -> impl Draw { - 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() { + east( + south( + button_3( + "t", + "rack ", + east( + selected.track().map(|track|east(track, "/")), + self.tracks().len() + ), + false + ), + button_3( + "s", + "cene ", + east( + selected.scene().map(|scene|east(scene, "/")), + self.scenes().len() + ), + false + ) + ), + west( + south( + button_2("T", "+", false), + button_2("S", "+", false), + ), + bg(theme.darker.term, iter_east(||self.tracks_with_sizes().map(|(index, track, x1, _x2)|{ 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(), "")) + bg(b, south( + east!( + "·t", + index, + " ", + 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))) + .exact_h(2) + }))) + ) + ) } /// Draw outputs per track @@ -391,9 +411,20 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra let f = Rgb(255, 255, 255); let b = track.color.dark.term; iter_south(||track.sequencer.midi_outs.iter().map(|port: &MidiOutput|{ - fg(f, bg(b, format!("·o{index:02} {}", port.port_name()).full_w().align_w()).exact_h(1)) + fg(f, bg(b, east!( + "·o", + index, + " ", + port.port_name() + ) + .full_w() + .align_w() + ).exact_h(1)) })) - .full_h().align_nw().exact_w(track_width(index, track)).draw(to)?; + .full_h() + .align_nw() + .exact_w(track_width(index, track)) + .draw(to)?; } Ok(Some(XYWH(0, 0, 0, 0))) }).align_w())) @@ -416,7 +447,12 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "), ).align_w().full_w()), iter_south(||track.sequencer.midi_ins.iter().map(|port|fg_bg(Rgb(255, 255, 255), track.color.dark.term, - format!("·i{index:02} {}", port.port_name()).align_w().full_w()))) + east!( + "·i", + index, + " ", + 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))) @@ -425,7 +461,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra fn view_track_devices (&self, theme: ItemTheme) -> impl Draw { let height = self.tracks_devices_height(); - let btn1 = button_3("d", "evice", format!("{}", self.track().map(|t|t.devices.len()).unwrap_or(0)), false); + let btn1 = button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false); let btn2 = button_2("D", "+", false); view_track_row_section(theme, btn1, btn2, iter_east(move||self.tracks_with_sizes() .enumerate() @@ -434,7 +470,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra iter_south(move||(0..height).map(|_|fg_bg( ItemTheme::G[32].lightest.term, ItemTheme::G[32].dark.term, - format!(" · {}", "--").align_nw() + " · --".align_nw() ).exact_wh(track.width as u16, 2))) .align_nw() ) @@ -453,7 +489,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra } fn view_inputs (&self, _theme: ItemTheme) -> impl Draw + '_ { - let title_1 = button_3("i", "nput ", format!("{}", self.midi_ins().len()), false).align_w().exact_wh(20, 1); + let title_1 = button_3("i", "nput ", 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() { @@ -500,17 +536,27 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra let height = self.outputs_height(); let list = south( button_3( - "o", "utput", format!("{}", self.midi_outs().len()), false + "o", "utput", 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!("{}/{} ", + east( + " ● ", + fg(Rgb(255,255,255), bold(true, port.port_name())) + ).align_w(), + east!( port.port().get_connections().len(), - port.connections.len()).align_e().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() { - format!(" c{index:02}{}", conn.info()).align_w().full_w().exact_h(1).draw(to)?; + east!( + " c", + index, + conn.info() + ).align_w().full_w().exact_h(1).draw(to)?; } } todo!(); diff --git a/src/tek.edn b/src/tek.edn index 7c2f2e99..5330b32c 100644 --- a/src/tek.edn +++ b/src/tek.edn @@ -42,12 +42,12 @@ (bsp/e (bg (g 30) (exact/x 4 (align/nw :meters/input))) (full/xy (align/c (max/xy 80 80 (bsp/s (bg (g 40) (exact/y 4 :tracks/outputs)) - (bsp/s (bg (g 50) (exact/y 2 :tracks/names)) - (bsp/s (bg (g 60) (exact/y 4 :tracks/devices)) - (bsp/s (bg (g 70) (exact/y 4 :tracks/inputs)) - (either :mode/editor - (bg (g 80) (bsp/s :scenes/names :editor)) - (bg (g 90) :scenes)))))))))))))) + (bsp/s (bg (g 60) (exact/y 4 :tracks/devices)) + (bsp/s (bg (g 50) (exact/y 2 :tracks/names)) + (bsp/s (either :mode/editor + (bg (g 80) (bsp/e :scenes/names :editor)) + (bg (g 90) :scenes)) + (bg (g 70) (exact/y 4 :tracks/inputs)))))))))))))) (keys :clock (@space clock/toggle 0) (@shift/space clock/toggle 0)) diff --git a/src/tek.rs b/src/tek.rs index 52563b1c..cb5331f8 100644 --- a/src/tek.rs +++ b/src/tek.rs @@ -13,7 +13,9 @@ pub fn show_version () { } /// Command-line entrypoint. -#[allow(unused)] fn main () -> Usually<()> { +#[allow(unused)] +#[hotpath::main] +fn main () -> Usually<()> { tengri::Tui::setup_panic(); #[cfg(feature = "cli")] { Config::watched(crate::cli::run_with_config)?; @@ -1326,14 +1328,14 @@ mod draw { /// Then, every top-level form of the DSL description is rendered. impl View for App { fn view (&self) -> impl Draw { - self.perf.cycle(&mut |_|{ + //self.perf.cycle(&mut |_|{ draw(|to: &mut Tui|{ self.draw_error(to)?; self.draw_mode(to)?; - self.draw_debug(to)?; + //self.draw_debug(to)?; Ok(Some(to.area().into())) }) - }) + //}) } } @@ -1404,9 +1406,9 @@ mod draw { Some("outputs") => self.project.view_track_outputs(self.color.clone(), 0).draw(to), _ => panic!() }, - Some(":scenes") => match frags.next() { - None => "TODO Scenes".draw(to), - Some(":scenes/names") => "TODO Scene Names".draw(to), + Some(":scenes") => match frags.next() { + None => self.view_scenes_clips().draw(to), + Some("names") => self.view_scenes_names().draw(to), _ => panic!() }, Some(":dialog") => draw_dialog(to, frags, self, lang), diff --git a/tengri b/tengri index 1f541407..95ace837 160000 --- a/tengri +++ b/tengri @@ -1 +1 @@ -Subproject commit 1f541407597c7866cf1450d03967ab4711d28d29 +Subproject commit 95ace837565c65292d86694cb395d9ba7fa834eb