confine the messy part mainly to view::view_ports

This commit is contained in:
🪞👃🪞 2025-03-15 23:40:47 +02:00
parent 3d290a9beb
commit 70ad0b343b
8 changed files with 611 additions and 600 deletions

View file

@ -1,16 +1,13 @@
use crate::*;
mod view_arranger; pub use self::view_arranger::*;
mod view_clock; pub use self::view_clock::*;
mod view_color; pub use self::view_color::*;
mod view_iter; pub use self::view_iter::*;
mod view_memo; pub use self::view_memo::*;
mod view_meter; pub use self::view_meter::*;
mod view_sizes; pub use self::view_sizes::*;
mod view_track; pub use self::view_track::*;
mod view_scene; pub use self::view_scene::*;
mod view_input; pub use self::view_input::*;
mod view_output; pub use self::view_output::*;
mod view_layout; pub use self::view_layout::*;
mod view_clock; pub use self::view_clock::*;
mod view_color; pub use self::view_color::*;
mod view_iter; pub use self::view_iter::*;
mod view_memo; pub use self::view_memo::*;
mod view_meter; pub use self::view_meter::*;
mod view_sizes; pub use self::view_sizes::*;
mod view_track; pub use self::view_track::*;
mod view_ports; pub use self::view_ports::*;
mod view_layout; pub use self::view_layout::*;
pub(crate) use std::fmt::Write;
pub(crate) use ::tengri::tui::ratatui::prelude::Position;
pub(crate) trait ScenesColors<'a> = Iterator<Item=SceneWithColor<'a>>;
@ -21,7 +18,7 @@ view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); {
//":scene-add" => self.view_scene_add().boxed(),
//":scenes" => self.view_scenes().boxed(),
//":tracks" => self.view_tracks().boxed(),
":arranger" => self.view_arranger().boxed(),
":arranger" => ArrangerView::new(self).boxed(),
":editor" => self.editor.as_ref().map(|e|Bsp::e(e.clip_status(), e.edit_status())).boxed(),
":sample" => ().boxed(),//self.view_sample(self.is_editing()).boxed(),
":sampler" => ().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(),
@ -41,78 +38,82 @@ provide_num!(u16: |self: Tek| {
":y-outs" => (self.size.h() as u16).saturating_sub(self.h_outputs() + 1),
":y-samples" => if self.is_editing() { 1 } else { 0 },
});
pub(crate) fn wrap (
bg: Color,
fg: Color,
content: impl Content<TuiOut>
) -> impl Content<TuiOut> {
Bsp::e(Tui::fg_bg(bg, Reset, ""),
Bsp::w(Tui::fg_bg(bg, Reset, ""),
Tui::fg_bg(fg, bg, content)))
pub(crate) struct ArrangerView<'a> {
app: &'a Tek,
is_editing: bool,
width_total: u16,
width_mid: u16,
width_side: u16,
inputs_count: usize,
inputs_height: u16,
outputs_count: usize,
outputs_height: u16,
scene_last: u16,
scene_scroll: u16,
scene_selected: Option<usize>,
scenes_height: u16,
track_scroll: u16,
track_selected: Option<usize>,
tracks_height: u16,
}
pub(crate) fn button_2 <'a, K, L> (
key: K,
label: L,
editing: bool,
) -> impl Content<TuiOut> + 'a where
K: Content<TuiOut> + 'a,
L: Content<TuiOut> + 'a,
{
let key = Tui::fg_bg(Tui::g(0), Tui::orange(), Bsp::e(
Tui::fg_bg(Tui::orange(), Reset, ""),
Bsp::e(key, Tui::fg(Tui::g(96), ""))
));
let label = When::new(!editing, Tui::fg_bg(Tui::g(255), Tui::g(96), label));
Tui::bold(true, Bsp::e(key, label))
}
pub(crate) fn button_3 <'a, K, L, V> (
key: K,
label: L,
value: V,
editing: bool,
) -> impl Content<TuiOut> + 'a where
K: Content<TuiOut> + 'a,
L: Content<TuiOut> + 'a,
V: Content<TuiOut> + 'a,
{
let key = Tui::fg_bg(Tui::g(0), Tui::orange(),
Bsp::e(Tui::fg_bg(Tui::orange(), Reset, ""), Bsp::e(key, Tui::fg(if editing {
Tui::g(128)
} else {
Tui::g(96)
}, ""))));
let label = Bsp::e(
When::new(!editing, Bsp::e(
Tui::fg_bg(Tui::g(255), Tui::g(96), label),
Tui::fg_bg(Tui::g(128), Tui::g(96), ""),
)),
Bsp::e(
Tui::fg_bg(Tui::g(224), Tui::g(128), value),
Tui::fg_bg(Tui::g(128), Reset, ""),
));
Tui::bold(true, Bsp::e(key, label))
}
fn heading <'a> (
key: &'a str,
label: &'a str,
count: usize,
content: impl Content<TuiOut> + Send + Sync + 'a,
editing: bool,
) -> impl Content<TuiOut> + 'a {
let count = format!("{count}");
Fill::xy(Align::w(Bsp::s(Fill::x(Align::w(button_3(key, label, count, editing))), content)))
}
#[cfg(test)] mod test {
use super::*;
#[test] fn test_view () {
let _ = button_2("", "", true);
let _ = button_2("", "", false);
let _ = button_3("", "", "", true);
let _ = button_3("", "", "", false);
let _ = heading("", "", 0, "", true);
let _ = heading("", "", 0, "", false);
let _ = wrap(Reset, Reset, "");
let _ = row(0, 0, 0, "", "", "");
let _ = row_top(0, 0, 0, "", "", "");
impl<'a> Content<TuiOut> for ArrangerView<'a> {
fn content (&self) -> impl Render<TuiOut> {
Bsp::s(self.inputs(),
Bsp::s(self.tracks(),
Bsp::n(self.outputs(), self.scenes())))
}
}
impl<'a> ArrangerView<'a> {
fn new (app: &'a Tek) -> Self {
Self {
app,
is_editing: app.is_editing(),
width_total: app.w(),
width_mid: app.w_tracks_area(),
width_side: app.w_sidebar(),
inputs_height: app.h_inputs().saturating_sub(1),
inputs_count: app.midi_ins.len(),
outputs_height: app.h_outputs().saturating_sub(1),
outputs_count: app.midi_outs.len(),
scenes_height: app.h_scenes(),
scene_selected: app.selected().scene(),
scene_last: app.scenes.len().saturating_sub(1),
scene_scroll: Fill::y(Fixed::x(1, ScrollbarV {
offset: app.scene_scroll,
length: app.h_tracks_area() as usize,
total: app.h_scenes() as usize,
})),
tracks_height: app.h_tracks_area(),
track_selected: app.selected().track(),
track_scroll: Fill::y(Fixed::x(1, ScrollbarV {
offset: app.scene_scroll,
length: app.h_tracks_area() as usize,
total: app.h_scenes() as usize,
})),
}
}
pub(crate) fn inputs_with_sizes (&'a self) -> impl PortsSizes<'a> {
self.app.inputs_sizes()
}
pub(crate) fn outputs_with_sizes (&'a self) -> impl PortsSizes<'a> {
self.app.outputs_sizes()
}
pub(crate) fn tracks_with_sizes (&'a self) -> impl TracksSizes<'a> {
self.app.tracks_sizes_scrolled()
}
}