mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
phrase editor keybinds are fixed now
This commit is contained in:
parent
3d14256d5e
commit
9f85012259
12 changed files with 55 additions and 55 deletions
|
|
@ -53,14 +53,14 @@ pub trait InteriorMutable<T>: Gettable<T> {
|
|||
}
|
||||
|
||||
impl Gettable<bool> for AtomicBool {
|
||||
fn get (&self) -> bool { self.load(Ordering::Relaxed) }
|
||||
fn get (&self) -> bool { self.load(Relaxed) }
|
||||
}
|
||||
impl InteriorMutable<bool> for AtomicBool {
|
||||
fn set (&self, value: bool) -> bool { self.swap(value, Ordering::Relaxed) }
|
||||
fn set (&self, value: bool) -> bool { self.swap(value, Relaxed) }
|
||||
}
|
||||
impl Gettable<usize> for AtomicUsize {
|
||||
fn get (&self) -> usize { self.load(Ordering::Relaxed) }
|
||||
fn get (&self) -> usize { self.load(Relaxed) }
|
||||
}
|
||||
impl InteriorMutable<usize> for AtomicUsize {
|
||||
fn set (&self, value: usize) -> usize { self.swap(value, Ordering::Relaxed) }
|
||||
fn set (&self, value: usize) -> usize { self.swap(value, Relaxed) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
/// Event enum for JACK events.
|
||||
pub enum JackEvent {
|
||||
ThreadInit,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::*;
|
||||
use Ordering::Relaxed;
|
||||
pub struct Note;
|
||||
impl Note {
|
||||
/// (pulses, name), assuming 96 PPQ
|
||||
|
|
|
|||
|
|
@ -50,11 +50,11 @@ impl<E: Engine> std::fmt::Debug for Measure<E> {
|
|||
}
|
||||
|
||||
impl<E: Engine> Measure<E> {
|
||||
pub fn w (&self) -> usize { self.x.load(Ordering::Relaxed) }
|
||||
pub fn h (&self) -> usize { self.y.load(Ordering::Relaxed) }
|
||||
pub fn w (&self) -> usize { self.x.load(Relaxed) }
|
||||
pub fn h (&self) -> usize { self.y.load(Relaxed) }
|
||||
pub fn wh (&self) -> [usize;2] { [self.w(), self.h()] }
|
||||
pub fn set_w (&self, w: impl Into<usize>) { self.x.store(w.into(), Ordering::Relaxed) }
|
||||
pub fn set_h (&self, h: impl Into<usize>) { self.y.store(h.into(), Ordering::Relaxed) }
|
||||
pub fn set_w (&self, w: impl Into<usize>) { self.x.store(w.into(), Relaxed) }
|
||||
pub fn set_h (&self, h: impl Into<usize>) { self.y.store(h.into(), Relaxed) }
|
||||
pub fn set_wh (&self, w: impl Into<usize>, h: impl Into<usize>) { self.set_w(w); self.set_h(h); }
|
||||
pub fn format (&self) -> String { format!("{}x{}", self.w(), self.h()) }
|
||||
pub fn new () -> Self {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ impl ClockModel {
|
|||
}
|
||||
/// Update chunk size
|
||||
pub fn set_chunk (&self, n_frames: usize) {
|
||||
self.chunk.store(n_frames, Ordering::Relaxed);
|
||||
self.chunk.store(n_frames, Relaxed);
|
||||
}
|
||||
pub fn update_from_scope (&self, scope: &ProcessScope) -> Usually<()> {
|
||||
// Store buffer length
|
||||
|
|
|
|||
|
|
@ -34,18 +34,18 @@ impl PerfModel {
|
|||
let t1 = self.clock.raw();
|
||||
self.used.store(
|
||||
self.clock.delta_as_nanos(t0, t1) as f64,
|
||||
Ordering::Relaxed,
|
||||
Relaxed,
|
||||
);
|
||||
self.period.store(
|
||||
scope.cycle_times().unwrap().period_usecs as f64,
|
||||
Ordering::Relaxed,
|
||||
Relaxed,
|
||||
);
|
||||
}
|
||||
}
|
||||
pub fn percentage (&self) -> Option<f64> {
|
||||
let period = self.period.load(Ordering::Relaxed) * 1000.0;
|
||||
let period = self.period.load(Relaxed) * 1000.0;
|
||||
if period > 0.0 {
|
||||
let used = self.used.load(Ordering::Relaxed);
|
||||
let used = self.used.load(Relaxed);
|
||||
Some(100.0 * used / period)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ pub trait TimeUnit: InteriorMutable<f64> {}
|
|||
#[macro_export] macro_rules! impl_time_unit {
|
||||
($T:ident) => {
|
||||
impl Gettable<f64> for $T {
|
||||
fn get (&self) -> f64 { self.0.load(Ordering::Relaxed) }
|
||||
fn get (&self) -> f64 { self.0.load(Relaxed) }
|
||||
}
|
||||
impl InteriorMutable<f64> for $T {
|
||||
fn set (&self, value: f64) -> f64 {
|
||||
let old = self.get();
|
||||
self.0.store(value, Ordering::Relaxed);
|
||||
self.0.store(value, Relaxed);
|
||||
old
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ impl crate::core::Engine for Tui {
|
|||
type Handled = bool;
|
||||
type Output = TuiOutput;
|
||||
fn exited (&self) -> bool {
|
||||
self.exited.fetch_and(true, Ordering::Relaxed)
|
||||
self.exited.fetch_and(true, Relaxed)
|
||||
}
|
||||
fn setup (&mut self) -> Usually<()> {
|
||||
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
||||
|
|
@ -115,14 +115,14 @@ impl Tui {
|
|||
let exited = engine.read().unwrap().exited.clone();
|
||||
let state = state.clone();
|
||||
spawn(move || loop {
|
||||
if exited.fetch_and(true, Ordering::Relaxed) {
|
||||
if exited.fetch_and(true, Relaxed) {
|
||||
break
|
||||
}
|
||||
if ::crossterm::event::poll(poll).is_ok() {
|
||||
let event = TuiEvent::Input(::crossterm::event::read().unwrap());
|
||||
match event {
|
||||
key_pat!(Ctrl-KeyCode::Char('c')) => {
|
||||
exited.store(true, Ordering::Relaxed);
|
||||
exited.store(true, Relaxed);
|
||||
},
|
||||
_ => {
|
||||
let exited = exited.clone();
|
||||
|
|
@ -143,7 +143,7 @@ impl Tui {
|
|||
let size = engine.read().unwrap().backend.size().expect("get size failed");
|
||||
let mut buffer = Buffer::empty(size);
|
||||
spawn(move || loop {
|
||||
if exited.fetch_and(true, Ordering::Relaxed) {
|
||||
if exited.fetch_and(true, Relaxed) {
|
||||
break
|
||||
}
|
||||
let size = engine.read().unwrap().backend.size()
|
||||
|
|
|
|||
|
|
@ -37,35 +37,38 @@ impl InputToCommand<Tui, PhraseEditorModel> for PhraseCommand {
|
|||
}
|
||||
|
||||
impl PhraseEditorModel {
|
||||
fn phrase_length (&self) -> usize {
|
||||
self.phrase().as_ref().map(|p|p.read().unwrap().length).unwrap_or(1)
|
||||
}
|
||||
fn to_editor_command (&self, from: &TuiInput) -> Option<PhraseCommand> {
|
||||
event_map!([
|
||||
(kexp!(Ctrl-Alt-Up), &|state: &Self|SetNoteScroll(state.note_point() + 3)),
|
||||
(kexp!(Ctrl-Alt-Down), &|state: &Self|SetNoteScroll(state.note_point().saturating_sub(3))),
|
||||
(kexp!(Ctrl-Alt-Left), &|state: &Self|SetTimeScroll(state.time_point().saturating_sub(state.time_zoom().get()))),
|
||||
(kexp!(Ctrl-Alt-Right), &|state: &Self|SetTimeScroll((state.time_point() + state.time_zoom().get()) % state.phrase_length().get())),
|
||||
(kexp!(Ctrl-Up), &|state: &Self|SetNoteScroll(state.note_lo().get() + 1)),
|
||||
(kexp!(Ctrl-Down), &|state: &Self|SetNoteScroll(state.note_lo().get().saturating_sub(1))),
|
||||
(kexp!(Ctrl-Left), &|state: &Self|SetTimeScroll(state.time_start().get().saturating_sub(state.note_len()))),
|
||||
(kexp!(Ctrl-Right), &|state: &Self|SetTimeScroll(state.time_start().get() + state.note_len())),
|
||||
(kexp!(Alt-Up), &|state: &Self|SetNoteCursor(state.note_point().get() + 3)),
|
||||
(kexp!(Alt-Down), &|state: &Self|SetNoteCursor(state.note_point().get().saturating_sub(3))),
|
||||
(kexp!(Alt-Left), &|state: &Self|SetTimeCursor(state.time_point().get().saturating_sub(state.time_zoom()))),
|
||||
(kexp!(Alt-Right), &|state: &Self|SetTimeCursor((state.time_point().get() + state.time_zoom().get()) % state.phrase_length().get())),
|
||||
(kexp!(Up), &|state: &Self|SetNoteCursor(state.note_point().get() + 1)),
|
||||
(kexp!(Down), &|state: &Self|SetNoteCursor(state.note_point().get().saturating_sub(1))),
|
||||
(kexp!(Left), &|state: &Self|SetTimeCursor(state.time_point().get().saturating_sub(state.note_len()))),
|
||||
(kexp!(Right), &|state: &Self|SetTimeCursor((state.time_point().get() + state.note_len().get()) % state.phrase_length().get())),
|
||||
(kexp!(Char('z')), &|state: &Self|SetTimeLock(!state.time_lock().get())),
|
||||
(kexp!(Char('-')), &|state: &Self|SetTimeZoom(Note::next(state.time_zoom().get()))),
|
||||
(kexp!(Char('_')), &|state: &Self|SetTimeZoom(Note::next(state.time_zoom().get()))),
|
||||
(kexp!(Char('=')), &|state: &Self|SetTimeZoom(Note::prev(state.time_zoom().get()))),
|
||||
(kexp!(Char('+')), &|state: &Self|SetTimeZoom(Note::prev(state.time_zoom().get()))),
|
||||
(kexp!(Enter), &|state: &Self|PutNote),
|
||||
(kexp!(Ctrl-Enter), &|state: &Self|AppendNote),
|
||||
(kexp!(Char(',')), &|state: &Self|SetNoteLength(Note::prev(state.note_len().get()))), // TODO: no 3plet
|
||||
(kexp!(Char('.')), &|state: &Self|SetNoteLength(Note::next(state.note_len().get()))),
|
||||
(kexp!(Char('<')), &|state: &Self|SetNoteLength(Note::prev(state.note_len().get()))), // TODO: 3plet
|
||||
(kexp!(Char('>')), &|state: &Self|SetNoteLength(Note::next(state.note_len().get()))),
|
||||
(kexp!(Ctrl-Alt-Up), &|s: &Self|SetNoteScroll(s.note_point() + 3)),
|
||||
(kexp!(Ctrl-Alt-Down), &|s: &Self|SetNoteScroll(s.note_point().saturating_sub(3))),
|
||||
(kexp!(Ctrl-Alt-Left), &|s: &Self|SetTimeScroll(s.time_point().saturating_sub(s.time_zoom().get()))),
|
||||
(kexp!(Ctrl-Alt-Right), &|s: &Self|SetTimeScroll((s.time_point() + s.time_zoom().get()) % s.phrase_length())),
|
||||
(kexp!(Ctrl-Up), &|s: &Self|SetNoteScroll(s.note_lo().get() + 1)),
|
||||
(kexp!(Ctrl-Down), &|s: &Self|SetNoteScroll(s.note_lo().get().saturating_sub(1))),
|
||||
(kexp!(Ctrl-Left), &|s: &Self|SetTimeScroll(s.time_start().get().saturating_sub(s.note_len()))),
|
||||
(kexp!(Ctrl-Right), &|s: &Self|SetTimeScroll(s.time_start().get() + s.note_len())),
|
||||
(kexp!(Alt-Up), &|s: &Self|SetNoteCursor(s.note_point() + 3)),
|
||||
(kexp!(Alt-Down), &|s: &Self|SetNoteCursor(s.note_point().saturating_sub(3))),
|
||||
(kexp!(Alt-Left), &|s: &Self|SetTimeCursor(s.time_point().saturating_sub(s.time_zoom().get()))),
|
||||
(kexp!(Alt-Right), &|s: &Self|SetTimeCursor((s.time_point() + s.time_zoom().get()) % s.phrase_length())),
|
||||
(kexp!(Up), &|s: &Self|SetNoteCursor(s.note_point() + 1)),
|
||||
(kexp!(Down), &|s: &Self|SetNoteCursor(s.note_point().saturating_sub(1))),
|
||||
(kexp!(Left), &|s: &Self|SetTimeCursor(s.time_point().saturating_sub(s.note_len()))),
|
||||
(kexp!(Right), &|s: &Self|SetTimeCursor((s.time_point() + s.note_len()) % s.phrase_length())),
|
||||
(kexp!(Char('z')), &|s: &Self|SetTimeLock(!s.time_lock().get())),
|
||||
(kexp!(Char('-')), &|s: &Self|SetTimeZoom(Note::next(s.time_zoom().get()))),
|
||||
(kexp!(Char('_')), &|s: &Self|SetTimeZoom(Note::next(s.time_zoom().get()))),
|
||||
(kexp!(Char('=')), &|s: &Self|SetTimeZoom(Note::prev(s.time_zoom().get()))),
|
||||
(kexp!(Char('+')), &|s: &Self|SetTimeZoom(Note::prev(s.time_zoom().get()))),
|
||||
(kexp!(Enter), &|s: &Self|PutNote),
|
||||
(kexp!(Ctrl-Enter), &|s: &Self|AppendNote),
|
||||
(kexp!(Char(',')), &|s: &Self|SetNoteLength(Note::prev(s.note_len()))), // TODO: no 3plet
|
||||
(kexp!(Char('.')), &|s: &Self|SetNoteLength(Note::next(s.note_len()))),
|
||||
(kexp!(Char('<')), &|s: &Self|SetNoteLength(Note::prev(s.note_len()))), // TODO: 3plet
|
||||
(kexp!(Char('>')), &|s: &Self|SetNoteLength(Note::next(s.note_len()))),
|
||||
//key_pat!(Char('`')) -> ToggleDirection,
|
||||
//// TODO: key_pat!(Char('/')) => // toggle 3plet
|
||||
//// TODO: key_pat!(Char('?')) => // toggle dotted
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use crate::{
|
|||
tui::phrase_length::PhraseLengthCommand as Length,
|
||||
tui::file_browser::FileBrowserCommand as Browse,
|
||||
};
|
||||
use Ordering::Relaxed;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PhraseListModel {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub struct SequencerStatus {
|
|||
pub(crate) playing: bool,
|
||||
}
|
||||
from!(|state:&SequencerTui|SequencerStatus = {
|
||||
let samples = state.clock.chunk.load(Ordering::Relaxed);
|
||||
let samples = state.clock.chunk.load(Relaxed);
|
||||
let rate = state.clock.timebase.sr.get() as f64;
|
||||
let buffer = samples as f64 / rate;
|
||||
let width = state.size.w();
|
||||
|
|
@ -45,7 +45,7 @@ from!(|state:&SequencerTui|SequencerStatus = {
|
|||
}
|
||||
});
|
||||
from!(|state:&ArrangerTui|SequencerStatus = {
|
||||
let samples = state.clock.chunk.load(Ordering::Relaxed);
|
||||
let samples = state.clock.chunk.load(Relaxed);
|
||||
let rate = state.clock.timebase.sr.get() as f64;
|
||||
let buffer = samples as f64 / rate;
|
||||
let width = state.size.w();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::*;
|
||||
use Ordering::Relaxed;
|
||||
use ::crossterm::event::*;
|
||||
|
||||
pub struct TuiInput {
|
||||
|
|
@ -7,7 +6,7 @@ pub struct TuiInput {
|
|||
pub(crate) event: TuiEvent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum TuiEvent {
|
||||
/// Terminal input
|
||||
Input(Event),
|
||||
|
|
@ -63,9 +62,9 @@ impl Input<Tui> for TuiInput {
|
|||
pub struct EventMap<'a, const N: usize, E, T, U>(pub [(E, &'a dyn Fn(T) -> U); N]);
|
||||
|
||||
impl<'a, const N: usize, E: PartialEq, T, U> EventMap<'a, N, E, T, U> {
|
||||
pub fn handle (&self, context: T, event: E) -> Option<U> {
|
||||
pub fn handle (&self, context: T, event: &E) -> Option<U> {
|
||||
for (binding, handler) in self.0.iter() {
|
||||
if event == *binding {
|
||||
if event == binding {
|
||||
return Some(handler(context))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue