use crate::*; /// Status bar for sequencer app #[derive(Clone)] pub struct SequencerStatus { pub(crate) width: usize, pub(crate) cpu: Option, pub(crate) size: String, pub(crate) playing: bool, } from!(|state:&SequencerTui|SequencerStatus = { let samples = state.clock.chunk.load(Relaxed); let rate = state.clock.timebase.sr.get(); let buffer = samples as f64 / rate; let width = state.size.w(); Self { width, playing: state.clock.is_rolling(), cpu: state.perf.percentage().map(|cpu|format!("│{cpu:.01}%")), size: format!("{}x{}│", width, state.size.h()), } }); render!(Tui: (self: SequencerStatus) => Fixed::y(2, lay!( Self::help(), Fill::xy(Align::se(Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats()))), ))); impl SequencerStatus { fn help () -> impl Content { let single = |binding, command|row!(" ", col!( Tui::fg(TuiTheme::yellow(), binding), command )); let double = |(b1, c1), (b2, c2)|col!( row!(" ", Tui::fg(TuiTheme::yellow(), b1), " ", c1,), row!(" ", Tui::fg(TuiTheme::yellow(), b2), " ", c2,), ); Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!( single("SPACE", "play/pause"), double(("▲▼▶◀", "cursor"), ("Ctrl", "scroll"), ), double(("a", "append"), ("s", "set note"),), double((",.", "length"), ("<>", "triplet"), ), double(("[]", "phrase"), ("{}", "order"), ), double(("q", "enqueue"), ("e", "edit"), ), double(("c", "color"), ("", ""),), )) } fn stats (&self) -> impl Content + use<'_> { row!(&self.cpu, &self.size) } } /// Status bar for arranger app #[derive(Clone)] pub struct ArrangerStatus { pub(crate) width: usize, pub(crate) cpu: Option, pub(crate) size: String, pub(crate) playing: bool, } from!(|state:&ArrangerTui|ArrangerStatus = { let samples = state.clock.chunk.load(Relaxed); let rate = state.clock.timebase.sr.get(); let buffer = samples as f64 / rate; let width = state.size.w(); Self { width, playing: state.clock.is_rolling(), cpu: state.perf.percentage().map(|cpu|format!("│{cpu:.01}%")), size: format!("{}x{}│", width, state.size.h()), } }); render!(Tui: (self: ArrangerStatus) => Fixed::y(2, lay!( Self::help(), Fill::xy(Align::se(Tui::fg_bg(TuiTheme::orange(), TuiTheme::g(25), self.stats()))), ))); impl ArrangerStatus { fn help () -> impl Content { let single = |binding, command|row!(" ", col!( Tui::fg(TuiTheme::yellow(), binding), command )); let double = |(b1, c1), (b2, c2)|col!( row!(" ", Tui::fg(TuiTheme::yellow(), b1), " ", c1,), row!(" ", Tui::fg(TuiTheme::yellow(), b2), " ", c2,), ); Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(50), row!( single("SPACE", "play/pause"), single(" Ctrl", " scroll"), single(" ▲▼▶◀", " cell"), double(("p", "put"), ("g", "get")), double(("q", "enqueue"), ("e", "edit")), single(" wsad", " note"), double(("a", "append"), ("s", "set"),), double((",.", "length"), ("<>", "triplet"),), double(("[]", "phrase"), ("{}", "order"),), )) } fn stats (&self) -> impl Content + use<'_> { row!(&self.cpu, &self.size) } }