From 62bfb0120b886755952ea7f19a5a183d96d6311f Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 17 May 2025 17:05:11 +0300 Subject: [PATCH] polite outline --- crates/app/src/view.rs | 20 +- crates/device/src/arranger/arranger_model.rs | 2 +- crates/device/src/arranger/arranger_view.rs | 208 +++++++++---------- 3 files changed, 109 insertions(+), 121 deletions(-) diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index fbb50f1b..35239af1 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -115,28 +115,16 @@ impl App { ) } pub fn view_arranger_inputs <'a> (&'a self) -> impl Content + use<'a> { - Fixed::y(3, Bsp::e( - Fixed::x(20, Tui::bg(self.color.darker.rgb, Fill::xy(""))), - self.project.view_track_inputs(self.color) - )) + Fixed::y(3, self.project.view_track_inputs(self.color)) } pub fn view_arranger_outputs <'a> (&'a self) -> impl Content + use<'a> { - Fixed::y(3, Bsp::e( - Fixed::x(20, Tui::bg(self.color.darker.rgb, Fill::xy(""))), - self.project.view_track_outputs(self.color) - )) + Fixed::y(3, self.project.view_track_outputs(self.color)) } pub fn view_arranger_devices <'a> (&'a self) -> impl Content + use<'a> { - Fixed::y(3, Bsp::e( - Fixed::x(20, Tui::bg(self.color.darker.rgb, Fill::xy(""))), - self.project.view_track_devices(self.color) - )) + Fixed::y(3, self.project.view_track_devices(self.color)) } pub fn view_arranger_tracks <'a> (&'a self) -> impl Content + use<'a> { - Fixed::y(2, Bsp::e( - Fixed::x(20, Tui::bg(self.color.darker.rgb, Fill::xy(""))), - self.project.view_track_names(self.color) - )) + Fixed::y(3, self.project.view_track_names(self.color)) } pub fn view_arranger_track_names (&self) -> impl Content + use<'_> { self.project.view_track_names(self.color) diff --git a/crates/device/src/arranger/arranger_model.rs b/crates/device/src/arranger/arranger_model.rs index a1717211..5c3bb4d1 100644 --- a/crates/device/src/arranger/arranger_model.rs +++ b/crates/device/src/arranger/arranger_model.rs @@ -157,7 +157,7 @@ impl Arrangement { mouts: &[PortConnect], ) -> Usually<(usize, &mut Track)> { let name: Arc = name.map_or_else( - ||format!("t{:02}", self.track_last).into(), + ||format!("trk{:02}", self.track_last).into(), |x|x.to_string().into() ); self.track_last += 1; diff --git a/crates/device/src/arranger/arranger_view.rs b/crates/device/src/arranger/arranger_view.rs index 4beee14d..90240754 100644 --- a/crates/device/src/arranger/arranger_view.rs +++ b/crates/device/src/arranger/arranger_view.rs @@ -12,16 +12,10 @@ pub trait TracksView: /// Iterate over tracks with their corresponding sizes. fn tracks_with_sizes (&self) -> impl TracksSizes<'_> { let editor_width = self.editor().map(|e|e.width()); - let active_track = if let Some(width) = editor_width { - self.selection().track() - } else { - None - }; + let active_track = self.selection().track(); let mut x = 0; self.tracks().iter().enumerate().map(move |(index, track)|{ - let width = active_track - .and_then(|_|editor_width) - .unwrap_or(track.width.max(8)); + let width = active_track.and_then(|_|editor_width).unwrap_or(track.width.max(8)); let data = (index, track, x, x + width); x += width + Self::TRACK_SPACING; data @@ -34,78 +28,87 @@ pub trait TracksView: ((x2 as u16) < self.tracks_width_available()) .then_some((t, track, x1, x2))) } + fn view_track_row_section <'a> ( + &'a self, + theme: ItemTheme, + button: impl Content, + button_add: impl Content, + content: impl Content + ) -> impl Content { + Bsp::w( + Fixed::x(4, button_add), + Bsp::e( + Fixed::x(20, Align::w(button)), + content + ) + ) + } fn view_track_header <'a, T: Content> ( &'a self, theme: ItemTheme, content: T ) -> impl Content { Fixed::x(12, Tui::bg(theme.darker.rgb, Fill::x(Align::e(content)))) } fn view_track_names (&self, theme: ItemTheme) -> impl Content { - let content = Fixed::y(1, Align::w(Tui::bg(theme.darker.rgb, Align::w(Fill::x( - Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ - for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::x(track.width as u16, - Tui::bg(if self.selection().track() == Some(index) { - track.color.light.rgb - } else { - track.color.base.rgb - }, Align::nw(Tui::fg( - Rgb(255, 255, 255), Tui::bold(true, - format!("{}", track.name))))))); - } - })))))); - Bsp::w( - self.view_track_header(theme, row!( - Tui::bold(true, button_2("t", "rack ", false)), - button_2("T", "+", false) - )), - content - ) - } - fn view_track_outputs <'a> (&'a self, theme: ItemTheme) -> impl Content { - let mut max_outputs = 0u16; - for track in self.tracks().iter() { - max_outputs = max_outputs.max(track.sequencer.midi_outs.len() as u16); - } - let content = Align::w(Fixed::y(1 + max_outputs*2, - Tui::bg(theme.darker.rgb, Align::w(Fill::x( + self.view_track_row_section( + theme, + button_2("t", "rack", false), + button_2("T", "+", false), + Fixed::y(1, Align::w(Tui::bg(theme.darker.rgb, Align::w(Fill::x( Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::x(track.width as u16, Align::nw(Bsp::n( + add(&Fixed::x(track.width as u16, Tui::bg(if self.selection().track() == Some(index) { track.color.light.rgb } else { track.color.base.rgb - }, Fill::x(Align::w(format!("·mute ·solo")))), - Map::south(2, ||track.sequencer.midi_outs.iter(), - |port, index|Tui::fg(Rgb(255, 255, 255), - Fixed::y(2, Tui::bg(track.color.dark.rgb, Fill::x(Align::w( - format!("·o{index}: {}", port.name()))))))))))); + }, Align::nw(Bsp::e( + format!("·t{index:02} "), + Tui::fg(Rgb(255, 255, 255), Tui::bold(true, &track.name)) + ))))); } - })))))); - Bsp::w( - self.view_track_header(theme, row!( - Tui::bold(true, button_2("o", "utput", false)), - button_2("O", "+", false) - )), - content - ) + }))))))) + } + fn view_track_outputs <'a> (&'a self, theme: ItemTheme) -> impl Content { + let mut h = 0u16; + for track in self.tracks().iter() { + h = h.max(track.sequencer.midi_outs.len() as u16); + } + self.view_track_row_section( + theme, + button_2("o", "utput", false), + button_2("O", "+", false), + Align::w(Fixed::y(1 + h*2, + Tui::bg(theme.darker.rgb, Align::w(Fill::x( + Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ + for (index, track, x1, x2) in self.tracks_with_sizes() { + add(&Fixed::x(track.width as u16, Align::nw(Bsp::n( + Tui::bg(if self.selection().track() == Some(index) { + track.color.light.rgb + } else { + track.color.base.rgb + }, Fill::x(Align::w(format!("·mute ·solo")))), + Map::south(2, ||track.sequencer.midi_outs.iter(), + |port, index|Tui::fg(Rgb(255, 255, 255), + Fixed::y(2, Tui::bg(track.color.dark.rgb, Fill::x(Align::w( + format!("·o{index:02} {}", port.name()))))))))))); + } + }))))))) } fn view_track_devices <'a> (&'a self, theme: ItemTheme) -> impl Content { let mut h = 2u16; for track in self.tracks().iter() { h = h.max(track.devices.len() as u16); } - Bsp::w( - self.view_track_header(theme, row!( - Tui::bold(true, button_2("d", "evice", false)), - button_2("D", "+", false) - )), + self.view_track_row_section( + theme, + button_2("d", "evice", false), + button_2("D", "+", false), Fixed::y(h, Tui::bg(theme.darker.rgb, Align::w(Fill::x(Stack::east( move|add: &mut dyn FnMut(&dyn Render)|{ for (index, track, x1, x2) in self.tracks_with_sizes() { add(&Fixed::xy(track.width as u16, h + 1, Tui::bg(track.color.dark.rgb, Align::nw(Map::south(1, move||0..h, - |_, index|format!("·d{index}: {}", "--------")))))); + |_, index|format!("·d{index:02} {}", "--------")))))); } })))))) } @@ -114,26 +117,21 @@ pub trait TracksView: for track in self.tracks().iter() { h = h.max(track.sequencer.midi_ins.len() as u16); } - let content = Tui::bg(theme.darker.rgb, Align::w(Fill::x( - Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ - for (index, track, x1, x2) in self.tracks_with_sizes() { - add(&Fixed::xy(track.width as u16, h + 1, - Align::nw(Bsp::s( - Tui::bg(track.color.base.rgb, - Fill::x(Align::w(format!("·mon ·rec ·dub")))), - Map::south(1, ||track.sequencer.midi_ins.iter(), - |port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb, - Fill::x(Align::w(format!("·i{index}: {}", port.name()))))))))); - } - - })))); - Bsp::w( - self.view_track_header(theme, row!( - Tui::bold(true, button_2("i", "nputs", false)), - button_2("I", "+", false) - )), - Fixed::y(h, Fill::x(Align::w(Fixed::y(h + 1, content)))), - ) + self.view_track_row_section( + theme, + button_2("i", "nput", false), + button_2("I", "+", false), + Tui::bg(theme.darker.rgb, Align::w(Fill::x( + Stack::east(move|add: &mut dyn FnMut(&dyn Render)|{ + for (index, track, x1, x2) in self.tracks_with_sizes() { + add(&Fixed::xy(track.width as u16, h + 1, + Align::nw(Bsp::s( + Tui::bg(track.color.base.rgb, + Fill::x(Align::w(format!("·mon ·rec ·dub")))), + Map::south(1, ||track.sequencer.midi_ins.iter(), + |port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb, + Fill::x(Align::w(format!("·i{index:02} {}", port.name()))))))))); + }}))))) } } @@ -165,8 +163,8 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync { }; Fixed::xy(20, h, Tui::bg(bg, Align::nw(Bsp::s( Fill::x(Align::w(Bsp::e( - format!(" {index:2} "), - Tui::fg(Rgb(255, 255, 255), Tui::bold(true, format!("{}", scene.name))) + format!("·s{index:02} "), + Tui::fg(Rgb(255, 255, 255), Tui::bold(true, &scene.name)) ))), When(self.selection().scene() == Some(index) && self.is_editing(), Fill::xy(Align::nw(Bsp::s( @@ -202,18 +200,18 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync { fn view_track_clips <'a> (&'a self, track_index: usize, track: &'a Track) -> impl Content + 'a { Stack::south(move|cell: &mut dyn FnMut(&dyn Render)|{ for (scene_index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) { - let (name, theme) = if let Some(Some(clip)) = &scene.clips.get(track_index) { + let (name, theme): (Arc, ItemTheme) = if let Some(Some(clip)) = &scene.clips.get(track_index) { let clip = clip.read().unwrap(); - (Some(clip.name.clone()), clip.color) + (clip.name.clone(), clip.color) } else { - (None, ItemTheme::G[32]) + (" ---- ".into(), ItemTheme::G[32]) }; let fg = theme.lightest.rgb; let mut outline = theme.base.rgb; let bg = if self.selection().track() == Some(track_index) && self.selection().scene() == Some(scene_index) { - outline = theme.lightest.rgb; + outline = theme.lighter.rgb; theme.light.rgb } else if self.selection().track() == Some(track_index) || self.selection().scene() == Some(scene_index) @@ -223,28 +221,30 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync { } else { theme.dark.rgb }; - cell(&Fixed::xy( - if self.selection().track() == Some(track_index) - && let Some(editor) = self.editor () - { - editor.width().max(24).max(track.width) - } else { - track.width - } as u16, - if self.selection().scene() == Some(scene_index) - && let Some(editor) = self.editor () - { - editor.height().max(12) - } else { - Self::H_SCENE - } as u16, - Bsp::b( - Fill::xy(Outer(true, Style::default().fg(outline))), - Fill::xy(Bsp::b( - Fill::xy(Align::nw(Tui::fg_bg(fg, bg, Align::nw(name.unwrap_or(" ---- ".into()))))), - Fill::xy(When(self.selection().track() == Some(track_index) - && self.selection().scene() == Some(scene_index) - && self.is_editing(), self.editor()))))))); + let w = if self.selection().track() == Some(track_index) + && let Some(editor) = self.editor () + { + editor.width().max(24).max(track.width) + } else { + track.width + } as u16; + let y = if self.selection().scene() == Some(scene_index) + && let Some(editor) = self.editor () + { + editor.height().max(12) + } else { + Self::H_SCENE + } as u16; + cell(&Fixed::xy(w, y, Bsp::b( + Fill::xy(Outer(true, Style::default().fg(outline))), + Fill::xy(Bsp::b( + Bsp::b( + Tui::fg_bg(outline, bg, Fill::xy("")), + Fill::xy(Align::nw(Tui::fg_bg(fg, bg, Tui::bold(true, name)))), + ), + Fill::xy(When(self.selection().track() == Some(track_index) + && self.selection().scene() == Some(scene_index) + && self.is_editing(), self.editor()))))))); //let (name, theme) = if let Some(clip) = &scene.clips.get(track_index).flatten() { //let clip = clip.read().unwrap(); //(Some(clip.name.clone()), clip.color)