use crate::*; impl Tek { fn update_clock (&self) { let compact = self.size.w() > 80; let clock = self.clock(); let rate = clock.timebase.sr.get(); let chunk = clock.chunk.load(Relaxed) as f64; let lat = chunk / rate * 1000.; let delta = |start: &Moment|clock.global.usec.get() - start.usec.get(); let mut fmtd = self.fmtd.write().unwrap(); fmtd.buf.update(Some(chunk), rewrite!(buf, "{chunk}")); fmtd.lat.update(Some(lat), rewrite!(buf, "{lat:.1}ms")); fmtd.sr.update(Some((compact, rate)), |buf,_,_|if compact { buf.clear(); write!(buf, "{:.1}kHz", rate / 1000.) } else { buf.clear(); write!(buf, "{:.0}Hz", rate) }); if let Some(now) = clock.started.read().unwrap().as_ref().map(delta) { let pulse = clock.timebase.usecs_to_pulse(now); let time = now/1000000.; let bpm = clock.timebase.bpm.get(); fmtd.beat.update(Some(pulse), |buf, _, _|{buf.clear();clock.timebase.format_beats_1_to(buf, pulse)}); fmtd.time.update(Some(time), rewrite!(buf, "{:.3}s", time)); fmtd.bpm.update(Some(bpm), rewrite!(buf, "{:.3}", bpm)); } else { fmtd.beat.update(None, rewrite!(buf, "-.-.--")); fmtd.time.update(None, rewrite!(buf, "-.---s")); fmtd.bpm.update(None, rewrite!(buf, "---.---")); } } pub(crate) fn view_status (&self) -> impl Content + use<'_> { self.update_clock(); let theme = ItemPalette::G[96]; let fmtd = self.fmtd.read().unwrap(); Tui::bg(Black, row!(Bsp::a( Fill::xy(Align::w(button_play_pause(self.clock.is_rolling()))), Fill::xy(Align::e(row!( FieldH(theme, "BPM", fmtd.bpm.view.clone()), FieldH(theme, "Beat", fmtd.beat.view.clone()), FieldH(theme, "Time", fmtd.time.view.clone()) ))) ))) } pub(crate) fn view_transport (&self) -> impl Content + use<'_> { self.update_clock(); let theme = ItemPalette::G[96]; let fmtd = self.fmtd.read().unwrap(); Tui::bg(Black, row!(Bsp::a( Fill::xy(Align::w( FieldH(theme, "Selected", self.selected.describe(&self.tracks, &self.scenes)) )), Fill::xy(Align::e(row!( FieldH(theme, "SR", fmtd.sr.view.clone()), FieldH(theme, "Buf", fmtd.buf.view.clone()), FieldH(theme, "Lat", fmtd.lat.view.clone()), ))) ))) } } fn button_play_pause (playing: bool) -> impl Content { let compact = true;//self.is_editing(); Tui::bg( if playing{Rgb(0,128,0)}else{Rgb(128,64,0)}, Either::new(compact, Thunk::new(move||Fixed::x(9, Either::new(playing, Tui::fg(Rgb(0, 255, 0), " PLAYING "), Tui::fg(Rgb(255, 128, 0), " STOPPED ")))), Thunk::new(move||Fixed::x(5, Either::new(playing, Tui::fg(Rgb(0, 255, 0), Bsp::s(" 🭍🭑🬽 ", " 🭞🭜🭘 ",)), Tui::fg(Rgb(255, 128, 0), Bsp::s(" ▗▄▖ ", " ▝▀▘ ",))))))) } #[cfg(test)] mod test { use super::*; #[test] fn test_view_clock () { let _ = button_play_pause(true); let mut app = Tek::default(); let _ = app.view_transport(); let _ = app.view_status(); let _ = app.update_clock(); } }