mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-10-08 18:56:42 +02:00
stack modes
This commit is contained in:
parent
9e3cc1139d
commit
f321397d6f
11 changed files with 570 additions and 498 deletions
137
src/tek_view.rs
137
src/tek_view.rs
|
|
@ -275,19 +275,21 @@ impl View<Tui, App> {
|
|||
}
|
||||
},
|
||||
|
||||
"exact" | "min" | "max" | "push" | "pull" | "pad" => {
|
||||
"exact" | "min" | "max" | "push" | "pull" | "pad" | "shrink" | "expand" => {
|
||||
match head.split('/').skip(1).next() {
|
||||
Some("w") | Some("x") => {
|
||||
let value = Arc::from(arg!(expr, head, 1, "value"));
|
||||
let value = move|state: &App|state.namespace(&value);
|
||||
let thunk = Self::compile(arg!(expr, head, 2, "content"))?;
|
||||
match ns {
|
||||
"exact" => Self::boxed(move|state, screen|Exact::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"push" => Self::boxed(move|state, screen|Push::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"pull" => Self::boxed(move|state, screen|Pull::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"pad" => Self::boxed(move|state, screen|Pad::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"min" => Self::boxed(move|state, screen|Min::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"max" => Self::boxed(move|state, screen|Max::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"shrink" => Self::boxed(move|state, screen|Shrink::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"expand" => Self::boxed(move|state, screen|Expand::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"exact" => Self::boxed(move|state, screen|Exact::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"push" => Self::boxed(move|state, screen|Push::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"pull" => Self::boxed(move|state, screen|Pull::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"pad" => Self::boxed(move|state, screen|Pad::X(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"min" => Self::boxed(move|state, screen|Min::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"max" => Self::boxed(move|state, screen|Max::W(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
_ => unreachable!()
|
||||
}
|
||||
},
|
||||
|
|
@ -296,6 +298,8 @@ impl View<Tui, App> {
|
|||
let value = move|state: &App|state.namespace(&value);
|
||||
let thunk = Self::compile(arg!(expr, head, 2, "content"))?;
|
||||
match ns {
|
||||
"shrink" => Self::boxed(move|state, screen|Shrink::H(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"expand" => Self::boxed(move|state, screen|Expand::H(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"exact" => Self::boxed(move|state, screen|Exact::H(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"push" => Self::boxed(move|state, screen|Push::Y(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
"pull" => Self::boxed(move|state, screen|Pull::Y(draw(|screen|thunk(state, screen)), value(state)?).draw(screen)),
|
||||
|
|
@ -312,12 +316,14 @@ impl View<Tui, App> {
|
|||
let value2 = move|state: &App|state.namespace(&value2);
|
||||
let thunk = Self::compile(arg!(expr, head, 3, "content"))?;
|
||||
match ns {
|
||||
"exact" => Self::boxed(move|state, screen|Exact::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"push" => Self::boxed(move|state, screen|Push::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"pull" => Self::boxed(move|state, screen|Pull::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"pad" => Self::boxed(move|state, screen|Pad::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"min" => Self::boxed(move|state, screen|Min::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"max" => Self::boxed(move|state, screen|Max::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"shrink" => Self::boxed(move|state, screen|Shrink::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"expand" => Self::boxed(move|state, screen|Expand::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"exact" => Self::boxed(move|state, screen|Exact::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"push" => Self::boxed(move|state, screen|Push::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"pull" => Self::boxed(move|state, screen|Pull::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"pad" => Self::boxed(move|state, screen|Pad::XY(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"min" => Self::boxed(move|state, screen|Min::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
"max" => Self::boxed(move|state, screen|Max::WH(draw(|screen|thunk(state, screen)), value1(state)?, value2(state)?).draw(screen)),
|
||||
_ => unreachable!()
|
||||
}
|
||||
},
|
||||
|
|
@ -385,7 +391,8 @@ impl View<Tui, App> {
|
|||
Some("Editor") => draw!("TODO editor"),
|
||||
Some("MetersIn") => draw!(|___|bg(Rgb(30, 30, 30), "Input Meters".align_s().full_h())),
|
||||
Some("MetersOut") => draw!(|___|bg(Rgb(30, 30, 30), "Output Meters".align_s().full_h())),
|
||||
Some("ModeList") => draw!(|app|app.modes.read().get(0)), // TODO all
|
||||
Some("ModeList") => draw!(|app|view_modes(app)),
|
||||
Some("HistoryCount") => draw!(|app|app.history.len()),
|
||||
Some("ScenesClips") => draw!(|app|view_scenes_clips(app)),
|
||||
Some("ScenesNames") => draw!(|app|app.view_scenes_names()),
|
||||
Some("Sessions") => draw!(|___|view_sessions()),
|
||||
|
|
@ -922,6 +929,26 @@ impl ScenesView for Project {
|
|||
}
|
||||
}
|
||||
|
||||
fn view_modes <'a, S: HasModeStack> (state: &'a S) -> impl Draw<Tui> + 'a {
|
||||
draw(move|to: &mut Tui|{
|
||||
let XYWH(x, y, w, h) = to.area();
|
||||
let mut x_next = x;
|
||||
let mut w_used = 0u16;
|
||||
for item in state.modes().iter() {
|
||||
let area = XYWH(x_next, y, w.minus(w_used), h);
|
||||
if let Some(used) = to.draw(area, item)? {
|
||||
let used_w = used.w() + 1;
|
||||
x_next = x_next.plus(used_w);
|
||||
w_used = w_used.plus(used_w);
|
||||
if w_used >= w {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Some(XYWH(x, y, w_used, h)))
|
||||
})
|
||||
}
|
||||
|
||||
/// Draw clips per scene
|
||||
fn view_scenes_clips <S: TracksView + ScenesView> (state: &S) -> impl Draw<Tui> {
|
||||
let select = state.selection();
|
||||
|
|
@ -1536,19 +1563,81 @@ impl<T: PartialEq, U> Memo<T, U> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Gettable<T> {
|
||||
/// Returns current value
|
||||
fn get (&self) -> T;
|
||||
/// Contains memoized renders of clock values.
|
||||
///
|
||||
/// Performance optimization.
|
||||
#[derive(Debug)] pub struct ClockView {
|
||||
pub sr: Memo<Option<(bool, f64)>, String>,
|
||||
pub buf: Memo<Option<f64>, String>,
|
||||
pub lat: Memo<Option<f64>, String>,
|
||||
pub bpm: Memo<Option<f64>, String>,
|
||||
pub beat: Memo<Option<f64>, String>,
|
||||
pub time: Memo<Option<f64>, String>,
|
||||
}
|
||||
|
||||
pub trait Mutable<T>: Gettable<T> {
|
||||
/// Sets new value, returns old
|
||||
fn set (&mut self, value: T) -> T;
|
||||
}
|
||||
impl_default!(ClockView: {
|
||||
let mut beat = String::with_capacity(16);
|
||||
let _ = write!(beat, "{}", Self::BEAT_EMPTY);
|
||||
let mut time = String::with_capacity(16);
|
||||
let _ = write!(time, "{}", Self::TIME_EMPTY);
|
||||
let mut bpm = String::with_capacity(16);
|
||||
let _ = write!(bpm, "{}", Self::BPM_EMPTY);
|
||||
Self {
|
||||
beat: Memo::new(None, beat),
|
||||
time: Memo::new(None, time),
|
||||
bpm: Memo::new(None, bpm),
|
||||
sr: Memo::new(None, String::with_capacity(16)),
|
||||
buf: Memo::new(None, String::with_capacity(16)),
|
||||
lat: Memo::new(None, String::with_capacity(16)),
|
||||
}
|
||||
});
|
||||
|
||||
pub trait InteriorMutable<T>: Gettable<T> {
|
||||
/// Sets new value, returns old
|
||||
fn set (&self, value: T) -> T;
|
||||
impl ClockView {
|
||||
pub const BEAT_EMPTY: &'static str = "-.-.--";
|
||||
pub const TIME_EMPTY: &'static str = "-.---s";
|
||||
pub const BPM_EMPTY: &'static str = "---.---";
|
||||
pub fn update_clock (cache: &Arc<RwLock<Self>>, clock: &Clock, compact: bool) {
|
||||
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 cache = cache.try_write().unwrap();
|
||||
|
||||
cache.buf.update(
|
||||
Some(chunk), rewrite!(buf, "{chunk}")
|
||||
);
|
||||
|
||||
cache.lat.update(
|
||||
Some(lat), rewrite!(buf, "{lat:.1}ms")
|
||||
);
|
||||
|
||||
cache.sr.update(
|
||||
Some((compact, rate)), |buf: &mut String,_,_|{
|
||||
buf.clear();
|
||||
if compact {
|
||||
write!(buf, "{:.1}kHz", rate / 1000.)
|
||||
} else {
|
||||
write!(buf, "{:.0}Hz", rate)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if let Some(now) = clock.started.try_read().unwrap().as_ref().map(delta) {
|
||||
let pulse = clock.timebase.usecs_to_pulse(now);
|
||||
let time = now/1000000.;
|
||||
let bpm = clock.timebase.bpm.get();
|
||||
cache.beat.update(Some(pulse), |buf, _, _|{
|
||||
buf.clear();
|
||||
clock.timebase.format_beats_1_to(buf, pulse)
|
||||
});
|
||||
cache.time.update(Some(time), rewrite!(buf, "{:.3}s", time));
|
||||
cache.bpm.update(Some(bpm), rewrite!(buf, "{:.3}", bpm));
|
||||
} else {
|
||||
cache.beat.update(None, rewrite!(buf, "{}", ClockView::BEAT_EMPTY));
|
||||
cache.time.update(None, rewrite!(buf, "{}", ClockView::TIME_EMPTY));
|
||||
cache.bpm.update(None, rewrite!(buf, "{}", ClockView::BPM_EMPTY));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)] mod test_view {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue