diff --git a/midi/src/midi_clip.rs b/midi/src/midi_clip.rs index ae03ef05..f09dd79c 100644 --- a/midi/src/midi_clip.rs +++ b/midi/src/midi_clip.rs @@ -92,7 +92,7 @@ impl MidiClip { controller: 123.into(), value: 0.into() }]]), - Some(ItemColor::from(Color::Rgb(32, 32, 32)).into()) + Some(ItemColor::from_rgb(Color::Rgb(32, 32, 32)).into()) ) } } diff --git a/output/src/op_align.rs b/output/src/op_align.rs index d083a735..d8f3df93 100644 --- a/output/src/op_align.rs +++ b/output/src/op_align.rs @@ -50,17 +50,17 @@ try_from_expr!(<'a, E>: Align>: |state, iter| } }); impl Align { - pub fn c (a: A) -> Self { Self(Alignment::Center, a) } - pub fn x (a: A) -> Self { Self(Alignment::X, a) } - pub fn y (a: A) -> Self { Self(Alignment::Y, a) } - pub fn n (a: A) -> Self { Self(Alignment::N, a) } - pub fn s (a: A) -> Self { Self(Alignment::S, a) } - pub fn e (a: A) -> Self { Self(Alignment::E, a) } - pub fn w (a: A) -> Self { Self(Alignment::W, a) } - pub fn nw (a: A) -> Self { Self(Alignment::NW, a) } - pub fn sw (a: A) -> Self { Self(Alignment::SW, a) } - pub fn ne (a: A) -> Self { Self(Alignment::NE, a) } - pub fn se (a: A) -> Self { Self(Alignment::SE, a) } + #[inline] pub fn c (a: A) -> Self { Self(Alignment::Center, a) } + #[inline] pub fn x (a: A) -> Self { Self(Alignment::X, a) } + #[inline] pub fn y (a: A) -> Self { Self(Alignment::Y, a) } + #[inline] pub fn n (a: A) -> Self { Self(Alignment::N, a) } + #[inline] pub fn s (a: A) -> Self { Self(Alignment::S, a) } + #[inline] pub fn e (a: A) -> Self { Self(Alignment::E, a) } + #[inline] pub fn w (a: A) -> Self { Self(Alignment::W, a) } + #[inline] pub fn nw (a: A) -> Self { Self(Alignment::NW, a) } + #[inline] pub fn sw (a: A) -> Self { Self(Alignment::SW, a) } + #[inline] pub fn ne (a: A) -> Self { Self(Alignment::NE, a) } + #[inline] pub fn se (a: A) -> Self { Self(Alignment::SE, a) } } impl> Content for Align { fn content (&self) -> impl Render { diff --git a/output/src/op_bsp.rs b/output/src/op_bsp.rs index bfd13e08..cf828ce3 100644 --- a/output/src/op_bsp.rs +++ b/output/src/op_bsp.rs @@ -55,12 +55,12 @@ try_from_expr!(<'a, E>: Bsp, RenderBox<'a, E>>: |state, iter| { } }); impl Bsp { - pub fn n (a: A, b: B) -> Self { Self(North, a, b) } - pub fn s (a: A, b: B) -> Self { Self(South, a, b) } - pub fn e (a: A, b: B) -> Self { Self(East, a, b) } - pub fn w (a: A, b: B) -> Self { Self(West, a, b) } - pub fn a (a: A, b: B) -> Self { Self(Above, a, b) } - pub fn b (a: A, b: B) -> Self { Self(Below, a, b) } + #[inline] pub fn n (a: A, b: B) -> Self { Self(North, a, b) } + #[inline] pub fn s (a: A, b: B) -> Self { Self(South, a, b) } + #[inline] pub fn e (a: A, b: B) -> Self { Self(East, a, b) } + #[inline] pub fn w (a: A, b: B) -> Self { Self(West, a, b) } + #[inline] pub fn a (a: A, b: B) -> Self { Self(Above, a, b) } + #[inline] pub fn b (a: A, b: B) -> Self { Self(Below, a, b) } } pub trait BspAreas, B: Content> { fn direction (&self) -> Direction; diff --git a/output/src/op_cond.rs b/output/src/op_cond.rs index c5446bc2..688fbc3e 100644 --- a/output/src/op_cond.rs +++ b/output/src/op_cond.rs @@ -1,10 +1,10 @@ use crate::*; /// Show an item only when a condition is true. pub struct When(pub bool, pub A); -impl When { pub fn new (c: bool, a: A) -> Self { Self(c, a) } } +impl When { #[inline] pub fn new (c: bool, a: A) -> Self { Self(c, a) } } /// Show one item if a condition is true and another if the condition is false pub struct Either(pub bool, pub A, pub B); -impl Either { pub fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } } +impl Either { #[inline] pub fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } } try_from_expr!(<'a, E>: When>: |state, iter| { if let Some(Token { value: Value::Key("when"), .. }) = iter.peek() { let _ = iter.next().unwrap(); diff --git a/output/src/op_iter.rs b/output/src/op_iter.rs index 378fdf69..f793a628 100644 --- a/output/src/op_iter.rs +++ b/output/src/op_iter.rs @@ -1,5 +1,5 @@ use crate::*; -pub fn map_south( +#[inline] pub fn map_south( item_offset: O::Unit, item_height: O::Unit, item: impl Content @@ -7,7 +7,7 @@ pub fn map_south( Push::y(item_offset, Fixed::y(item_height, Fill::x(item))) } -pub fn map_south_west( +#[inline] pub fn map_south_west( item_offset: O::Unit, item_height: O::Unit, item: impl Content @@ -15,7 +15,7 @@ pub fn map_south_west( Push::y(item_offset, Align::nw(Fixed::y(item_height, Fill::x(item)))) } -pub fn map_east( +#[inline] pub fn map_east( item_offset: O::Unit, item_width: O::Unit, item: impl Content diff --git a/output/src/op_transform.rs b/output/src/op_transform.rs index ab423010..fc868727 100644 --- a/output/src/op_transform.rs +++ b/output/src/op_transform.rs @@ -25,9 +25,9 @@ macro_rules! transform_xy { ($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$area:expr) => { pub enum $Enum { X(T), Y(T), XY(T) } impl $Enum { - pub fn x (item: T) -> Self { Self::X(item) } - pub fn y (item: T) -> Self { Self::Y(item) } - pub fn xy (item: T) -> Self { Self::XY(item) } + #[inline] pub fn x (item: T) -> Self { Self::X(item) } + #[inline] pub fn y (item: T) -> Self { Self::Y(item) } + #[inline] pub fn xy (item: T) -> Self { Self::XY(item) } } impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T> for $Enum> { @@ -71,9 +71,9 @@ macro_rules! transform_xy_unit { ($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$layout:expr) => { pub enum $Enum { X(U, T), Y(U, T), XY(U, U, T), } impl $Enum { - pub fn x (x: U, item: T) -> Self { Self::X(x, item) } - pub fn y (y: U, item: T) -> Self { Self::Y(y, item) } - pub fn xy (x: U, y: U, item: T) -> Self { Self::XY(x, y, item) } + #[inline] pub fn x (x: U, item: T) -> Self { Self::X(x, item) } + #[inline] pub fn y (y: U, item: T) -> Self { Self::Y(y, item) } + #[inline] pub fn xy (x: U, y: U, item: T) -> Self { Self::XY(x, y, item) } } impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T> for $Enum> { @@ -118,12 +118,12 @@ macro_rules! transform_xy_unit { } } impl $Enum { - pub fn dx (&self) -> U { + #[inline] pub fn dx (&self) -> U { match self { Self::X(x, _) => *x, Self::Y(_, _) => 0.into(), Self::XY(x, _, _) => *x, } } - pub fn dy (&self) -> U { + #[inline] pub fn dy (&self) -> U { match self { Self::X(_, _) => 0.into(), Self::Y(y, _) => *y, Self::XY(_, y, _) => *y, } diff --git a/tek/src/arranger.edn b/tek/src/arranger.edn new file mode 100644 index 00000000..dcf55404 --- /dev/null +++ b/tek/src/arranger.edn @@ -0,0 +1,82 @@ + This is the unified Tek Arranger. + + Its appearance is defined by the following view definition: + +{def :view (bsp/s (fixed/y 2 :toolbar) + (fill/x (align/c (bsp/w (fixed/x :pool-w :pool) + (bsp/n (fixed/y 3 :outputs) + (bsp/n (fixed/y 3 :inputs) + (bsp/n (fixed/y 3 :tracks) :scenes)))))))} + + The arranger's behavior is controlled by the + following keymaps: + +{def :keys + (@u undo 1) + (@shift-u redo 1) + (@space clock toggle) + (@shift-space clock toggle 0) + (@ctrl-a scene add) + (@ctrl-t track add) + (@tab edit) + (@c color)} + +{def :keys-mix + (@down select 0 1) + (@s select 0 1) + + (@right select 1 0) + (@d select 1 0)} + +{def :keys-track + (@left select :track-prev :scene) + (@a select :track-prev :scene) + (@right select :track-next :scene) + (@d select :track-next :scene) + (@down select :track :scene-next) + (@s select :track :scene-next) + + (@q track launch) + (@c track color :track) + (@comma track swap-prev) + (@period track swap-next) + (@lt track size-dec) + (@gt track size-inc) + (@delete track delete)} + +{def :keys-scene + (@up select :track :scene-prev) + (@w select :track :scene-prev) + (@down select :track :scene-next) + (@s select :track :scene-next) + (@right select :track-next :scene) + (@d select :track-next :scene) + + (@q scene launch) + (@c scene color :scene) + (@comma scene swap-prev) + (@period scene swap-next) + (@lt scene size-dec) + (@gt scene size-inc) + (@delete scene delete)} + +{def :keys-clip + (@up select :track :scene-prev) + (@w select :track :scene-prev) + (@down select :track :scene-next) + (@s select :track :scene-next) + (@left select :track-prev :scene) + (@a select :track-prev :scene) + (@right select :track-next :scene) + (@d select :track-next :scene) + + (@q enqueue :clip) + (@c clip color :track :scene) + (@g clip get) + (@p clip put) + (@delete clip del) + (@comma clip prev) + (@period clip next) + (@lt clip swap-prev) + (@gt clip swap-next) + (@l clip loop-toggle)} diff --git a/tek/src/lib.rs b/tek/src/lib.rs index 782f79f0..3b1afe09 100644 --- a/tek/src/lib.rs +++ b/tek/src/lib.rs @@ -380,13 +380,10 @@ impl Tek { let time = ||now.map(|now|format!("{:.3}s", now/1000000.)) .unwrap_or("-.---s".into()); let bpm = ||format!("{:.3}", clock.timebase.bpm.get()); + let theme = ItemPalette::G[128]; Either::new(compact, - row!(Field(Tui::g(128).into(), "BPM", bpm()), - Field(Tui::g(128).into(), "Beat", beat()), - Field(Tui::g(128).into(), "Time", time())), - row!(FieldV(Tui::g(128).into(), "BPM", bpm()), - FieldV(Tui::g(128).into(), "Beat", beat()), - FieldV(Tui::g(128).into(), "Time", time()))) + row!(Field(theme, "BPM", bpm()), Field(theme, "Beat", beat()), Field(theme, "Time", time())), + row!(FieldV(theme, "BPM", bpm()), FieldV(theme, "Beat", beat()), FieldV(theme, "Time", time()))) } fn view_engine_stats (&self) -> impl Content + use<'_> { let compact = self.size.w() > 80; @@ -396,17 +393,14 @@ impl Tek { let sr = move||format!("{}", if compact {format!("{:.1}kHz", rate / 1000.)} else {format!("{:.0}Hz", rate)}); let buf = move||format!("{chunk}"); let latency = move||format!("{:.1}ms", chunk as f64 / rate * 1000.); + let theme = ItemPalette::G[128]; Either::new(compact, - row!(Field(Tui::g(128).into(), "SR", sr()), - Field(Tui::g(128).into(), "Buf", buf()), - Field(Tui::g(128).into(), "Lat", latency())), - row!(FieldV(Tui::g(128).into(), "SR", sr()), - FieldV(Tui::g(128).into(), "Buf", buf()), - FieldV(Tui::g(128).into(), "Lat", latency()))) + row!(Field(theme, "SR", sr()), Field(theme, "Buf", buf()), Field(theme, "Lat", latency())), + row!(FieldV(theme, "SR", sr()), FieldV(theme, "Buf", buf()), FieldV(theme, "Lat", latency()))) } fn view_meter <'a> (&'a self, label: &'a str, value: f32) -> impl Content + 'a { col!( - Field(Tui::g(128).into(), label, format!("{:>+9.3}", value)), + Field(ItemPalette::G[128], label, format!("{:>+9.3}", value)), Fixed::xy(if value >= 0.0 { 13 } else if value >= -1.0 { 12 } else if value >= -2.0 { 11 } @@ -507,7 +501,7 @@ impl Tek { let c = c.read().unwrap(); (c.name.to_string(), c.color.lightest.rgb, c.color) } else { - ("⏹ ".to_string(), Tui::g(64), Tui::g(32).into()) + ("⏹ ".to_string(), Tui::g(64), ItemPalette::G[32]) }; let same_track = selected_track == Some(t+1); let selected = same_track && Some(s+1) == selected_scene; diff --git a/tui/src/tui_color.rs b/tui/src/tui_color.rs index e8ef4979..cdf278e5 100644 --- a/tui/src/tui_color.rs +++ b/tui/src/tui_color.rs @@ -90,8 +90,8 @@ impl ItemColor { impl ItemPalette { pub const G: [Self;256] = { let mut builder = konst::array::ArrayBuilder::new(); - let mut index = 0; while !builder.is_full() { + let index = builder.len() as u8; let light = (index as f64 * 1.3) as u8; let lighter = (index as f64 * 1.6) as u8; let lightest = (index as f64 * 1.9) as u8; @@ -107,7 +107,6 @@ impl ItemPalette { darker: ItemColor::from_rgb(Color::Rgb(darker, darker, darker, )), darkest: ItemColor::from_rgb(Color::Rgb(darkest, darkest, darkest, )), }); - index += 1; } builder.build() };