mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
more updates to space and transport
This commit is contained in:
parent
9fa858f226
commit
304ce35cbb
6 changed files with 139 additions and 140 deletions
|
|
@ -100,8 +100,8 @@ impl ArrangerTui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render!(<Tui>|self: ArrangerTui|{
|
render!(<Tui>|self: ArrangerTui|{
|
||||||
let play = Fixed::wh(5, 2, PlayPause(self.clock.is_rolling()));
|
let play = PlayPause(self.clock.is_rolling());
|
||||||
let transport = TransportView::from((self, Some(ItemPalette::from(TuiTheme::g(96))), true));
|
let transport = TransportView::new(self, Some(ItemPalette::from(TuiTheme::g(96))), true);
|
||||||
let with_transport = |x|col!([row!(![&play, &transport]), &x]);
|
let with_transport = |x|col!([row!(![&play, &transport]), &x]);
|
||||||
let pool_size = if self.phrases.visible { self.splits[1] } else { 0 };
|
let pool_size = if self.phrases.visible { self.splits[1] } else { 0 };
|
||||||
let with_pool = |x|Split::w(false, pool_size, PoolView(&self.phrases), x);
|
let with_pool = |x|Split::w(false, pool_size, PoolView(&self.phrases), x);
|
||||||
|
|
|
||||||
|
|
@ -117,15 +117,16 @@ render!(<Tui>|self:Groovebox|{
|
||||||
let pool_w = if self.pool.visible { phrase_w } else { 0 };
|
let pool_w = if self.pool.visible { phrase_w } else { 0 };
|
||||||
let sampler_w = 11;
|
let sampler_w = 11;
|
||||||
let note_pt = self.editor.note_point();
|
let note_pt = self.editor.note_point();
|
||||||
|
let color = self.player.play_phrase().as_ref()
|
||||||
|
.and_then(|(_,p)|p.as_ref().map(|p|p.read().unwrap().color))
|
||||||
|
.clone();
|
||||||
Fill::wh(lay!([
|
Fill::wh(lay!([
|
||||||
&self.size,
|
&self.size,
|
||||||
Fill::wh(Align::s(Fixed::h(2, GrooveboxStatus::from(self)))),
|
Fill::wh(Align::s(Fixed::h(2, GrooveboxStatus::from(self)))),
|
||||||
Shrink::y(2, col!([
|
Shrink::y(2, col!([
|
||||||
Fixed::h(2, row!([
|
Fixed::h(3, row!([
|
||||||
Fixed::wh(5, 2, PlayPause(self.clock().is_rolling())),
|
PlayPause(self.clock().is_rolling()),
|
||||||
Fixed::h(2, TransportView::from((self, self.player.play_phrase().as_ref().map(|(_,p)|
|
TransportView::new(self, color, true),
|
||||||
p.as_ref().map(|p|p.read().unwrap().color)
|
|
||||||
).flatten().clone(), true))),
|
|
||||||
])),
|
])),
|
||||||
Push::x(sampler_w, Fixed::h(1, row!([
|
Push::x(sampler_w, Fixed::h(1, row!([
|
||||||
PhraseSelector::play_phrase(&self.player),
|
PhraseSelector::play_phrase(&self.player),
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@ render!(<Tui>|self: SequencerTui|{
|
||||||
).flatten().clone();
|
).flatten().clone();
|
||||||
|
|
||||||
let toolbar = Cond::when(self.transport, row!([
|
let toolbar = Cond::when(self.transport, row!([
|
||||||
Fixed::wh(5, 2, PlayPause(self.clock.is_rolling())),
|
PlayPause(self.clock.is_rolling()),
|
||||||
Fixed::h(2, TransportView::from((self, color, true))),
|
TransportView::new(self, color, true),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let play_queue = Cond::when(self.selectors, row!([
|
let play_queue = Cond::when(self.selectors, row!([
|
||||||
|
|
|
||||||
126
src/space.rs
126
src/space.rs
|
|
@ -11,6 +11,11 @@ mod scroll; pub use self::scroll::*;
|
||||||
mod size; pub use self::size::*;
|
mod size; pub use self::size::*;
|
||||||
mod split; pub use self::split::*;
|
mod split; pub use self::split::*;
|
||||||
|
|
||||||
|
/// A cardinal direction.
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub enum Direction { North, South, West, East, }
|
||||||
|
use self::Direction::*;
|
||||||
|
|
||||||
/// Has static methods for conditional rendering,
|
/// Has static methods for conditional rendering,
|
||||||
/// in unary and binary forms.
|
/// in unary and binary forms.
|
||||||
pub struct Cond;
|
pub struct Cond;
|
||||||
|
|
@ -94,6 +99,36 @@ pub trait Size<N: Coordinate> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait HasSize<E: Engine> {
|
||||||
|
fn size (&self) -> &Measure<E>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! has_size {
|
||||||
|
(<$E:ty>|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||||
|
impl $(<$($L),*$($T $(: $U)?),*>)? HasSize<$E> for $Struct $(<$($L),*$($T),*>)? {
|
||||||
|
fn size (&$self) -> &Measure<$E> { $cb }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A widget that tracks its render width and height
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Measure<E: Engine> {
|
||||||
|
_engine: PhantomData<E>,
|
||||||
|
pub x: Arc<AtomicUsize>,
|
||||||
|
pub y: Arc<AtomicUsize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ShowMeasure<'a>(&'a Measure<Tui>);
|
||||||
|
|
||||||
|
pub trait LayoutDebug<E: Engine> {
|
||||||
|
fn debug <W: Render<E>> (other: W) -> DebugOverlay<E, W> {
|
||||||
|
DebugOverlay(Default::default(), other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DebugOverlay<E: Engine, W: Render<E>>(PhantomData<E>, pub W);
|
||||||
|
|
||||||
pub trait Area<N: Coordinate>: Copy {
|
pub trait Area<N: Coordinate>: Copy {
|
||||||
fn x (&self) -> N;
|
fn x (&self) -> N;
|
||||||
fn y (&self) -> N;
|
fn y (&self) -> N;
|
||||||
|
|
@ -319,14 +354,27 @@ pub enum Margin<E: Engine, T: Render<E>> {
|
||||||
|
|
||||||
by_axis!(+Margin);
|
by_axis!(+Margin);
|
||||||
|
|
||||||
/// A cardinal direction.
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
pub enum Direction { North, South, West, East, }
|
|
||||||
|
|
||||||
/// A binary split with fixed proportion
|
/// A binary split with fixed proportion
|
||||||
pub struct Split<E: Engine, A: Render<E>, B: Render<E>>(
|
pub struct Split<E, A, B>(pub bool, pub Direction, pub E::Unit, A, B, PhantomData<E>)
|
||||||
pub bool, pub Direction, pub E::Unit, A, B, PhantomData<E>
|
where E: Engine, A: Render<E>, B: Render<E>;
|
||||||
);
|
|
||||||
|
impl<E: Engine, A: Render<E>, B: Render<E>> Split<E, A, B> {
|
||||||
|
#[inline] pub fn new (flip: bool, direction: Direction, proportion: E::Unit, a: A, b: B) -> Self {
|
||||||
|
Self(flip, direction, proportion, a, b, Default::default())
|
||||||
|
}
|
||||||
|
#[inline] pub fn n (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||||
|
Self::new(flip, North, proportion, a, b)
|
||||||
|
}
|
||||||
|
#[inline] pub fn s (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||||
|
Self::new(flip, South, proportion, a, b)
|
||||||
|
}
|
||||||
|
#[inline] pub fn e (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||||
|
Self::new(flip, West, proportion, a, b)
|
||||||
|
}
|
||||||
|
#[inline] pub fn w (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
||||||
|
Self::new(flip, East, proportion, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum Bsp<E: Engine, X: Render<E>, Y: Render<E>> {
|
pub enum Bsp<E: Engine, X: Render<E>, Y: Render<E>> {
|
||||||
/// X is north of Y
|
/// X is north of Y
|
||||||
|
|
@ -345,11 +393,39 @@ pub enum Bsp<E: Engine, X: Render<E>, Y: Render<E>> {
|
||||||
Null(PhantomData<E>),
|
Null(PhantomData<E>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Engine, X: Render<E>, Y: Render<E>> Bsp<E, X, Y> {
|
||||||
|
pub fn new (x: X) -> Self { Self::A(Some(x), None) }
|
||||||
|
pub fn n (x: X, y: Y) -> Self { Self::N(Some(x), Some(y)) }
|
||||||
|
pub fn s (x: X, y: Y) -> Self { Self::S(Some(x), Some(y)) }
|
||||||
|
pub fn e (x: X, y: Y) -> Self { Self::E(Some(x), Some(y)) }
|
||||||
|
pub fn w (x: X, y: Y) -> Self { Self::W(Some(x), Some(y)) }
|
||||||
|
pub fn a (x: X, y: Y) -> Self { Self::A(Some(x), Some(y)) }
|
||||||
|
pub fn b (x: X, y: Y) -> Self { Self::B(Some(x), Some(y)) }
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Stack<
|
pub struct Stack<
|
||||||
E: Engine,
|
E: Engine,
|
||||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
||||||
>(pub F, pub Direction, PhantomData<E>);
|
>(pub F, pub Direction, PhantomData<E>);
|
||||||
|
|
||||||
|
impl<
|
||||||
|
E: Engine,
|
||||||
|
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
||||||
|
> Stack<E, F> {
|
||||||
|
#[inline] pub fn new (direction: Direction, build: F) -> Self {
|
||||||
|
Self(build, direction, Default::default())
|
||||||
|
}
|
||||||
|
#[inline] pub fn right (build: F) -> Self {
|
||||||
|
Self::new(East, build)
|
||||||
|
}
|
||||||
|
#[inline] pub fn down (build: F) -> Self {
|
||||||
|
Self::new(South, build)
|
||||||
|
}
|
||||||
|
#[inline] pub fn up (build: F) -> Self {
|
||||||
|
Self::new(North, build)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export] macro_rules! col {
|
#[macro_export] macro_rules! col {
|
||||||
([$($expr:expr),* $(,)?]) => {
|
([$($expr:expr),* $(,)?]) => {
|
||||||
Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) })
|
Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) })
|
||||||
|
|
@ -395,41 +471,11 @@ pub struct Stack<
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasSize<E: Engine> {
|
|
||||||
fn size (&self) -> &Measure<E>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export] macro_rules! has_size {
|
|
||||||
(<$E:ty>|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
|
||||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasSize<$E> for $Struct $(<$($L),*$($T),*>)? {
|
|
||||||
fn size (&$self) -> &Measure<$E> { $cb }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LayoutDebug<E: Engine> {
|
|
||||||
fn debug <W: Render<E>> (other: W) -> DebugOverlay<E, W> {
|
|
||||||
DebugOverlay(Default::default(), other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DebugOverlay<E: Engine, W: Render<E>>(PhantomData<E>, pub W);
|
|
||||||
|
|
||||||
/// A widget that tracks its render width and height
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Measure<E: Engine> {
|
|
||||||
_engine: PhantomData<E>,
|
|
||||||
pub x: Arc<AtomicUsize>,
|
|
||||||
pub y: Arc<AtomicUsize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ShowMeasure<'a>(&'a Measure<Tui>);
|
|
||||||
|
|
||||||
/// A scrollable area.
|
/// A scrollable area.
|
||||||
pub struct Scroll<
|
pub struct Scroll<E, F>(pub F, pub Direction, pub u64, PhantomData<E>)
|
||||||
|
where
|
||||||
E: Engine,
|
E: Engine,
|
||||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>;
|
||||||
>(pub F, pub Direction, pub u64, PhantomData<E>);
|
|
||||||
|
|
||||||
/// Override X and Y coordinates, aligning to corner, side, or center of area
|
/// Override X and Y coordinates, aligning to corner, side, or center of area
|
||||||
pub enum Align<E: Engine, T: Render<E>> {
|
pub enum Align<E: Engine, T: Render<E>> {
|
||||||
|
|
|
||||||
|
|
@ -27,24 +27,6 @@ impl Direction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine, A: Render<E>, B: Render<E>> Split<E, A, B> {
|
|
||||||
pub fn new (flip: bool, direction: Direction, proportion: E::Unit, a: A, b: B) -> Self {
|
|
||||||
Self(flip, direction, proportion, a, b, Default::default())
|
|
||||||
}
|
|
||||||
pub fn n (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
|
||||||
Self(flip, North, proportion, a, b, Default::default())
|
|
||||||
}
|
|
||||||
pub fn s (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
|
||||||
Self(flip, South, proportion, a, b, Default::default())
|
|
||||||
}
|
|
||||||
pub fn e (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
|
||||||
Self(flip, West, proportion, a, b, Default::default())
|
|
||||||
}
|
|
||||||
pub fn w (flip: bool, proportion: E::Unit, a: A, b: B) -> Self {
|
|
||||||
Self(flip, East, proportion, a, b, Default::default())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for Split<E, A, B> {
|
impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for Split<E, A, B> {
|
||||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||||
Ok(Some(to))
|
Ok(Some(to))
|
||||||
|
|
@ -61,16 +43,6 @@ impl<E: Engine, A: Render<E>, B: Render<E>> Render<E> for Split<E, A, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine, X: Render<E>, Y: Render<E>> Bsp<E, X, Y> {
|
|
||||||
pub fn new (x: X) -> Self { Self::A(Some(x), None) }
|
|
||||||
pub fn n (x: X, y: Y) -> Self { Self::N(Some(x), Some(y)) }
|
|
||||||
pub fn s (x: X, y: Y) -> Self { Self::S(Some(x), Some(y)) }
|
|
||||||
pub fn e (x: X, y: Y) -> Self { Self::E(Some(x), Some(y)) }
|
|
||||||
pub fn w (x: X, y: Y) -> Self { Self::W(Some(x), Some(y)) }
|
|
||||||
pub fn a (x: X, y: Y) -> Self { Self::A(Some(x), Some(y)) }
|
|
||||||
pub fn b (x: X, y: Y) -> Self { Self::B(Some(x), Some(y)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Engine, X: Render<E>, Y: Render<E>> Default for Bsp<E, X, Y> {
|
impl<E: Engine, X: Render<E>, Y: Render<E>> Default for Bsp<E, X, Y> {
|
||||||
fn default () -> Self {
|
fn default () -> Self {
|
||||||
Self::Null(Default::default())
|
Self::Null(Default::default())
|
||||||
|
|
@ -142,24 +114,6 @@ impl<E: Engine, X: Render<E>, Y: Render<E>> Render<E> for Bsp<E, X, Y> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
|
||||||
E: Engine,
|
|
||||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
|
||||||
> Stack<E, F> {
|
|
||||||
#[inline] pub fn new (direction: Direction, build: F) -> Self {
|
|
||||||
Self(build, direction, Default::default())
|
|
||||||
}
|
|
||||||
#[inline] pub fn right (build: F) -> Self {
|
|
||||||
Self::new(East, build)
|
|
||||||
}
|
|
||||||
#[inline] pub fn down (build: F) -> Self {
|
|
||||||
Self::new(South, build)
|
|
||||||
}
|
|
||||||
#[inline] pub fn up (build: F) -> Self {
|
|
||||||
Self::new(North, build)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Engine, F> Render<E> for Stack<E, F>
|
impl<E: Engine, F> Render<E> for Stack<E, F>
|
||||||
where
|
where
|
||||||
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,13 @@ from_jack!(|jack|TransportTui Self {
|
||||||
cursor: (0, 0),
|
cursor: (0, 0),
|
||||||
focus: TransportFocus::PlayPause
|
focus: TransportFocus::PlayPause
|
||||||
});
|
});
|
||||||
has_clock!(|self:TransportTui|&self.clock);
|
has_clock!(|self: TransportTui|&self.clock);
|
||||||
audio!(|self:TransportTui,client,scope|ClockAudio(self).process(client, scope));
|
audio!(|self: TransportTui, client, scope|ClockAudio(self).process(client, scope));
|
||||||
handle!(<Tui>|self:TransportTui,from|TransportCommand::execute_with_state(self, from));
|
handle!(<Tui>|self: TransportTui, from|TransportCommand::execute_with_state(self, from));
|
||||||
render!(<Tui>|self: TransportTui|TransportView::from((self, None, true)));
|
render!(<Tui>|self: TransportTui|row!([
|
||||||
|
Fixed::wh(5, 3, PlayPause(false)),
|
||||||
|
Fixed::h(3, TransportView::new(self, None, true))
|
||||||
|
]));
|
||||||
impl std::fmt::Debug for TransportTui {
|
impl std::fmt::Debug for TransportTui {
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
f.debug_struct("TransportTui")
|
f.debug_struct("TransportTui")
|
||||||
|
|
@ -46,8 +49,8 @@ pub struct TransportView {
|
||||||
current_sample: f64,
|
current_sample: f64,
|
||||||
current_second: f64,
|
current_second: f64,
|
||||||
}
|
}
|
||||||
impl<T: HasClock> From<(&T, Option<ItemPalette>, bool)> for TransportView {
|
impl TransportView {
|
||||||
fn from ((state, color, focused): (&T, Option<ItemPalette>, bool)) -> Self {
|
pub fn new (state: &impl HasClock, color: Option<ItemPalette>, focused: bool) -> Self {
|
||||||
let clock = state.clock();
|
let clock = state.clock();
|
||||||
let rate = clock.timebase.sr.get();
|
let rate = clock.timebase.sr.get();
|
||||||
let chunk = clock.chunk.load(Relaxed);
|
let chunk = clock.chunk.load(Relaxed);
|
||||||
|
|
@ -58,61 +61,56 @@ impl<T: HasClock> From<(&T, Option<ItemPalette>, bool)> for TransportView {
|
||||||
let chunk = format!("{chunk}");
|
let chunk = format!("{chunk}");
|
||||||
let latency = format!("{latency}");
|
let latency = format!("{latency}");
|
||||||
let color = color.unwrap_or(ItemPalette::from(TuiTheme::g(32)));
|
let color = color.unwrap_or(ItemPalette::from(TuiTheme::g(32)));
|
||||||
if let Some(started) = clock.started.read().unwrap().as_ref() {
|
let (
|
||||||
|
global_sample, global_second, current_sample, current_second, beat
|
||||||
|
) = if let Some(started) = clock.started.read().unwrap().as_ref() {
|
||||||
let current_sample = (clock.global.sample.get() - started.sample.get())/1000.;
|
let current_sample = (clock.global.sample.get() - started.sample.get())/1000.;
|
||||||
let current_usec = clock.global.usec.get() - started.usec.get();
|
let current_usec = clock.global.usec.get() - started.usec.get();
|
||||||
let current_second = current_usec/1000000.;
|
let current_second = current_usec/1000000.;
|
||||||
Self {
|
let global_sample = format!("{:.0}k", started.sample.get()/1000.);
|
||||||
color, focused, sr, bpm, ppq, chunk, latency,
|
let global_second = format!("{:.1}s", started.usec.get()/1000.);
|
||||||
started: true,
|
let beat = clock.timebase.format_beats_1(clock.timebase.usecs_to_pulse(current_usec));
|
||||||
global_sample: format!("{:.0}k", started.sample.get()/1000.),
|
(global_sample, global_second, current_sample, current_second, beat)
|
||||||
global_second: format!("{:.1}s", started.usec.get()/1000.),
|
|
||||||
current_sample,
|
|
||||||
current_second,
|
|
||||||
beat: clock.timebase.format_beats_0(
|
|
||||||
clock.timebase.usecs_to_pulse(current_usec)
|
|
||||||
),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Self {
|
let global_sample = format!("{:.0}k", clock.global.sample.get()/1000.);
|
||||||
color, focused, sr, bpm, ppq, chunk, latency,
|
let global_second = format!("{:.1}s", clock.global.usec.get()/1000000.);
|
||||||
started: false,
|
let current_sample = 0.0;
|
||||||
global_sample: format!("{:.0}k", clock.global.sample.get()/1000.),
|
let current_second = 0.0;
|
||||||
global_second: format!("{:.1}s", clock.global.usec.get()/1000000.),
|
let beat = format!("000.0.00");
|
||||||
current_sample: 0.0,
|
(global_sample, global_second, current_sample, current_second, beat)
|
||||||
current_second: 0.0,
|
};
|
||||||
beat: format!("000.0.00")
|
Self {
|
||||||
}
|
color, focused, sr, bpm, ppq, chunk, latency, started: false,
|
||||||
|
global_sample, global_second, current_sample, current_second, beat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render!(<Tui>|self: TransportView|{
|
render!(<Tui>|self: TransportView|{
|
||||||
let color = self.color;
|
let color = self.color;
|
||||||
struct Field<'a>(&'a str, &'a str, &'a ItemPalette);
|
Fixed::h(3, Tui::bg(color.base.rgb, Fill::w(row!([
|
||||||
render!(<Tui>|self: Field<'a>|row!([
|
|
||||||
Tui::fg_bg(self.2.lightest.rgb, self.2.base.rgb, Tui::bold(true, self.0)),
|
|
||||||
Tui::fg_bg(self.2.base.rgb, self.2.darkest.rgb, "▌"),
|
|
||||||
Tui::fg_bg(self.2.lightest.rgb, self.2.darkest.rgb, format!("{:>10}", self.1)),
|
|
||||||
Tui::fg_bg(self.2.darkest.rgb, self.2.base.rgb, "▌"),
|
|
||||||
]));
|
|
||||||
Tui::bg(color.base.rgb, Fill::w(row!([
|
|
||||||
//PlayPause(self.started), " ",
|
//PlayPause(self.started), " ",
|
||||||
col!([
|
col!([
|
||||||
Field(" Beat", self.beat.as_str(), &color),
|
TransportField(" Beat", self.beat.as_str(), &color),
|
||||||
Field(" Time", format!("{:.1}s", self.current_second).as_str(), &color),
|
TransportField(" Time", format!("{:.1}s", self.current_second).as_str(), &color),
|
||||||
|
TransportField(" BPM", self.bpm.as_str(), &color),
|
||||||
|
]),
|
||||||
|
col!([
|
||||||
|
TransportField(" Rate", format!("{}", self.sr).as_str(), &color),
|
||||||
|
TransportField(" Chunk", format!("{}", self.chunk).as_str(), &color),
|
||||||
|
TransportField(" Lag", format!("{:.3}ms", self.latency).as_str(), &color),
|
||||||
]),
|
]),
|
||||||
col!([
|
col!([
|
||||||
Field(" BPM", self.bpm.as_str(), &color),
|
|
||||||
//Field(" Smpl", format!("{:.1}k", self.current_sample).as_str(), &color),
|
|
||||||
Field(" Rate", format!("{}", self.sr).as_str(), &color),
|
|
||||||
//Field(" CPU%", format!("{:.1}ms", self.perf).as_str(), &color),
|
//Field(" CPU%", format!("{:.1}ms", self.perf).as_str(), &color),
|
||||||
]),
|
]),
|
||||||
col!([
|
]))))
|
||||||
Field(" Chunk", format!("{}", self.chunk).as_str(), &color),
|
|
||||||
Field(" Lag", format!("{:.3}ms", self.latency).as_str(), &color),
|
|
||||||
]),
|
|
||||||
])))
|
|
||||||
});
|
});
|
||||||
|
struct TransportField<'a>(&'a str, &'a str, &'a ItemPalette);
|
||||||
|
render!(<Tui>|self: TransportField<'a>|row!([
|
||||||
|
Tui::fg_bg(self.2.lightest.rgb, self.2.base.rgb, Tui::bold(true, self.0)),
|
||||||
|
Tui::fg_bg(self.2.base.rgb, self.2.darkest.rgb, "▌"),
|
||||||
|
Tui::fg_bg(self.2.lightest.rgb, self.2.darkest.rgb, format!("{:>10}", self.1)),
|
||||||
|
Tui::fg_bg(self.2.darkest.rgb, self.2.base.rgb, "▌"),
|
||||||
|
]));
|
||||||
pub struct PlayPause(pub bool);
|
pub struct PlayPause(pub bool);
|
||||||
render!(<Tui>|self: PlayPause|Tui::bg(
|
render!(<Tui>|self: PlayPause|Tui::bg(
|
||||||
if self.0{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
if self.0{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue