diff --git a/README.md b/README.md index 64655591..1245d348 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ or [**matrix** `@unspeaker:matrix.org`](https://matrix.to/#/@unspeaker:matrix.or | | | |-|-| -|![Screenshot of Arranger Mode](https://codeberg.org/unspeaker/tek/attachments/5014ff4d-9ece-4862-90de-3bc6573eacf6)|![Screenshot of Groovebox Mode](https://codeberg.org/unspeaker/tek/attachments/bbc12eda-1d5e-4e0f-9474-f585128255a5)
![Screenshot of Help in Groovebox Mode](https://codeberg.org/unspeaker/tek/attachments/d8963b84-8183-4c05-b77b-349a4c4c6161)| +|![Screenshot of Arranger Mode](https://codeberg.org/unspeaker/tek/attachments/5014ff4d-9ece-4862-90de-3bc6573eacf6)|![Screenshot of Groovebox Mode](https://codeberg.org/unspeaker/tek/releases/download/0.2.0-rc.7/Screenshot%20From%202025-01-02%2023-18-05.png) ## usage diff --git a/config/config_arranger.edn b/config/config_arranger.edn index 408dab55..7fb8416f 100644 --- a/config/config_arranger.edn +++ b/config/config_arranger.edn @@ -26,6 +26,6 @@ (fill/xy (align/n (bsp/s :view-arranger-track-names (bsp/s :view-arranger-track-outputs (bsp/s :view-arranger-track-devices :view-arranger-track-inputs))))))) - (fill/xy (align/w (bsp/e - (align/w (fixed/x 20 (fill/xy (align/nw :view-arranger-scenes-names)))) - (align/w (fill/xy (align/nw :view-arranger-scenes-clips))))))))) + (bsp/w + (fixed/x 20 :view-pool) + :view-arranger-scenes))) diff --git a/config/config_groovebox.edn b/config/config_groovebox.edn index 136b216a..5fa63e9e 100644 --- a/config/config_groovebox.edn +++ b/config/config_groovebox.edn @@ -12,17 +12,17 @@ (layer "./keys_global.edn")) (view (bsp/a :view-dialog (bsp/w :view-meters-output (bsp/e :view-meters-input - (bsp/w + (bsp/e (fill/y (align/n - (bsp/s :view-midi-ins-status - (bsp/s :view-midi-outs-status - (bsp/s :view-audio-ins-status - (bsp/s :view-audio-outs-status - :view-pool)))))) - (bsp/n - (fixed/y :h-sample-detail - (bsp/e (fill/y (fixed/x 20 (align/nw :view-sample-status))) - :view-sample-viewer)) - (bsp/e - (fill/y (align/n (bsp/s :view-status-v :view-editor-status))) + (bsp/s :view-status-v + (bsp/s :view-editor-status :view-pool)))) + (bsp/w + (fill/y (align/n + (bsp/s :view-midi-ins-status + (bsp/s :view-midi-outs-status + (bsp/s :view-audio-ins-status :view-audio-outs-status))))) + (bsp/n + (fixed/y :h-sample-detail + (bsp/e (fill/y (fixed/x 20 (align/nw :view-sample-status))) + :view-sample-viewer)) (bsp/e :view-samples-keys :view-editor)))))))) diff --git a/crates/app/src/model.rs b/crates/app/src/model.rs index 1138f078..9696e698 100644 --- a/crates/app/src/model.rs +++ b/crates/app/src/model.rs @@ -195,9 +195,6 @@ impl App { fn focus_editor (&self) -> bool { self.is_editing() } - fn is_editing (&self) -> bool { - HasEditor::is_editing(self) - } fn focus_message (&self) -> bool { matches!(self.dialog, Some(Dialog::Message(..))) } diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index d5723f74..a84c9bb6 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -107,12 +107,6 @@ impl App { pub fn view_arranger_scenes (&self) -> impl Content + use<'_> { self.scenes_view(&self.editor) } - pub fn view_arranger_scenes_names (&self) -> impl Content + use<'_> { - self.scenes_names() - } - pub fn view_arranger_scenes_clips (&self) -> impl Content + use<'_> { - self.scenes_clips(&self.editor) - } pub fn view_arranger_scene_names <'a> (&'a self) -> impl Content + use<'a> { let h = self.project.scenes.len() as u16 * 2; let bg = self.color.darker.rgb; @@ -363,16 +357,16 @@ impl App { impl ArrangerSceneRows for App { fn arrangement (&self) -> &Arrangement { - &self.project + self.project } fn scenes_height (&self) -> u16 { - (self.height() as u16).saturating_sub(20) + self.project.scenes_height } - fn width_side (&self) -> u16 { + fn width_side (&self) -> u16 { 20 } - fn width_mid (&self) -> u16 { - (self.width() as u16).saturating_sub(self.width_side()) + fn width_mid (&self) -> u16 { + self.width().saturating_sub(self.width_side() * 2) } fn scene_selected (&self) -> Option { self.project.selection.scene() @@ -384,7 +378,7 @@ impl ArrangerSceneRows for App { self.project.selection.track() } fn is_editing (&self) -> bool { - self.editor.is_some() + self.is_editing } } diff --git a/crates/cli/tek.rs b/crates/cli/tek.rs index a99f86db..97a7f499 100644 --- a/crates/cli/tek.rs +++ b/crates/cli/tek.rs @@ -56,7 +56,7 @@ pub enum LaunchMode { /// 🎧 Multi-track MIDI sequencer. Arranger { /// Number of scenes - #[arg(short = 'y', long, default_value_t = 8)] scenes: usize, + #[arg(short = 'y', long, default_value_t = 4)] scenes: usize, /// Number of tracks #[arg(short = 'x', long, default_value_t = 4)] tracks: usize, /// Width of tracks diff --git a/crates/device/src/arranger/arranger_scenes.rs b/crates/device/src/arranger/arranger_scenes.rs index f14d686f..941b99ba 100644 --- a/crates/device/src/arranger/arranger_scenes.rs +++ b/crates/device/src/arranger/arranger_scenes.rs @@ -22,8 +22,7 @@ pub trait ArrangerSceneRows: Send + Sync { fn width_side (&self) -> u16; fn width_mid (&self) -> u16; fn scenes_names (&self) -> impl Content { - let h = self.scenes_with_prev_color().last().map(|(_,_,_,h,_)|h as u16).unwrap_or(0); - Fixed::y(h, Map::new(move||self.scenes_with_prev_color(), + Map::new(move||self.scenes_with_prev_color(), move|(s, scene, y1, y2, previous): SceneWith<'_, Option>, _|{ let height = (1 + y2 - y1) as u16; let name = Some(scene.name.clone()); @@ -47,25 +46,16 @@ pub trait ArrangerSceneRows: Send + Sync { Fill::x(map_south(y1 as u16, height, Fixed::y(height, Phat { width: 0, height: 0, content, colors: [fg, bg, hi, lo] }))) - })) + }) } fn scenes_with_prev_color (&self) -> impl Iterator>> + Send + Sync { self.scenes_iter().map(|(s, scene, y1, y2)|(s, scene, y1, y2, - (s>0).then(||self.arrangement().scenes()[s-1].color))) - } - fn per_track <'a, T: Content + 'a, U: TracksSizes<'a>> ( - tracks: impl Fn() -> U + Send + Sync + 'a, - callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a - ) -> impl Content + 'a { - Map::new(tracks, move|(index, track, x1, x2): (usize, &'a Track, usize, usize), _|{ - Tui::fg_bg(track.color.lightest.rgb, track.color.darker.rgb, - map_east(x1 as u16, (x2 - x1) as u16, callback(index, track))) }) + (s>0).then_some(self.arrangement().scenes()[s-1].color))) } fn scenes_clips <'a> (&'a self, editor: &'a Option) -> impl Content + 'a { - let h = self.scenes_with_prev_color().last().map(|(_,_,_,h,_)|h as u16).unwrap_or(0); - Fixed::y(h, Self::per_track(||self.tracks_with_sizes_scrolled(), + per_track(||self.tracks_with_sizes_scrolled(), move|track_index, track|Map::new(move||self.scenes_with_clip(track_index), move|(s, scene, y1, y2, previous): SceneWith<'_, Option>, _|{ let (name, theme) = if let Some(clip) = &scene.clips[track_index] { @@ -74,6 +64,7 @@ pub trait ArrangerSceneRows: Send + Sync { } else { (None, ItemTheme::G[32]) }; + let height = (1 + y2 - y1) as u16; let content = Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⏹ ", name)))); let same_track = self.track_selected() == Some(track_index); let selected = same_track && self.scene_selected() == Some(s); @@ -82,7 +73,11 @@ pub trait ArrangerSceneRows: Send + Sync { let fg = theme.lightest.rgb; let bg = if selected { theme.light } else { theme.base }.rgb; let hi = if let Some(previous) = previous { - if neighbor { previous.light.rgb } else { previous.base.rgb } + if neighbor { + previous.light.rgb + } else { + previous.base.rgb + } } else { Reset }; @@ -93,18 +88,17 @@ pub trait ArrangerSceneRows: Send + Sync { } else { theme.base.rgb }; - let height = (1 + y2 - y1) as u16; map_south(y1 as u16, height, Bsp::b(Fixed::y(height, Phat { width: 0, height: 0, content, colors: [fg, bg, hi, lo] }), When( self.is_editing() && same_track && self.scene_selected() == Some(s), editor ))) - }))) + })) } fn scenes_with_clip (&self, track_index: usize) -> impl Iterator>> + Send + Sync { self.scenes_iter().map(move|(s, scene, y1, y2)|(s, scene, y1, y2, - (s>0).then(||self.arrangement().scenes()[s-1].clips[track_index].as_ref() + (s>0).then_some(self.arrangement().scenes()[s-1].clips[track_index].as_ref() .map(|c|c.read().unwrap().color) .unwrap_or(ItemTheme::G[32])))) } diff --git a/crates/device/src/editor/editor_model.rs b/crates/device/src/editor/editor_model.rs index f7495032..c0444a9b 100644 --- a/crates/device/src/editor/editor_model.rs +++ b/crates/device/src/editor/editor_model.rs @@ -106,7 +106,7 @@ impl MidiViewer for MidiEditor { pub trait HasEditor { fn editor (&self) -> Option<&MidiEditor>; fn editor_mut (&mut self) -> Option<&mut MidiEditor>; - fn is_editing (&self) -> bool { self.editor().is_some() } + fn is_editing (&self) -> bool { true } fn editor_w (&self) -> usize { 0 } fn editor_h (&self) -> usize { 0 } } diff --git a/deps/tengri b/deps/tengri index 4ff4ea81..c954965a 160000 --- a/deps/tengri +++ b/deps/tengri @@ -1 +1 @@ -Subproject commit 4ff4ea81735548f808302c61b619ad7804e1eec0 +Subproject commit c954965ae125136286291e5f0d4532edf98f46ad