almost compiles
Some checks failed
/ build (push) Has been cancelled

the long-standing architectural issues
around how the Draw, Layout, and Content
traits from Tengri should, well, actually work -
that has subsided for now. somewhat.

going to amend this commit with fixes to
the remaining import not founds,
and then... what?
This commit is contained in:
🪞👃🪞 2025-09-29 06:50:40 +03:00
parent ef81b085a0
commit e6bf5c1f6e
4 changed files with 79 additions and 60 deletions

View file

@ -1,6 +1,6 @@
pub(crate) use ::{
tek_device::*,
tek_device::tengri::{
tengri::{
Usually, Perhaps, Has, MaybeHas, has, maybe_has, impl_debug, from,
dsl::*,
input::*,
@ -8,7 +8,9 @@ pub(crate) use ::{
tui::{
*,
ratatui::{
self, prelude::{Style, Stylize, Buffer, Modifier, buffer::Cell, Color::{self, *}}
self,
prelude::{Rect, Style, Stylize, Buffer, Modifier, buffer::Cell, Color::{self, *}},
widgets::{Widget, canvas::{Canvas, Line}},
},
crossterm::{
self,
@ -31,6 +33,5 @@ pub(crate) use ::{
thread::JoinHandle
},
xdg::BaseDirectories,
atomic_float::*,
tengri::tui::ratatui::{prelude::Rect, widgets::{Widget, canvas::{Canvas, Line}}},
atomic_float::*
};

2
deps/tengri vendored

@ -1 +1 @@
Subproject commit 41fa55fa6ca15abd0a80fd50a30326b1fea6b5f1
Subproject commit 8c54510f630e8a81b7d7bdca0a51a69cdb9dffcc

View file

@ -118,7 +118,7 @@ pub trait ScenesView:
})
}
fn view_scenes_names (&self) -> impl Content<TuiOut> {
Fixed::x(20, Thunk::new(|to: &mut TuiOut|for (index, scene, ..) in self.scenes_with_sizes() {
Fixed::X(20, Thunk::new(|to: &mut TuiOut|for (index, scene, ..) in self.scenes_with_sizes() {
to.place(&self.view_scene_name(index, scene));
}))
}
@ -182,7 +182,7 @@ impl Scene {
match self.clips.get(index) { Some(Some(clip)) => Some(clip), _ => None }
}
}
//scene_scroll: Fill::Y(Fixed::x(1, ScrollbarV {
//scene_scroll: Fill::Y(Fixed::X(1, ScrollbarV {
//offset: arrangement.scene_scroll,
//length: h_scenes_area as usize,
//total: h_scenes as usize,

View file

@ -1,6 +1,6 @@
use crate::*;
def_sizes_iter!(TracksSizes => Track);
def_sizes_iter!(TracksSizes => Track);
impl<T: Has<Vec<Track>> + Send + Sync> HasTracks for T {}
@ -36,33 +36,41 @@ pub trait HasTracks: Has<Vec<Track>> + Send + Sync {
const TRACK_SPACING: usize = 0;
}
pub trait HasTrackScroll: HasTracks { fn track_scroll (&self) -> usize; }
impl HasTrackScroll for Arrangement { fn track_scroll (&self) -> usize { self.track_scroll } }
pub trait HasTrackScroll: HasTracks {
fn track_scroll (&self) -> usize;
}
impl HasTrackScroll for Arrangement {
fn track_scroll (&self) -> usize {
self.track_scroll
}
}
pub trait HasTrack {
fn track (&self) -> Option<&Track>;
fn track_mut (&mut self) -> Option<&mut Track>;
#[cfg(feature = "port")] fn view_midi_ins_status <'a> (&'a self, theme: ItemTheme) -> impl Content<TuiOut> + 'a {
self.track().map(move|track|view_ports_status(theme, "MIDI ins: ", &track.sequencer.midi_ins))
}
#[cfg(feature = "port")] fn view_midi_outs_status (&self, theme: ItemTheme) -> impl Content<TuiOut> + '_ {
self.track().map(move|track|view_ports_status(theme, "MIDI outs: ", &track.sequencer.midi_outs))
}
#[cfg(feature = "port")] fn view_audio_ins_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().map(move|track|view_ports_status(theme, "Audio ins: ", &track.audio_ins()))
}
#[cfg(feature = "port")] fn view_audio_outs_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().map(move|track|view_ports_status(theme, "Audio outs:", &track.audio_outs()))
}
}
impl<T: MaybeHas<Track>> HasTrack for T {
fn track (&self) -> Option<&Track> { self.get() }
fn track_mut (&mut self) -> Option<&mut Track> { self.get_mut() }
fn track (&self) -> Option<&Track> {
self.get()
}
fn track_mut (&mut self) -> Option<&mut Track> {
self.get_mut()
}
}
impl Track {
fn _todo_opt_bool_stub_ (&self) -> Option<bool> { todo!() }
fn _todo_usize_stub_ (&self) -> usize { todo!() }
fn _todo_arc_str_stub_ (&self) -> Arc<str> { todo!() }
fn _todo_item_theme_stub (&self) -> ItemTheme { todo!() }
}
def_command!(TrackCommand: |track: Track| {
Stop => { track.sequencer.enqueue_next(None); Ok(None) },
SetMute { mute: Option<bool> } => todo!(),
SetSolo { solo: Option<bool> } => todo!(),
SetSize { size: usize } => todo!(),
SetZoom { zoom: usize } => todo!(),
SetName { name: Arc<str> } =>
swap_value(&mut track.name, name, |name|Self::SetName { name }),
SetColor { color: ItemTheme } =>
swap_value(&mut track.color, color, |color|Self::SetColor { color }),
SetRec { rec: Option<bool> } =>
toggle_bool(&mut track.sequencer.recording, rec, |rec|Self::SetRec { rec }),
SetMon { mon: Option<bool> } =>
toggle_bool(&mut track.sequencer.monitoring, mon, |mon|Self::SetMon { mon }),
});
#[derive(Debug, Default)]
pub struct Track {
@ -80,13 +88,6 @@ pub struct Track {
has!(Clock: |self: Track|self.sequencer.clock);
has!(Sequencer: |self: Track|self.sequencer);
impl HasWidth for Track {
const MIN_WIDTH: usize = 9;
fn width_inc (&mut self) { self.width += 1; }
fn width_dec (&mut self) { if self.width > Track::MIN_WIDTH { self.width -= 1; } }
}
impl Track {
/// Create a new track with only the default [Sequencer].
pub fn new (
@ -105,7 +106,24 @@ impl Track {
..Default::default()
})
}
fn audio_ins (&self) -> &[AudioInput] {
self.devices.first().map(|x|x.audio_ins()).unwrap_or_default()
}
fn audio_outs (&self) -> &[AudioOutput] {
self.devices.last().map(|x|x.audio_outs()).unwrap_or_default()
}
fn _todo_opt_bool_stub_ (&self) -> Option<bool> { todo!() }
fn _todo_usize_stub_ (&self) -> usize { todo!() }
fn _todo_arc_str_stub_ (&self) -> Arc<str> { todo!() }
fn _todo_item_theme_stub (&self) -> ItemTheme { todo!() }
}
impl HasWidth for Track {
const MIN_WIDTH: usize = 9;
fn width_inc (&mut self) { self.width += 1; }
fn width_dec (&mut self) { if self.width > Track::MIN_WIDTH { self.width -= 1; } }
}
#[cfg(feature = "sampler")]
impl Track {
/// Create a new track connecting the [Sequencer] to a [Sampler].
@ -148,23 +166,21 @@ impl Track {
None
}
}
pub trait HasTrack {
fn track (&self) -> Option<&Track>;
fn track_mut (&mut self) -> Option<&mut Track>;
#[cfg(feature = "port")] fn view_midi_ins_status <'a> (&'a self, theme: ItemTheme) -> impl Content<TuiOut> + 'a {
self.track().map(move|track|view_ports_status(theme, "MIDI ins: ", &track.sequencer.midi_ins))
}
#[cfg(feature = "port")] fn view_midi_outs_status (&self, theme: ItemTheme) -> impl Content<TuiOut> + '_ {
self.track().map(move|track|view_ports_status(theme, "MIDI outs: ", &track.sequencer.midi_outs))
}
#[cfg(feature = "port")] fn view_audio_ins_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().map(move|track|view_ports_status(theme, "Audio ins: ", &track.audio_ins()))
}
#[cfg(feature = "port")] fn view_audio_outs_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().map(move|track|view_ports_status(theme, "Audio outs:", &track.audio_outs()))
}
}
def_command!(TrackCommand: |track: Track| {
Stop => { track.sequencer.enqueue_next(None); Ok(None) },
SetMute { mute: Option<bool> } => todo!(),
SetSolo { solo: Option<bool> } => todo!(),
SetSize { size: usize } => todo!(),
SetZoom { zoom: usize } => todo!(),
SetName { name: Arc<str> } =>
swap_value(&mut track.name, name, |name|Self::SetName { name }),
SetColor { color: ItemTheme } =>
swap_value(&mut track.color, color, |color|Self::SetColor { color }),
SetRec { rec: Option<bool> } =>
toggle_bool(&mut track.sequencer.recording, rec, |rec|Self::SetRec { rec }),
SetMon { mon: Option<bool> } =>
toggle_bool(&mut track.sequencer.monitoring, mon, |mon|Self::SetMon { mon }),
});
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
@ -268,13 +284,15 @@ fn view_track_header (theme: ItemTheme, content: impl Content<TuiOut>) -> impl C
Fixed::X(12, Tui::bg(theme.darker.rgb, Fill::X(Align::e(content))))
}
fn view_ports_status <T: JackPort> (theme: ItemTheme, title: &str, ports: &[T]) {
fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, ports: &'a [T])
-> impl Content<TuiOut> + use<'a, T>
{
let ins = ports.len() as u16;
let frame = Outer(true, Style::default().fg(Tui::g(96)));
let iter = move||ports.iter();
let names = Map::south(1, iter, |port, index|Fill::Y(Align::w(format!(" {index} {}", port.port_name()))));
let names = Map::south(1, iter, move|port, index|Fill::Y(Align::w(format!(" {index} {}", port.port_name()))));
let field = FieldV(theme, title, names);
Fixed::XY(20, 1 + ins, frame.enclose(Fixed::XY(20, 1 + ins, field.content())))
Fixed::XY(20, 1 + ins, frame.enclose(Fixed::XY(20, 1 + ins, field)))
}
impl Track {