mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 03:36:41 +01:00
wip: edn minefield
This commit is contained in:
parent
98d2107e4e
commit
6f51872856
7 changed files with 150 additions and 210 deletions
|
|
@ -16,12 +16,22 @@ const fn digit (c: char) -> usize {
|
|||
#[derive(Debug)]
|
||||
pub enum ParseError {
|
||||
Empty,
|
||||
Incomplete,
|
||||
Unexpected(char),
|
||||
Incomplete
|
||||
}
|
||||
impl std::fmt::Display for ParseError {
|
||||
fn fmt (&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Empty => write!(f, "empty"),
|
||||
Self::Incomplete => write!(f, "incomplete"),
|
||||
Self::Unexpected(c) => write!(f, "unexpected '{c}'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::error::Error for ParseError {}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
pub enum Item<T: AsRef<str>> {
|
||||
pub enum Item<T: std::fmt::Debug + Clone + Default + PartialEq> {
|
||||
#[default] Nil,
|
||||
Num(usize),
|
||||
Sym(T),
|
||||
|
|
@ -30,7 +40,13 @@ pub enum Item<T: AsRef<str>> {
|
|||
}
|
||||
|
||||
impl Item<String> {
|
||||
pub fn read_all <'a> (mut source: &'a str) -> Result<Vec<Self>, ParseError> {
|
||||
}
|
||||
|
||||
impl<'a> Item<&'a str> {
|
||||
}
|
||||
|
||||
impl<'a, T: std::fmt::Debug + Clone + Default + PartialEq + From<&'a str>> Item<T> {
|
||||
pub fn read_all (mut source: &'a str) -> Result<Vec<Self>, ParseError> {
|
||||
let mut items = vec![];
|
||||
loop {
|
||||
if source.len() == 0 {
|
||||
|
|
@ -42,19 +58,29 @@ impl Item<String> {
|
|||
}
|
||||
Ok(items)
|
||||
}
|
||||
pub fn read <'a> (token: Token<'a>) -> Result<Self, ParseError> {
|
||||
pub fn read (token: Token<'a>) -> Result<Self, ParseError> {
|
||||
use Token::*;
|
||||
Ok(match token {
|
||||
Nil => Item::Nil,
|
||||
Num(chars, index, length) =>
|
||||
Self::Num(number(&chars[index..index+length])),
|
||||
Sym(chars, index, length) =>
|
||||
Self::Sym(chars[index..index+length].to_string()),
|
||||
Self::Sym(T::from(&chars[index..index+length])),
|
||||
Key(chars, index, length) =>
|
||||
Self::Key(chars[index..index+length].to_string()),
|
||||
Self::Key(T::from(&chars[index..index+length])),
|
||||
Exp(chars, index, length, 0) =>
|
||||
Self::Exp(Self::read_all(&chars[index+1..(index+length).saturating_sub(1)])?),
|
||||
_ => panic!("unclosed delimiter")
|
||||
})
|
||||
}
|
||||
//pub fn to_str <'a> (&'a self) -> Item<&'a str> {
|
||||
//use Item::*;
|
||||
//match self {
|
||||
//Nil => Nil,
|
||||
//Num(n) => Num(*n),
|
||||
//Sym(t) => Sym(t.as_str()),
|
||||
//Key(t) => Key(t.as_str()),
|
||||
//Exp(t) => Exp(t.iter().map(|x|x.to_str()).collect())
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,150 +1,68 @@
|
|||
use crate::*;
|
||||
use std::marker::PhantomData;
|
||||
use ::tek_layout::{*, tek_engine::{Content, Render, Engine, Thunk}};
|
||||
use ::tek_layout::{*, tek_engine::{Usually, Content, Render, Engine, Thunk}};
|
||||
use Item::*;
|
||||
|
||||
pub struct EdnContent<'a, E, T: AsRef<str>>(PhantomData<E>, &'a [Item<T>]);
|
||||
//pub struct EdnContent<'a, E, T: AsRef<str>>(PhantomData<E>, &'a [Item<T>]);
|
||||
|
||||
impl<'a, E, T: AsRef<str>> From<&'a [Item<T>]> for EdnContent<'a, E, T> {
|
||||
fn from (items: &'a [Item<T>]) -> Self {
|
||||
Self(Default::default(), items)
|
||||
//impl<'a, E, T: AsRef<str>> From<&'a [Item<T>]> for EdnContent<'a, E, T> {
|
||||
//fn from (items: &'a [Item<T>]) -> Self {
|
||||
//Self(Default::default(), items)
|
||||
//}
|
||||
//}
|
||||
|
||||
pub struct EdnView<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a>(
|
||||
PhantomData<&'a ()>,
|
||||
Box<dyn Fn(T)->Box<dyn Render<E> + Send + Sync> + Send + Sync>
|
||||
);
|
||||
|
||||
impl<'a, E: Engine + 'a, T: EdnLayout<'a, E> + 'a> EdnView<'a, E, T> {
|
||||
fn from (source: &'a str) -> Usually<Self> {
|
||||
let items: Vec<Item<&'a str>> = Item::read_all(source)?;
|
||||
let layout = T::parse(items.iter().map(|x|x.to_str()).collect::<Vec<_>>().as_slice());
|
||||
Ok(Self(Default::default(), Box::new(move|_|{
|
||||
let _ = layout;
|
||||
Box::new(())
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
//impl<'a, E: Engine> Content<E> for EdnContent<'a, E> {
|
||||
/*todo*/
|
||||
//}
|
||||
|
||||
//pub struct EdnContent<'a, T>(T, &'a [Item]);
|
||||
|
||||
pub trait EdnLayout<E: Engine + 'static> {
|
||||
fn get_bool (&self, item: &Item<&str>) -> bool { false }
|
||||
fn get_unit (&self, item: &Item<&str>) -> E::Unit { 0.into() }
|
||||
fn get_usize (&self, key: &str) -> usize { 0 }
|
||||
fn get_content (&self, item: &Item<&str>) -> Box<dyn Render<E> + '_> { Box::new(()) }
|
||||
fn parse <'a: 'static> (&'a self, items: &[Item<&str>]) -> Box<dyn Render<E> + 'a> {
|
||||
match items {
|
||||
[Key("when"), c, a, ..] =>
|
||||
Box::new(When(self.get_bool(c), self.get_content(a))),
|
||||
[Key("either"), c, a, b, ..] =>
|
||||
Box::new(Either(self.get_bool(c), self.get_content(a), self.get_content(b))),
|
||||
|
||||
[Key("fill"), a, ..] =>
|
||||
Box::new(Fill::xy(self.get_content(a))),
|
||||
[Key("fill/x"), a, ..] => Box::new(Fill::x(self.get_content(a))),
|
||||
[Key("fill/y"), a, ..] => Box::new(Fill::y(self.get_content(a))),
|
||||
|
||||
[Key("fixed"), x, y, a, ..] =>
|
||||
Box::new(Fixed::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
|
||||
[Key("fixed/x"), x, a, ..] => Box::new(Fixed::x(self.get_unit(x), self.get_content(a))),
|
||||
[Key("fixed/y"), y, a, ..] => Box::new(Fixed::y(self.get_unit(y), self.get_content(a))),
|
||||
|
||||
[Key("shrink"), x, y, a, ..] =>
|
||||
Box::new(Shrink::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
|
||||
[Key("shrink/x"), x, a, ..] => Box::new(Shrink::x(self.get_unit(x), self.get_content(a))),
|
||||
[Key("shrink/y"), y, a, ..] => Box::new(Shrink::y(self.get_unit(y), self.get_content(a))),
|
||||
|
||||
[Key("expand"), x, y, a, ..] =>
|
||||
Box::new(Expand::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
|
||||
[Key("expand/x"), x, a, ..] => Box::new(Expand::x(self.get_unit(x), self.get_content(a))),
|
||||
[Key("expand/y"), y, a, ..] => Box::new(Expand::y(self.get_unit(y), self.get_content(a))),
|
||||
|
||||
[Key("push"), x, y, a, ..] =>
|
||||
Box::new(Push::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
|
||||
[Key("push/x"), x, a, ..] => Box::new(Push::x(self.get_unit(x), self.get_content(a))),
|
||||
[Key("push/y"), y, a, ..] => Box::new(Push::y(self.get_unit(y), self.get_content(a))),
|
||||
|
||||
[Key("pull"), x, y, a, ..] =>
|
||||
Box::new(Pull::xy(self.get_unit(x), self.get_unit(y), self.get_content(a))),
|
||||
[Key("pull/x"), x, a, ..] => Box::new(Pull::x(self.get_unit(x), self.get_content(a))),
|
||||
[Key("pull/y"), y, a, ..] => Box::new(Pull::y(self.get_unit(y), self.get_content(a))),
|
||||
|
||||
_ => Box::new(())
|
||||
//[Key("when"), Sym(condition), Sym(template)] => When(
|
||||
//self.get_bool(condition),
|
||||
//self.get_content(template)),
|
||||
//[Key("when"), Sym(condition), Exp(template)] => When(
|
||||
//self.get_bool(condition),
|
||||
//Thunk::new(||EdnLayout::parse(template))),
|
||||
|
||||
macro_rules! edn_ns {
|
||||
(|$state:ident, $items:ident| { $($match:pat => $handle:expr),* $(,)? }) => {
|
||||
match $items {
|
||||
$($match => |$state|Box::new($handle),)*
|
||||
_ => |$state|Box::new(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//edn_ns! { EdnLayout |context, item| {
|
||||
|
||||
//[Key("when"), Sym(condition), Sym(template)] => When(
|
||||
//context.get_bool(condition),
|
||||
//context.get_template(template)),
|
||||
|
||||
//[Key("when"), Sym(condition), Exp(template)] => When(
|
||||
//context.get_bool(condition),
|
||||
//Thunk::new(||EdnLayout::parse(template))),
|
||||
|
||||
//"when" => When(item.0[1].into(), item.0[2].into())
|
||||
|
||||
////"either" = Either<A, B>(args[0].into(), args[1].into(), args[2].into()),
|
||||
|
||||
////"map" = Map<A, B, I, F, G>(args[0].into(), args[1].into()),
|
||||
|
||||
////"fill" = edn_ns! {
|
||||
////"x" = Fixed<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Fixed<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Fixed<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"fixed" = edn_ns! {
|
||||
////"x" = Fixed<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Fixed<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Fixed<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"shrink" = edn_ns! {
|
||||
////"x" = Shrink<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Shrink<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Shrink<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"expand" = edn_ns! {
|
||||
////"x" = Expand<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Expand<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Expand<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"min" = edn_ns! {
|
||||
////"x" = Min<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Min<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Min<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"max" = edn_ns! {
|
||||
////"x" = Max<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Max<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Max<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"push" = edn_ns! {
|
||||
////"x" = Push<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Push<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Push<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"pull" = edn_ns! {
|
||||
////"x" = Pull<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Pull<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Pull<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"margin" = edn_ns! {
|
||||
////"x" = Margin<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Margin<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Margin<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
////"padding" = edn_ns! {
|
||||
////"x" = Padding<T>::X(args[0].into(), args[1].into()),
|
||||
////"y" = Padding<T>::Y(args[0].into(), args[1].into()),
|
||||
////"xy" = Padding<T>::XY(args[0].into(), args[1].into(), args[2].into()),
|
||||
////},
|
||||
|
||||
//} }
|
||||
pub trait EdnLayout<'a, E: Engine> where Self: 'a {
|
||||
fn get_bool (&self, _: &Item<&str>) -> bool { false }
|
||||
fn get_unit (&self, _: &Item<&str>) -> E::Unit { 0.into() }
|
||||
fn get_usize (&self, _: &Item<&str>) -> usize { 0 }
|
||||
fn get_content (&self, _: &Item<&str>) -> Box<dyn Render<E>> { Box::new(()) }
|
||||
fn parse (items: &'a [Item<&'a str>]) -> impl Fn(&'a Self)->Box<dyn Render<E> + 'a> + 'a {
|
||||
edn_ns!(|state, items|{
|
||||
[Key("when"), c, a, ..] => When(state.get_bool(c), state.get_content(a)),
|
||||
[Key("either"), c, a, b, ..] => Either(state.get_bool(c), state.get_content(a), state.get_content(b)),
|
||||
[Key("fill"), a, ..] => Fill::xy(state.get_content(a)),
|
||||
[Key("fill/x"), a, ..] => Fill::x(state.get_content(a)),
|
||||
[Key("fill/y"), a, ..] => Fill::y(state.get_content(a)),
|
||||
[Key("fixed"), x, y, a, ..] => Fixed::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
[Key("fixed/x"), x, a, ..] => Fixed::x(state.get_unit(x), state.get_content(a)),
|
||||
[Key("fixed/y"), y, a, ..] => Fixed::y(state.get_unit(y), state.get_content(a)),
|
||||
[Key("shrink"), x, y, a, ..] => Shrink::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
[Key("shrink/x"), x, a, ..] => Shrink::x(state.get_unit(x), state.get_content(a)),
|
||||
[Key("shrink/y"), y, a, ..] => Shrink::y(state.get_unit(y), state.get_content(a)),
|
||||
[Key("expand"), x, y, a, ..] => Expand::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
[Key("expand/x"), x, a, ..] => Expand::x(state.get_unit(x), state.get_content(a)),
|
||||
[Key("expand/y"), y, a, ..] => Expand::y(state.get_unit(y), state.get_content(a)),
|
||||
[Key("push"), x, y, a, ..] => Push::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
[Key("push/x"), x, a, ..] => Push::x(state.get_unit(x), state.get_content(a)),
|
||||
[Key("push/y"), y, a, ..] => Push::y(state.get_unit(y), state.get_content(a)),
|
||||
[Key("pull"), x, y, a, ..] => Pull::xy(state.get_unit(x), state.get_unit(y), state.get_content(a)),
|
||||
[Key("pull/x"), x, a, ..] => Pull::x(state.get_unit(x), state.get_content(a)),
|
||||
[Key("pull/y"), y, a, ..] => Pull::y(state.get_unit(y), state.get_content(a)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ mod input; pub use self::input::*;
|
|||
mod output; pub use self::output::*;
|
||||
|
||||
pub mod tui;
|
||||
#[cfg(feature = "edn")] pub mod edn;
|
||||
|
||||
pub use std::error::Error;
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ impl<T: Content<Tui> + Handle<Tui> + Sized + 'static> TuiRun<T> for Arc<RwLock<T
|
|||
},
|
||||
_ => {
|
||||
let exited = exited.clone();
|
||||
if let Err(e) = state.write().unwrap().handle(&TuiIn { event, exited }) {
|
||||
if let Err(e) = state.write().unwrap().handle(&TuiIn(exited, event)) {
|
||||
panic!("{e}")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,15 @@
|
|||
use crate::{*, tui::*};
|
||||
pub use crossterm::event::Event;
|
||||
use Event as CrosstermEvent;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TuiIn {
|
||||
pub(crate) exited: Arc<AtomicBool>,
|
||||
pub(crate) event: Event,
|
||||
}
|
||||
pub struct TuiIn(pub Arc<AtomicBool>, pub CrosstermEvent);
|
||||
|
||||
impl Input<Tui> for TuiIn {
|
||||
type Event = Event;
|
||||
fn event (&self) -> &Event {
|
||||
&self.event
|
||||
}
|
||||
fn is_done (&self) -> bool {
|
||||
self.exited.fetch_and(true, Relaxed)
|
||||
}
|
||||
fn done (&self) {
|
||||
self.exited.store(true, Relaxed);
|
||||
}
|
||||
fn event (&self) -> &CrosstermEvent { &self.1 }
|
||||
fn is_done (&self) -> bool { self.0.fetch_and(true, Relaxed) }
|
||||
fn done (&self) { self.0.store(true, Relaxed); }
|
||||
}
|
||||
|
||||
/// Define a key
|
||||
|
|
|
|||
|
|
@ -10,22 +10,24 @@ mod groovebox_audio; pub use self::groovebox_audio::*;
|
|||
mod groovebox_command; pub use self::groovebox_command::*;
|
||||
mod groovebox_tui; pub use self::groovebox_tui::*;
|
||||
|
||||
pub struct Groovebox {
|
||||
pub struct Groovebox<'a> {
|
||||
_jack: Arc<RwLock<JackConnection>>,
|
||||
pub view: EdnView<'a, Tui, Self>,
|
||||
|
||||
pub player: MidiPlayer,
|
||||
pub pool: PoolModel,
|
||||
pub editor: MidiEditor,
|
||||
pub sampler: Sampler,
|
||||
pub player: MidiPlayer,
|
||||
pub pool: PoolModel,
|
||||
pub editor: MidiEditor,
|
||||
pub sampler: Sampler,
|
||||
|
||||
pub compact: bool,
|
||||
pub size: Measure<Tui>,
|
||||
pub status: bool,
|
||||
pub note_buf: Vec<u8>,
|
||||
pub midi_buf: Vec<Vec<Vec<u8>>>,
|
||||
pub perf: PerfModel,
|
||||
pub compact: bool,
|
||||
pub size: Measure<Tui>,
|
||||
pub status: bool,
|
||||
pub note_buf: Vec<u8>,
|
||||
pub midi_buf: Vec<Vec<Vec<u8>>>,
|
||||
pub perf: PerfModel,
|
||||
}
|
||||
impl Groovebox {
|
||||
|
||||
impl<'a> Groovebox<'a> {
|
||||
pub fn new (
|
||||
jack: &Arc<RwLock<JackConnection>>,
|
||||
midi_from: &[impl AsRef<str>],
|
||||
|
|
@ -55,7 +57,49 @@ impl Groovebox {
|
|||
midi_buf: vec![vec![];65536],
|
||||
note_buf: vec![],
|
||||
perf: PerfModel::default(),
|
||||
|
||||
view: EdnView::from(include_str!("groovebox/groovebox.edn")),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
has_clock!(|self: Groovebox|self.player.clock());
|
||||
|
||||
impl<'a> EdnLayout<'a, Tui> for Groovebox {
|
||||
fn get_bool (&self, item: &Item<&str>) -> bool { todo!() }
|
||||
fn get_unit (&self, item: &Item<&str>) -> u16 {
|
||||
match item {
|
||||
Sym(":sample-h") => if self.compact { 0 } else { 5 },
|
||||
Sym(":samples-w") => if self.compact { 4 } else { 11 },
|
||||
Sym(":samples-y") => if self.compact { 1 } else { 0 },
|
||||
Sym(":pool-w") => if self.compact { 5 } else {
|
||||
let w = self.size.w();
|
||||
if w > 60 { 20 } else if w > 40 { 15 } else { 10 }
|
||||
},
|
||||
_ => 0
|
||||
}
|
||||
}
|
||||
fn get_content (&self, item: &Item<&str>) -> Box<dyn Render<Tui> + '_> {
|
||||
match item {
|
||||
Sym(":input-meter-l") => Box::new(Meter("L/", self.sampler.input_meter[0])),
|
||||
Sym(":input-meter-r") => Box::new(Meter("R/", self.sampler.input_meter[1])),
|
||||
|
||||
Sym(":transport") => Box::new(TransportView::new(true, &self.player.clock)),
|
||||
Sym(":clip-play") => Box::new(ClipSelected::play_phrase(&self.player)),
|
||||
Sym(":clip-next") => Box::new(ClipSelected::next_phrase(&self.player)),
|
||||
Sym(":clip-edit") => Box::new(MidiEditClip(&self.editor)),
|
||||
Sym(":edit-stat") => Box::new(MidiEditStatus(&self.editor)),
|
||||
Sym(":pool-view") => Box::new(PoolView(self.compact, &self.pool)),
|
||||
Sym(":midi-view") => Box::new(&self.editor),
|
||||
|
||||
Sym(":sample-view") => Box::new(SampleViewer::from_sampler(
|
||||
&self.sampler, self.editor.note_point())),
|
||||
Sym(":sample-stat") => Box::new(SamplerStatus(
|
||||
&self.sampler, self.editor.note_point())),
|
||||
Sym(":samples-view") => Box::new(SampleList::new(
|
||||
self.compact, &self.sampler, &self.editor)),
|
||||
|
||||
_ => Box::new(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,45 +4,6 @@ use std::marker::ConstParamTy;
|
|||
use tek_engine::Render;
|
||||
use Item::*;
|
||||
|
||||
impl EdnLayout<Tui> for Groovebox {
|
||||
fn get_bool (&self, item: &Item<&str>) -> bool { todo!() }
|
||||
fn get_unit (&self, item: &Item<&str>) -> u16 {
|
||||
match item {
|
||||
Sym(":sample-h") => if self.compact { 0 } else { 5 },
|
||||
Sym(":samples-w") => if self.compact { 4 } else { 11 },
|
||||
Sym(":samples-y") => if self.compact { 1 } else { 0 },
|
||||
Sym(":pool-w") => if self.compact { 5 } else {
|
||||
let w = self.size.w();
|
||||
if w > 60 { 20 } else if w > 40 { 15 } else { 10 }
|
||||
},
|
||||
_ => 0
|
||||
}
|
||||
}
|
||||
fn get_content (&self, item: &Item<&str>) -> Box<dyn Render<Tui> + '_> {
|
||||
match item {
|
||||
Sym(":input-meter-l") => Box::new(Meter("L/", self.sampler.input_meter[0])),
|
||||
Sym(":input-meter-r") => Box::new(Meter("R/", self.sampler.input_meter[1])),
|
||||
|
||||
Sym(":transport") => Box::new(TransportView::new(true, &self.player.clock)),
|
||||
Sym(":clip-play") => Box::new(ClipSelected::play_phrase(&self.player)),
|
||||
Sym(":clip-next") => Box::new(ClipSelected::next_phrase(&self.player)),
|
||||
Sym(":clip-edit") => Box::new(MidiEditClip(&self.editor)),
|
||||
Sym(":edit-stat") => Box::new(MidiEditStatus(&self.editor)),
|
||||
Sym(":pool-view") => Box::new(PoolView(self.compact, &self.pool)),
|
||||
Sym(":midi-view") => Box::new(&self.editor),
|
||||
|
||||
Sym(":sample-view") => Box::new(SampleViewer::from_sampler(
|
||||
&self.sampler, self.editor.note_point())),
|
||||
Sym(":sample-stat") => Box::new(SamplerStatus(
|
||||
&self.sampler, self.editor.note_point())),
|
||||
Sym(":samples-view") => Box::new(SampleList::new(
|
||||
self.compact, &self.sampler, &self.editor)),
|
||||
|
||||
_ => Box::new(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render!(Tui: (self: Groovebox) => self.size.of(
|
||||
Bsp::s(self.toolbar_view(),
|
||||
Bsp::n(self.selector_view(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue