mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
some from! trait invocations
This commit is contained in:
parent
77ea2a9b02
commit
7620739e0d
7 changed files with 53 additions and 93 deletions
|
|
@ -14,9 +14,9 @@ pub use self::{
|
|||
/// Prototypal case of implementor macro.
|
||||
/// Saves 4loc per data pats.
|
||||
#[macro_export] macro_rules! from {
|
||||
(|$self:ident: $Source:ty| $Target:ty = $cb:expr) => {
|
||||
impl From<$Source> for $Target {
|
||||
fn from (state: $Source) -> Self { $cb }
|
||||
($(<$lt:lifetime>)?|$state:ident:$Source:ty|$Target:ty=$cb:expr) => {
|
||||
impl $(<$lt>)? From<$Source> for $Target {
|
||||
fn from ($state:$Source) -> Self { $cb }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,13 +25,10 @@ pub struct ItemPalette {
|
|||
pub darkest: ItemColor,
|
||||
}
|
||||
/// Adds TUI RGB representation to an OKHSL value.
|
||||
impl From<Okhsl<f32>> for ItemColor {
|
||||
fn from (okhsl: Okhsl<f32>) -> Self { Self { okhsl, rgb: okhsl_to_rgb(okhsl) } }
|
||||
}
|
||||
from!(|okhsl: Okhsl<f32>|ItemColor = Self { okhsl, rgb: okhsl_to_rgb(okhsl) });
|
||||
/// Adds OKHSL representation to a TUI RGB value.
|
||||
impl From<Color> for ItemColor {
|
||||
fn from (rgb: Color) -> Self { Self { rgb, okhsl: rgb_to_okhsl(rgb) } }
|
||||
}
|
||||
from!(|rgb: Color|ItemColor = Self { rgb, okhsl: rgb_to_okhsl(rgb) });
|
||||
// A single color within item theme parameters, in OKHSL and RGB representations.
|
||||
impl ItemColor {
|
||||
pub fn random () -> Self {
|
||||
let mut rng = thread_rng();
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ pub struct PhrasePlayerModel {
|
|||
/// MIDI output buffer
|
||||
pub note_buf: Vec<u8>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PhrasePlayerModel {
|
||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
f.debug_struct("PhrasePlayerModel")
|
||||
|
|
@ -111,34 +110,26 @@ impl std::fmt::Debug for PhrasePlayerModel {
|
|||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&ClockModel> for PhrasePlayerModel {
|
||||
fn from (clock: &ClockModel) -> Self {
|
||||
Self {
|
||||
clock: clock.clone(),
|
||||
midi_ins: vec![],
|
||||
midi_outs: vec![],
|
||||
note_buf: vec![0;8],
|
||||
reset: true,
|
||||
recording: false,
|
||||
monitoring: false,
|
||||
overdub: false,
|
||||
play_phrase: None,
|
||||
next_phrase: None,
|
||||
notes_in: RwLock::new([false;128]).into(),
|
||||
notes_out: RwLock::new([false;128]).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(&ClockModel, &Arc<RwLock<Phrase>>)> for PhrasePlayerModel {
|
||||
fn from ((clock, phrase): (&ClockModel, &Arc<RwLock<Phrase>>)) -> Self {
|
||||
let mut model = Self::from(clock);
|
||||
model.play_phrase = Some((Moment::zero(&clock.timebase), Some(phrase.clone())));
|
||||
model
|
||||
}
|
||||
}
|
||||
|
||||
from!(|clock: &ClockModel| PhrasePlayerModel = Self {
|
||||
clock: clock.clone(),
|
||||
midi_ins: vec![],
|
||||
midi_outs: vec![],
|
||||
note_buf: vec![0;8],
|
||||
reset: true,
|
||||
recording: false,
|
||||
monitoring: false,
|
||||
overdub: false,
|
||||
play_phrase: None,
|
||||
next_phrase: None,
|
||||
notes_in: RwLock::new([false;128]).into(),
|
||||
notes_out: RwLock::new([false;128]).into(),
|
||||
});
|
||||
from!(|state: (&ClockModel, &Arc<RwLock<Phrase>>)|PhrasePlayerModel = {
|
||||
let (clock, phrase) = state;
|
||||
let mut model = Self::from(clock);
|
||||
model.play_phrase = Some((Moment::zero(&clock.timebase), Some(phrase.clone())));
|
||||
model
|
||||
});
|
||||
has_clock!(|self:PhrasePlayerModel|&self.clock);
|
||||
|
||||
impl HasMidiIns for PhrasePlayerModel {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use crate::*;
|
||||
use Ordering::Relaxed;
|
||||
|
||||
pub trait MidiViewport<E: Engine>: MidiRange + MidiPoint + HasSize<E> {
|
||||
/// Make sure cursor is within range
|
||||
fn autoscroll (&self) {
|
||||
|
|
@ -17,8 +16,11 @@ pub trait MidiViewport<E: Engine>: MidiRange + MidiPoint + HasSize<E> {
|
|||
/// Make sure best usage of screen space is achieved by default
|
||||
fn autozoom (&self) {
|
||||
}
|
||||
fn autozoom_n (&self) {
|
||||
}
|
||||
fn autozoom_t (&self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MidiRangeModel {
|
||||
/// Length of visible time axis
|
||||
|
|
@ -34,18 +36,14 @@ pub struct MidiRangeModel {
|
|||
// Lowest note displayed
|
||||
pub note_lo: Arc<AtomicUsize>,
|
||||
}
|
||||
impl From<(usize, bool)> for MidiRangeModel {
|
||||
fn from ((time_zoom, time_lock): (usize, bool)) -> Self {
|
||||
Self {
|
||||
note_axis: Arc::new(0.into()),
|
||||
note_lo: Arc::new(0.into()),
|
||||
time_axis: Arc::new(0.into()),
|
||||
time_start: Arc::new(0.into()),
|
||||
time_zoom: Arc::new(time_zoom.into()),
|
||||
time_lock: Arc::new(time_lock.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
from!(|data:(usize, bool)|MidiRangeModel = Self {
|
||||
note_axis: Arc::new(0.into()),
|
||||
note_lo: Arc::new(0.into()),
|
||||
time_axis: Arc::new(0.into()),
|
||||
time_start: Arc::new(0.into()),
|
||||
time_zoom: Arc::new(data.0.into()),
|
||||
time_lock: Arc::new(data.1.into()),
|
||||
});
|
||||
pub trait MidiRange {
|
||||
fn time_zoom (&self) -> usize;
|
||||
fn set_time_zoom (&mut self, x: usize);
|
||||
|
|
|
|||
|
|
@ -76,13 +76,7 @@ impl Plugin {
|
|||
}
|
||||
|
||||
pub struct PluginAudio(Arc<RwLock<Plugin>>);
|
||||
|
||||
impl From<&Arc<RwLock<Plugin>>> for PluginAudio {
|
||||
fn from (model: &Arc<RwLock<Plugin>>) -> Self {
|
||||
Self(model.clone())
|
||||
}
|
||||
}
|
||||
|
||||
from!(|model: &Arc<RwLock<Plugin>>| PluginAudio = Self(model.clone()));
|
||||
audio!(|self: PluginAudio, client_, _scope|{
|
||||
let state = &mut*self.0.write().unwrap();
|
||||
match state.plugin.as_mut() {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ pub struct ArrangerVColSep {
|
|||
scenes_w: u16,
|
||||
sep_fg: Color,
|
||||
}
|
||||
from!(|source:&ArrangerTui|ArrangerVColSep = Self {
|
||||
from!(|state:&ArrangerTui|ArrangerVColSep = Self {
|
||||
cols: track_widths(state.tracks()),
|
||||
scenes_w: 3 + ArrangerScene::longest_name(state.scenes()) as u16,
|
||||
sep_fg: TuiTheme::separator_fg(false),
|
||||
|
|
@ -139,7 +139,7 @@ pub struct ArrangerVHead<'a> {
|
|||
timebase: &'a Arc<Timebase>,
|
||||
current: &'a Arc<Moment>,
|
||||
}
|
||||
from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a>, { // A
|
||||
from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a> = Self { // A
|
||||
tracks: &state.tracks,
|
||||
cols: track_widths(state.tracks()),
|
||||
focused: true,
|
||||
|
|
@ -149,22 +149,6 @@ from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a>, { // A
|
|||
timebase: state.clock().timebase(),
|
||||
current: &state.clock().playhead,
|
||||
});
|
||||
|
||||
impl<'a> From<&'a ArrangerTui> for ArrangerVHead<'a> { // B
|
||||
fn from (state: &'a ArrangerTui) -> Self {
|
||||
Self {
|
||||
tracks: &state.tracks,
|
||||
cols: track_widths(state.tracks()),
|
||||
focused: true,
|
||||
selected: state.selected,
|
||||
scenes_w: 3 + ArrangerScene::longest_name(state.scenes()) as u16,
|
||||
header_h: 3,
|
||||
timebase: state.clock().timebase(),
|
||||
current: &state.clock().playhead,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render!(<Tui>|self: ArrangerVHead<'a>|row!(
|
||||
(track, w) in self.tracks.iter().zip(self.cols.iter().map(|col|col.0)) => {
|
||||
|
||||
|
|
|
|||
|
|
@ -41,23 +41,19 @@ impl Bar for SequencerStatus {
|
|||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&SequencerTui> for SequencerStatus {
|
||||
fn from (state: &SequencerTui) -> Self {
|
||||
let samples = state.clock.chunk.load(Ordering::Relaxed);
|
||||
let rate = state.clock.timebase.sr.get() as f64;
|
||||
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()),
|
||||
res: format!("│{}s│{:.1}kHz│{:.1}ms│", samples, rate / 1000., buffer * 1000.),
|
||||
}
|
||||
from!(|state:&SequencerTui|SequencerStatus = {
|
||||
let samples = state.clock.chunk.load(Ordering::Relaxed);
|
||||
let rate = state.clock.timebase.sr.get() as f64;
|
||||
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()),
|
||||
res: format!("│{}s│{:.1}kHz│{:.1}ms│", samples, rate / 1000., buffer * 1000.),
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
render!(<Tui>|self: SequencerStatus|Fixed::h(2, lay!([
|
||||
{
|
||||
let single = |binding, command|row!([" ", col!([
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue