some from! trait invocations

This commit is contained in:
🪞👃🪞 2024-12-19 17:38:30 +01:00
parent 77ea2a9b02
commit 7620739e0d
7 changed files with 53 additions and 93 deletions

View file

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

View file

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

View file

@ -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,10 +110,7 @@ impl std::fmt::Debug for PhrasePlayerModel {
.finish()
}
}
impl From<&ClockModel> for PhrasePlayerModel {
fn from (clock: &ClockModel) -> Self {
Self {
from!(|clock: &ClockModel| PhrasePlayerModel = Self {
clock: clock.clone(),
midi_ins: vec![],
midi_outs: vec![],
@ -127,18 +123,13 @@ impl From<&ClockModel> for PhrasePlayerModel {
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 {
});
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 {

View file

@ -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 {
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(time_zoom.into()),
time_lock: Arc::new(time_lock.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);

View file

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

View file

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

View file

@ -41,9 +41,7 @@ impl Bar for SequencerStatus {
todo!()
}
}
impl From<&SequencerTui> for SequencerStatus {
fn from (state: &SequencerTui) -> Self {
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;
@ -55,9 +53,7 @@ impl From<&SequencerTui> for SequencerStatus {
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!([