mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
remove last color conversion from render loop
This commit is contained in:
parent
a31de6e819
commit
7ad574cf2a
9 changed files with 122 additions and 47 deletions
|
|
@ -92,7 +92,7 @@ impl MidiClip {
|
||||||
controller: 123.into(),
|
controller: 123.into(),
|
||||||
value: 0.into()
|
value: 0.into()
|
||||||
}]]),
|
}]]),
|
||||||
Some(ItemColor::from(Color::Rgb(32, 32, 32)).into())
|
Some(ItemColor::from_rgb(Color::Rgb(32, 32, 32)).into())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,17 +50,17 @@ try_from_expr!(<'a, E>: Align<RenderBox<'a, E>>: |state, iter|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
impl<A> Align<A> {
|
impl<A> Align<A> {
|
||||||
pub fn c (a: A) -> Self { Self(Alignment::Center, a) }
|
#[inline] pub fn c (a: A) -> Self { Self(Alignment::Center, a) }
|
||||||
pub fn x (a: A) -> Self { Self(Alignment::X, a) }
|
#[inline] pub fn x (a: A) -> Self { Self(Alignment::X, a) }
|
||||||
pub fn y (a: A) -> Self { Self(Alignment::Y, a) }
|
#[inline] pub fn y (a: A) -> Self { Self(Alignment::Y, a) }
|
||||||
pub fn n (a: A) -> Self { Self(Alignment::N, a) }
|
#[inline] pub fn n (a: A) -> Self { Self(Alignment::N, a) }
|
||||||
pub fn s (a: A) -> Self { Self(Alignment::S, a) }
|
#[inline] pub fn s (a: A) -> Self { Self(Alignment::S, a) }
|
||||||
pub fn e (a: A) -> Self { Self(Alignment::E, a) }
|
#[inline] pub fn e (a: A) -> Self { Self(Alignment::E, a) }
|
||||||
pub fn w (a: A) -> Self { Self(Alignment::W, a) }
|
#[inline] pub fn w (a: A) -> Self { Self(Alignment::W, a) }
|
||||||
pub fn nw (a: A) -> Self { Self(Alignment::NW, a) }
|
#[inline] pub fn nw (a: A) -> Self { Self(Alignment::NW, a) }
|
||||||
pub fn sw (a: A) -> Self { Self(Alignment::SW, a) }
|
#[inline] pub fn sw (a: A) -> Self { Self(Alignment::SW, a) }
|
||||||
pub fn ne (a: A) -> Self { Self(Alignment::NE, a) }
|
#[inline] pub fn ne (a: A) -> Self { Self(Alignment::NE, a) }
|
||||||
pub fn se (a: A) -> Self { Self(Alignment::SE, a) }
|
#[inline] pub fn se (a: A) -> Self { Self(Alignment::SE, a) }
|
||||||
}
|
}
|
||||||
impl<E: Output, A: Content<E>> Content<E> for Align<A> {
|
impl<E: Output, A: Content<E>> Content<E> for Align<A> {
|
||||||
fn content (&self) -> impl Render<E> {
|
fn content (&self) -> impl Render<E> {
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,12 @@ try_from_expr!(<'a, E>: Bsp<RenderBox<'a, E>, RenderBox<'a, E>>: |state, iter| {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
impl<A, B> Bsp<A, B> {
|
impl<A, B> Bsp<A, B> {
|
||||||
pub fn n (a: A, b: B) -> Self { Self(North, a, b) }
|
#[inline] pub fn n (a: A, b: B) -> Self { Self(North, a, b) }
|
||||||
pub fn s (a: A, b: B) -> Self { Self(South, a, b) }
|
#[inline] pub fn s (a: A, b: B) -> Self { Self(South, a, b) }
|
||||||
pub fn e (a: A, b: B) -> Self { Self(East, a, b) }
|
#[inline] pub fn e (a: A, b: B) -> Self { Self(East, a, b) }
|
||||||
pub fn w (a: A, b: B) -> Self { Self(West, a, b) }
|
#[inline] pub fn w (a: A, b: B) -> Self { Self(West, a, b) }
|
||||||
pub fn a (a: A, b: B) -> Self { Self(Above, a, b) }
|
#[inline] 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 b (a: A, b: B) -> Self { Self(Below, a, b) }
|
||||||
}
|
}
|
||||||
pub trait BspAreas<E: Output, A: Content<E>, B: Content<E>> {
|
pub trait BspAreas<E: Output, A: Content<E>, B: Content<E>> {
|
||||||
fn direction (&self) -> Direction;
|
fn direction (&self) -> Direction;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
/// Show an item only when a condition is true.
|
/// Show an item only when a condition is true.
|
||||||
pub struct When<A>(pub bool, pub A);
|
pub struct When<A>(pub bool, pub A);
|
||||||
impl<A> When<A> { pub fn new (c: bool, a: A) -> Self { Self(c, a) } }
|
impl<A> When<A> { #[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
|
/// Show one item if a condition is true and another if the condition is false
|
||||||
pub struct Either<A, B>(pub bool, pub A, pub B);
|
pub struct Either<A, B>(pub bool, pub A, pub B);
|
||||||
impl<A, B> Either<A, B> { pub fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } }
|
impl<A, B> Either<A, B> { #[inline] pub fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } }
|
||||||
try_from_expr!(<'a, E>: When<RenderBox<'a, E>>: |state, iter| {
|
try_from_expr!(<'a, E>: When<RenderBox<'a, E>>: |state, iter| {
|
||||||
if let Some(Token { value: Value::Key("when"), .. }) = iter.peek() {
|
if let Some(Token { value: Value::Key("when"), .. }) = iter.peek() {
|
||||||
let _ = iter.next().unwrap();
|
let _ = iter.next().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
pub fn map_south<O: Output>(
|
#[inline] pub fn map_south<O: Output>(
|
||||||
item_offset: O::Unit,
|
item_offset: O::Unit,
|
||||||
item_height: O::Unit,
|
item_height: O::Unit,
|
||||||
item: impl Content<O>
|
item: impl Content<O>
|
||||||
|
|
@ -7,7 +7,7 @@ pub fn map_south<O: Output>(
|
||||||
Push::y(item_offset, Fixed::y(item_height, Fill::x(item)))
|
Push::y(item_offset, Fixed::y(item_height, Fill::x(item)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_south_west<O: Output>(
|
#[inline] pub fn map_south_west<O: Output>(
|
||||||
item_offset: O::Unit,
|
item_offset: O::Unit,
|
||||||
item_height: O::Unit,
|
item_height: O::Unit,
|
||||||
item: impl Content<O>
|
item: impl Content<O>
|
||||||
|
|
@ -15,7 +15,7 @@ pub fn map_south_west<O: Output>(
|
||||||
Push::y(item_offset, Align::nw(Fixed::y(item_height, Fill::x(item))))
|
Push::y(item_offset, Align::nw(Fixed::y(item_height, Fill::x(item))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_east<O: Output>(
|
#[inline] pub fn map_east<O: Output>(
|
||||||
item_offset: O::Unit,
|
item_offset: O::Unit,
|
||||||
item_width: O::Unit,
|
item_width: O::Unit,
|
||||||
item: impl Content<O>
|
item: impl Content<O>
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ macro_rules! transform_xy {
|
||||||
($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$area:expr) => {
|
($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$area:expr) => {
|
||||||
pub enum $Enum<T> { X(T), Y(T), XY(T) }
|
pub enum $Enum<T> { X(T), Y(T), XY(T) }
|
||||||
impl<T> $Enum<T> {
|
impl<T> $Enum<T> {
|
||||||
pub fn x (item: T) -> Self { Self::X(item) }
|
#[inline] pub fn x (item: T) -> Self { Self::X(item) }
|
||||||
pub fn y (item: T) -> Self { Self::Y(item) }
|
#[inline] pub fn y (item: T) -> Self { Self::Y(item) }
|
||||||
pub fn xy (item: T) -> Self { Self::XY(item) }
|
#[inline] pub fn xy (item: T) -> Self { Self::XY(item) }
|
||||||
}
|
}
|
||||||
impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T>
|
impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T>
|
||||||
for $Enum<RenderBox<'a, E>> {
|
for $Enum<RenderBox<'a, E>> {
|
||||||
|
|
@ -71,9 +71,9 @@ macro_rules! transform_xy_unit {
|
||||||
($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$layout:expr) => {
|
($x:literal $y:literal $xy:literal |$self:ident : $Enum:ident, $to:ident|$layout:expr) => {
|
||||||
pub enum $Enum<U, T> { X(U, T), Y(U, T), XY(U, U, T), }
|
pub enum $Enum<U, T> { X(U, T), Y(U, T), XY(U, U, T), }
|
||||||
impl<U, T> $Enum<U, T> {
|
impl<U, T> $Enum<U, T> {
|
||||||
pub fn x (x: U, item: T) -> Self { Self::X(x, item) }
|
#[inline] pub fn x (x: U, item: T) -> Self { Self::X(x, item) }
|
||||||
pub fn y (y: U, item: T) -> Self { Self::Y(y, item) }
|
#[inline] 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 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>
|
impl<'a, E: Output + 'a, T: ViewContext<'a, E>> TryFromAtom<'a, T>
|
||||||
for $Enum<E::Unit, RenderBox<'a, E>> {
|
for $Enum<E::Unit, RenderBox<'a, E>> {
|
||||||
|
|
@ -118,12 +118,12 @@ macro_rules! transform_xy_unit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<U: Copy + Coordinate, T> $Enum<U, T> {
|
impl<U: Copy + Coordinate, T> $Enum<U, T> {
|
||||||
pub fn dx (&self) -> U {
|
#[inline] pub fn dx (&self) -> U {
|
||||||
match self {
|
match self {
|
||||||
Self::X(x, _) => *x, Self::Y(_, _) => 0.into(), Self::XY(x, _, _) => *x,
|
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 {
|
match self {
|
||||||
Self::X(_, _) => 0.into(), Self::Y(y, _) => *y, Self::XY(_, y, _) => *y,
|
Self::X(_, _) => 0.into(), Self::Y(y, _) => *y, Self::XY(_, y, _) => *y,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
82
tek/src/arranger.edn
Normal file
82
tek/src/arranger.edn
Normal file
|
|
@ -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)}
|
||||||
|
|
@ -380,13 +380,10 @@ impl Tek {
|
||||||
let time = ||now.map(|now|format!("{:.3}s", now/1000000.))
|
let time = ||now.map(|now|format!("{:.3}s", now/1000000.))
|
||||||
.unwrap_or("-.---s".into());
|
.unwrap_or("-.---s".into());
|
||||||
let bpm = ||format!("{:.3}", clock.timebase.bpm.get());
|
let bpm = ||format!("{:.3}", clock.timebase.bpm.get());
|
||||||
|
let theme = ItemPalette::G[128];
|
||||||
Either::new(compact,
|
Either::new(compact,
|
||||||
row!(Field(Tui::g(128).into(), "BPM", bpm()),
|
row!(Field(theme, "BPM", bpm()), Field(theme, "Beat", beat()), Field(theme, "Time", time())),
|
||||||
Field(Tui::g(128).into(), "Beat", beat()),
|
row!(FieldV(theme, "BPM", bpm()), FieldV(theme, "Beat", beat()), FieldV(theme, "Time", time())))
|
||||||
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())))
|
|
||||||
}
|
}
|
||||||
fn view_engine_stats (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_engine_stats (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
let compact = self.size.w() > 80;
|
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 sr = move||format!("{}", if compact {format!("{:.1}kHz", rate / 1000.)} else {format!("{:.0}Hz", rate)});
|
||||||
let buf = move||format!("{chunk}");
|
let buf = move||format!("{chunk}");
|
||||||
let latency = move||format!("{:.1}ms", chunk as f64 / rate * 1000.);
|
let latency = move||format!("{:.1}ms", chunk as f64 / rate * 1000.);
|
||||||
|
let theme = ItemPalette::G[128];
|
||||||
Either::new(compact,
|
Either::new(compact,
|
||||||
row!(Field(Tui::g(128).into(), "SR", sr()),
|
row!(Field(theme, "SR", sr()), Field(theme, "Buf", buf()), Field(theme, "Lat", latency())),
|
||||||
Field(Tui::g(128).into(), "Buf", buf()),
|
row!(FieldV(theme, "SR", sr()), FieldV(theme, "Buf", buf()), FieldV(theme, "Lat", latency())))
|
||||||
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())))
|
|
||||||
}
|
}
|
||||||
fn view_meter <'a> (&'a self, label: &'a str, value: f32) -> impl Content<TuiOut> + 'a {
|
fn view_meter <'a> (&'a self, label: &'a str, value: f32) -> impl Content<TuiOut> + 'a {
|
||||||
col!(
|
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 }
|
Fixed::xy(if value >= 0.0 { 13 }
|
||||||
else if value >= -1.0 { 12 }
|
else if value >= -1.0 { 12 }
|
||||||
else if value >= -2.0 { 11 }
|
else if value >= -2.0 { 11 }
|
||||||
|
|
@ -507,7 +501,7 @@ impl Tek {
|
||||||
let c = c.read().unwrap();
|
let c = c.read().unwrap();
|
||||||
(c.name.to_string(), c.color.lightest.rgb, c.color)
|
(c.name.to_string(), c.color.lightest.rgb, c.color)
|
||||||
} else {
|
} 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 same_track = selected_track == Some(t+1);
|
||||||
let selected = same_track && Some(s+1) == selected_scene;
|
let selected = same_track && Some(s+1) == selected_scene;
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,8 @@ impl ItemColor {
|
||||||
impl ItemPalette {
|
impl ItemPalette {
|
||||||
pub const G: [Self;256] = {
|
pub const G: [Self;256] = {
|
||||||
let mut builder = konst::array::ArrayBuilder::new();
|
let mut builder = konst::array::ArrayBuilder::new();
|
||||||
let mut index = 0;
|
|
||||||
while !builder.is_full() {
|
while !builder.is_full() {
|
||||||
|
let index = builder.len() as u8;
|
||||||
let light = (index as f64 * 1.3) as u8;
|
let light = (index as f64 * 1.3) as u8;
|
||||||
let lighter = (index as f64 * 1.6) as u8;
|
let lighter = (index as f64 * 1.6) as u8;
|
||||||
let lightest = (index as f64 * 1.9) 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, )),
|
darker: ItemColor::from_rgb(Color::Rgb(darker, darker, darker, )),
|
||||||
darkest: ItemColor::from_rgb(Color::Rgb(darkest, darkest, darkest, )),
|
darkest: ItemColor::from_rgb(Color::Rgb(darkest, darkest, darkest, )),
|
||||||
});
|
});
|
||||||
index += 1;
|
|
||||||
}
|
}
|
||||||
builder.build()
|
builder.build()
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue