phrase editor keybinds are fixed now

This commit is contained in:
🪞👃🪞 2024-12-21 22:24:05 +01:00
parent 3d14256d5e
commit 9f85012259
12 changed files with 55 additions and 55 deletions

View file

@ -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) }
}

View file

@ -1,6 +1,6 @@
use crate::*;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
/// Event enum for JACK events.
pub enum JackEvent {
ThreadInit,

View file

@ -1,5 +1,4 @@
use crate::*;
use Ordering::Relaxed;
pub struct Note;
impl Note {
/// (pulses, name), assuming 96 PPQ

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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
}
}

View file

@ -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()

View file

@ -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

View file

@ -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 {

View file

@ -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();

View file

@ -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))
}
}