wip: try to get a simplified parser going

This commit is contained in:
🪞👃🪞 2025-01-04 08:49:38 +01:00
parent fc82d6ff9b
commit 600d0b3aca
17 changed files with 676 additions and 133 deletions

View file

@ -0,0 +1,12 @@
(sized
(bsp/s (fill/x (fixed/y 2 (lay
(align/w :input-meter-l)
(align/e :input-meter-r)
(align/x :transport))))
(bsp/n (row :clip-play :clip-next :clip-edit :edit-stat)
(bsp/n (max/y :sample-h (fill/xy :sample-view))
(bsp/n (align/w (fixed/y 1 :sample-stat))
(bsp/n (fixed/x :pool-w :pool-view)
(fill/xy (bsp/e
(fixed/x :samples-w (push/y :samples-y :samples-view))
:midi-view))))))))

View file

@ -1,49 +1,111 @@
use crate::*;
use super::*;
use std::marker::ConstParamTy;
render!(Tui: (self: Groovebox) => self.size.of(
Bsp::s(self.toolbar_view(),
Bsp::n(self.selector_view(),
Bsp::n(self.sample_view(),
Bsp::n(self.status_view(),
Bsp::w(self.pool_view(), Fill::xy(Bsp::e(self.sampler_view(), &self.editor)))))))));
const GROOVEBOX_EDN: &'static str = include_str!("groovebox.edn");
impl Groovebox {
fn toolbar_view (&self) -> impl Content<Tui> + use<'_> {
Fill::x(Fixed::y(2, lay!(
Align::w(Meter("L/", self.sampler.input_meter[0])),
Align::e(Meter("R/", self.sampler.input_meter[1])),
Align::x(TransportView::new(true, &self.player.clock)),
)))
}
fn selector_view (&self) -> impl Content<Tui> + use<'_> {
row!(
ClipSelected::play_phrase(&self.player),
ClipSelected::next_phrase(&self.player),
MidiEditClip(&self.editor),
MidiEditStatus(&self.editor),
)
}
fn sample_view (&self) -> impl Content<Tui> + use<'_> {
let note_pt = self.editor.note_point();
let sample_h = if self.compact { 0 } else { 5 };
Max::y(sample_h, Fill::xy(
SampleViewer::from_sampler(&self.sampler, note_pt)))
}
fn status_view (&self) -> impl Content<Tui> + use<'_> {
let note_pt = self.editor.note_point();
Align::w(Fixed::y(1, SamplerStatus(&self.sampler, note_pt)))
}
fn pool_view (&self) -> impl Content<Tui> + use<'_> {
let w = self.size.w();
let pool_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 };
Fixed::x(if self.compact { 5 } else { pool_w },
PoolView(self.compact, &self.pool))
}
fn sampler_view (&self) -> impl Content<Tui> + use<'_> {
let sampler_w = if self.compact { 4 } else { 11 };
let sampler_y = if self.compact { 1 } else { 0 };
Fixed::x(sampler_w, Push::y(sampler_y, Fill::y(
SampleList::new(self.compact, &self.sampler, &self.editor))))
impl Content<Tui> for Groovebox {
fn content (&self) -> impl Content<Tui> {
EdnView::parse(self.edn.as_slice())
}
}
//render!(Tui: (self: Groovebox) => self.size.of(
//Bsp::s(self.toolbar_view(),
//Bsp::n(self.selector_view(),
//Bsp::n(self.sample_view(),
//Bsp::n(self.status_view(),
//Bsp::w(self.pool_view(), Fill::xy(Bsp::e(self.sampler_view(), &self.editor)))))))));
macro_rules! edn_context {
($Struct:ident |$l:lifetime, $state:ident| {
$($key:literal = $field:ident: $Type:ty => $expr:expr,)*
}) => {
#[derive(Default)]
pub struct EdnView<$l> { $($field: Option<$Type>),* }
impl<$l> EdnView<$l> {
pub fn parse <'e> (edn: &[Edn<'e>]) -> impl Fn(&$Struct) + use<'e> {
let imports = Self::imports_all(edn);
move |state| {
let mut context = EdnView::default();
for import in imports.iter() {
context.import(state, import)
}
}
}
fn imports_all <'e> (edn: &[Edn<'e>]) -> Vec<&'e str> {
let mut imports = vec![];
for edn in edn.iter() {
for import in Self::imports_one(edn) {
imports.push(import);
}
}
imports
}
fn imports_one <'e> (edn: &Edn<'e>) -> Vec<&'e str> {
match edn {
Edn::Symbol(import) => vec![import],
Edn::List(edn) => Self::imports_all(edn.as_slice()),
_ => vec![],
}
}
pub fn import (&mut self, $state: &$l$Struct, key: &str) {
match key {
$($key => self.$field = Some($expr),)*
_ => {}
}
}
}
}
}
edn_context!(Groovebox |'a, state| {
":input-meter-l" = input_meter_l: Meter<'a> => Meter("L/", state.sampler.input_meter[0]),
":input-meter-r" = input_meter_r: Meter<'a> => Meter("R/", state.sampler.input_meter[1]),
":transport" = transport: TransportView<'a> => TransportView::new(true, &state.player.clock),
":clip-play" = clip_play: ClipSelected => ClipSelected::play_phrase(&state.player),
":clip-next" = clip_next: ClipSelected => ClipSelected::next_phrase(&state.player),
":clip-edit" = clip_edit: MidiEditClip<'a> => MidiEditClip(&state.editor),
":edit-stat" = edit_stat: MidiEditStatus<'a> => MidiEditStatus(&state.editor),
":sample-h" = sample_h: u16 => if state.compact { 0 } else { 5 },
":sample-view" = sample_view: SampleViewer => SampleViewer::from_sampler(
&state.sampler, state.editor.note_point()),
":sample-stat" = sample_stat: SamplerStatus<'a> => SamplerStatus(
&state.sampler, state.editor.note_point()),
":pool-w" = pool_w: u16 => if state.compact { 5 } else {
let w = state.size.w();
if w > 60 { 20 } else if w > 40 { 15 } else { 10 } },
":pool-view" = pool_view: PoolView<'a> => PoolView(state.compact, &state.pool),
":samples-w" = samples_w: u16 => if state.compact { 4 } else { 11 },
":samples-y" = samples_y: u16 => if state.compact { 1 } else { 0 },
":samples-view" = samples_view: SampleList<'a> => SampleList::new(
state.compact, &state.sampler, &state.editor),
":midi-view" = midi_view: &'a MidiEditor => &state.editor,
});
//impl Groovebox {
//fn status_view (&self) -> impl Content<Tui> + use<'_> {
//let note_pt = self.editor.note_point();
//Align::w(Fixed::y(1, ))
//}
//fn pool_view (&self) -> impl Content<Tui> + use<'_> {
//let w = self.size.w();
//let pool_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 };
//Fixed::x(if self.compact { 5 } else { pool_w },
//)
//}
//fn sampler_view (&self) -> impl Content<Tui> + use<'_> {
//let sampler_w = if self.compact { 4 } else { 11 };
//let sampler_y = if self.compact { 1 } else { 0 };
//Fixed::x(sampler_w, Push::y(sampler_y, Fill::y(
//SampleList::new(self.compact, &self.sampler, &self.editor))))
//}
//}

View file

@ -1,5 +1,9 @@
#![allow(unused)]
#![allow(clippy::unit_arg)]
#![feature(adt_const_params)]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
#![feature(associated_type_defaults)]
pub use ::tek_layout;
pub use ::tek_layout::tek_engine;
@ -12,7 +16,6 @@ pub(crate) use ::tek_layout::{
Output, Content, Thunk, render,
Input, Handle, handle,
kexp, kpat,
edn::*,
tui::{
Tui,
TuiIn, key, ctrl, shift, alt,
@ -33,6 +36,9 @@ pub(crate) use ::tek_layout::{
}
};
pub use ::tek_edn;
pub(crate) use ::tek_edn::*;
pub(crate) use std::cmp::{Ord, Eq, PartialEq};
pub(crate) use std::collections::BTreeMap;
pub(crate) use std::error::Error;