fine detour!

This commit is contained in:
🪞👃🪞 2025-05-17 06:05:40 +03:00
parent 4f6cb7cb8e
commit 0733742685
8 changed files with 68 additions and 58 deletions

View file

@ -18,7 +18,8 @@
#![feature(closure_lifetime_binder)] #![feature(closure_lifetime_binder)]
pub use ::tek_engine:: *; pub use ::tek_engine:: *;
pub use ::tek_device::{self, *}; pub use ::tek_device::{self, *};
pub use ::tengri::{Usually, Perhaps, Has}; pub use ::tengri::{Usually, Perhaps, Has, MaybeHas};
pub use ::tengri::{has, maybe_has};
pub use ::tengri::dsl::*; pub use ::tengri::dsl::*;
pub use ::tengri::input::*; pub use ::tengri::input::*;
pub use ::tengri::output::*; pub use ::tengri::output::*;

View file

@ -36,6 +36,12 @@ has!(Vec<JackMidiOut>: |self: App|self.project.midi_outs);
has!(Vec<Scene>: |self: App|self.project.scenes); has!(Vec<Scene>: |self: App|self.project.scenes);
has!(Vec<Track>: |self: App|self.project.tracks); has!(Vec<Track>: |self: App|self.project.tracks);
has!(Measure<TuiOut>: |self: App|self.size); has!(Measure<TuiOut>: |self: App|self.size);
maybe_has!(Track: |self: App|
{ MaybeHas::<Track>::get(&self.project) };
{ MaybeHas::<Track>::get_mut(&mut self.project) });
maybe_has!(Scene: |self: App|
{ MaybeHas::<Scene>::get(&self.project) };
{ MaybeHas::<Scene>::get_mut(&mut self.project) });
has_clips!(|self: App|self.project.pool.clips); has_clips!(|self: App|self.project.pool.clips);
has_editor!(|self: App|{ has_editor!(|self: App|{

View file

@ -61,45 +61,20 @@ impl App {
self.editor() self.editor()
} }
pub fn view_editor_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_editor_status (&self) -> impl Content<TuiOut> + use<'_> {
self.editor().map(|e|Bsp::s(e.clip_status(), e.edit_status())) self.editor().map(|e|Fixed::x(20, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fill::y(Align::n(Bsp::s(e.clip_status(), e.edit_status()))))))
} }
pub fn view_midi_ins_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_midi_ins_status (&self) -> impl Content<TuiOut> + use<'_> {
self.project.get_track().map(|track|{ self.project.view_midi_ins_status(self.color)
let ins = track.sequencer.midi_ins.len() as u16;
Fixed::xy(20, 1 + ins, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + ins, FieldV(self.color, format!("MIDI ins: "),
Map::south(1, ||track.sequencer.midi_ins.iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))
})
} }
pub fn view_midi_outs_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_midi_outs_status (&self) -> impl Content<TuiOut> + use<'_> {
self.project.get_track().map(|track|{ self.project.view_midi_outs_status(self.color)
let outs = track.sequencer.midi_outs.len() as u16;
Fixed::xy(20, 1 + outs, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + outs, FieldV(self.color, format!("MIDI outs: "),
Map::south(1, ||track.sequencer.midi_outs.iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))
})
} }
pub fn view_audio_ins_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_audio_ins_status (&self) -> impl Content<TuiOut> + use<'_> {
self.project.get_track() self.project.view_audio_ins_status(self.color)
.and_then(|track|track.devices.get(0))
.map(|device|{
let ins = device.audio_ins().len() as u16;
Fixed::xy(20, 1 + ins, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + ins, FieldV(self.color, format!("Audio ins: "),
Map::south(1, ||device.audio_ins().iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))})
} }
pub fn view_audio_outs_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_audio_outs_status (&self) -> impl Content<TuiOut> + use<'_> {
self.project.get_track() self.project.view_audio_outs_status(self.color)
.and_then(|track|track.devices.last())
.map(|device|{
let outs = device.audio_outs().len() as u16;
Fixed::xy(20, 1 + outs, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + outs, FieldV(self.color, format!("Audio outs: "),
Map::south(1, ||device.audio_outs().iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))})
} }
pub fn view_arranger (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_arranger (&self) -> impl Content<TuiOut> + use<'_> {
ArrangerView::new(&self.project, self.editor.as_ref()) ArrangerView::new(&self.project, self.editor.as_ref())
@ -255,7 +230,8 @@ impl App {
self.project.sampler().map(|s|s.view_sample_info(self.editor().unwrap().get_note_pos())) self.project.sampler().map(|s|s.view_sample_info(self.editor().unwrap().get_note_pos()))
} }
pub fn view_sample_status (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_sample_status (&self) -> impl Content<TuiOut> + use<'_> {
self.project.sampler().map(|s|s.view_sample_status(self.editor().unwrap().get_note_pos())) self.project.sampler().map(|s|Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fill::y(Align::n(s.view_sample_status(self.editor().unwrap().get_note_pos())))))
} }
pub fn view_meters_input (&self) -> impl Content<TuiOut> + use<'_> { pub fn view_meters_input (&self) -> impl Content<TuiOut> + use<'_> {
self.project.sampler().map(|s|s.view_meters_input()) self.project.sampler().map(|s|s.view_meters_input())

View file

@ -192,6 +192,12 @@ impl ArrangementCommand {
} }
} }
impl<'state> Context<'state, TrackCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<TrackCommand> {
Context::get(&self, iter)
}
}
impl<'state> Context<'state, MidiInputCommand> for Arrangement { impl<'state> Context<'state, MidiInputCommand> for Arrangement {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<MidiInputCommand> { fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<MidiInputCommand> {
Context::get(&self, iter) Context::get(&self, iter)

View file

@ -47,6 +47,12 @@ has!(Vec<JackMidiOut>: |self: Arrangement|self.midi_outs);
has!(Vec<Scene>: |self: Arrangement|self.scenes); has!(Vec<Scene>: |self: Arrangement|self.scenes);
has!(Vec<Track>: |self: Arrangement|self.tracks); has!(Vec<Track>: |self: Arrangement|self.tracks);
has!(Measure<TuiOut>: |self: Arrangement|self.size); has!(Measure<TuiOut>: |self: Arrangement|self.size);
maybe_has!(Track: |self: Arrangement|
{ Has::<Selection>::get(self).track().map(|index|Has::<Vec<Track>>::get(self).get(index)).flatten() };
{ Has::<Selection>::get(self).track().map(|index|Has::<Vec<Track>>::get_mut(self).get_mut(index)).flatten() });
maybe_has!(Scene: |self: Arrangement|
{ Has::<Selection>::get(self).track().map(|index|Has::<Vec<Scene>>::get(self).get(index)).flatten() };
{ Has::<Selection>::get(self).track().map(|index|Has::<Vec<Scene>>::get_mut(self).get_mut(index)).flatten() });
impl Arrangement { impl Arrangement {
/// Width of display /// Width of display

View file

@ -1,8 +1,11 @@
use crate::*; use crate::*;
impl<'state> Context<'state, TrackCommand> for Arrangement { impl<T: MaybeHas<Track>> HasTrack for T {
fn get <'source> (&'state self, iter: &mut TokenIter<'source>) -> Option<TrackCommand> { fn track (&self) -> Option<&Track> {
Context::get(&self, iter) self.get()
}
fn track_mut (&mut self) -> Option<&mut Track> {
self.get_mut()
} }
} }
@ -152,6 +155,38 @@ impl Track {
pub trait HasTrack { pub trait HasTrack {
fn track (&self) -> Option<&Track>; fn track (&self) -> Option<&Track>;
fn track_mut (&mut self) -> Option<&mut Track>; fn track_mut (&mut self) -> Option<&mut Track>;
fn view_midi_ins_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().map(|track|{
let ins = track.sequencer.midi_ins.len() as u16;
Fixed::xy(20, 1 + ins, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + ins, FieldV(theme, format!("MIDI ins: "),
Map::south(1, ||track.sequencer.midi_ins.iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))})
}
fn view_midi_outs_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().map(|track|{
let outs = track.sequencer.midi_outs.len() as u16;
Fixed::xy(20, 1 + outs, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + outs, FieldV(theme, format!("MIDI outs: "),
Map::south(1, ||track.sequencer.midi_outs.iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))})
}
fn view_audio_ins_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().and_then(|track|track.devices.get(0)).map(|device|{
let ins = device.audio_ins().len() as u16;
Fixed::xy(20, 1 + ins, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + ins, FieldV(theme, format!("Audio ins: "),
Map::south(1, ||device.audio_ins().iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))})
}
fn view_audio_outs_status (&self, theme: ItemTheme) -> impl Content<TuiOut> {
self.track().and_then(|track|track.devices.last()).map(|device|{
let outs = device.audio_outs().len() as u16;
Fixed::xy(20, 1 + outs, Outer(true, Style::default().fg(Tui::g(96))).enclose(
Fixed::xy(20, 1 + outs, FieldV(theme, format!("Audio outs: "),
Map::south(1, ||device.audio_outs().iter(),
|port, index|Fill::x(Align::w(format!(" {index} {}", port.name()))))))))})
}
} }
//impl<T: Has<Option<Track>>> HasTrack for T { //impl<T: Has<Option<Track>>> HasTrack for T {
@ -162,14 +197,3 @@ pub trait HasTrack {
//self.get_mut().as_mut() //self.get_mut().as_mut()
//} //}
//} //}
impl<T: Has<Vec<Track>> + Has<Selection>> HasTrack for T {
fn track (&self) -> Option<&Track> {
let index = Has::<Selection>::get(self).track()?;
Has::<Vec<Track>>::get(self).get(index)
}
fn track_mut (&mut self) -> Option<&mut Track> {
let index = Has::<Selection>::get(self).track()?;
Has::<Vec<Track>>::get_mut(self).get_mut(index)
}
}

View file

@ -13,7 +13,7 @@ pub(crate) use std::path::PathBuf;
pub(crate) use std::error::Error; pub(crate) use std::error::Error;
pub(crate) use std::ffi::OsString; pub(crate) use std::ffi::OsString;
pub(crate) use ::tengri::{from, Usually, Perhaps, Has}; pub(crate) use ::tengri::{from, has, maybe_has, Usually, Perhaps, Has, MaybeHas};
pub(crate) use ::tengri::{dsl::*, input::*, output::*, tui::{*, ratatui::prelude::*}}; pub(crate) use ::tengri::{dsl::*, input::*, output::*, tui::{*, ratatui::prelude::*}};
pub(crate) use ::tek_engine::*; pub(crate) use ::tek_engine::*;
pub(crate) use ::tek_engine::midi::{u7, LiveEvent, MidiMessage}; pub(crate) use ::tek_engine::midi::{u7, LiveEvent, MidiMessage};

View file

@ -9,7 +9,7 @@ pub(crate) use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering::Rela
pub(crate) use std::fmt::Debug; pub(crate) use std::fmt::Debug;
pub(crate) use std::ops::{Add, Sub, Mul, Div, Rem}; pub(crate) use std::ops::{Add, Sub, Mul, Div, Rem};
pub(crate) use ::tengri::{from, Usually, Perhaps, Has, tui::*}; pub(crate) use ::tengri::{from, Usually, Perhaps, Has, has, maybe_has, tui::*};
pub use ::atomic_float; pub(crate) use atomic_float::*; pub use ::atomic_float; pub(crate) use atomic_float::*;
@ -23,15 +23,6 @@ pub use ::atomic_float; pub(crate) use atomic_float::*;
//} //}
//} //}
#[macro_export] macro_rules! has {
($T:ty: |$self:ident : $S:ty| $x:expr) => {
impl Has<$T> for $S {
fn get (&$self) -> &$T { &$x }
fn get_mut (&mut $self) -> &mut $T { &mut $x }
}
};
}
#[macro_export] macro_rules! as_ref { #[macro_export] macro_rules! as_ref {
($T:ty: |$self:ident : $S:ty| $x:expr) => { ($T:ty: |$self:ident : $S:ty| $x:expr) => {
impl AsRef<$T> for $S { impl AsRef<$T> for $S {