Compare commits

..

4 commits

7 changed files with 384 additions and 213 deletions

112
.old/demo.rs.old Normal file
View file

@ -0,0 +1,112 @@
use tek::*;
fn main () -> Usually<()> {
Tui::run(Arc::new(RwLock::new(Demo::new())))?;
Ok(())
}
pub struct Demo<E: Engine> {
index: usize,
items: Vec<Box<dyn Render<Engine = E>>>
}
impl Demo<Tui> {
fn new () -> Self {
Self {
index: 0,
items: vec![]
}
}
}
impl Content for Demo<Tui> {
type Engine = Tui;
fn content (&self) -> dyn Render<Engine = Tui> {
let border_style = Style::default().fg(Color::Rgb(0,0,0));
Align::Center(Layers::new(move|add|{
add(&Background(Color::Rgb(0,128,128)))?;
add(&Margin::XY(1, 1, Stack::down(|add|{
add(&Layers::new(|add|{
add(&Background(Color::Rgb(128,96,0)))?;
add(&Border(Square(border_style)))?;
add(&Margin::XY(2, 1, "..."))?;
Ok(())
}).debug())?;
add(&Layers::new(|add|{
add(&Background(Color::Rgb(128,64,0)))?;
add(&Border(Lozenge(border_style)))?;
add(&Margin::XY(4, 2, "---"))?;
Ok(())
}).debug())?;
add(&Layers::new(|add|{
add(&Background(Color::Rgb(96,64,0)))?;
add(&Border(SquareBold(border_style)))?;
add(&Margin::XY(6, 3, "~~~"))?;
Ok(())
}).debug())?;
Ok(())
})).debug())?;
Ok(())
}))
//Align::Center(Margin::X(1, Layers::new(|add|{
//add(&Background(Color::Rgb(128,0,0)))?;
//add(&Stack::down(|add|{
//add(&Margin::Y(1, Layers::new(|add|{
//add(&Background(Color::Rgb(0,128,0)))?;
//add(&Align::Center("12345"))?;
//add(&Align::Center("FOO"))
//})))?;
//add(&Margin::XY(1, 1, Layers::new(|add|{
//add(&Align::Center("1234567"))?;
//add(&Align::Center("BAR"))?;
//add(&Background(Color::Rgb(0,0,128)))
//})))
//}))
//})))
//Align::Y(Layers::new(|add|{
//add(&Background(Color::Rgb(128,0,0)))?;
//add(&Margin::X(1, Align::Center(Stack::down(|add|{
//add(&Align::X(Margin::Y(1, Layers::new(|add|{
//add(&Background(Color::Rgb(0,128,0)))?;
//add(&Align::Center("12345"))?;
//add(&Align::Center("FOO"))
//})))?;
//add(&Margin::XY(1, 1, Layers::new(|add|{
//add(&Align::Center("1234567"))?;
//add(&Align::Center("BAR"))?;
//add(&Background(Color::Rgb(0,0,128)))
//})))?;
//Ok(())
//})))))
//}))
}
}
impl Handle<TuiIn> for Demo<Tui> {
fn handle (&mut self, from: &TuiIn) -> Perhaps<bool> {
use KeyCode::{PageUp, PageDown};
match from.event() {
kexp!(PageUp) => {
self.index = (self.index + 1) % self.items.len();
},
kexp!(PageDown) => {
self.index = if self.index > 1 {
self.index - 1
} else {
self.items.len() - 1
};
},
_ => return Ok(None)
}
Ok(Some(true))
}
}

View file

@ -17,8 +17,7 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm
None None
})); }));
#[tengri_proc::expose] #[tengri_proc::expose] impl Tek {
impl Tek {
fn focus_editor (&self) -> bool { fn focus_editor (&self) -> bool {
self.is_editing() self.is_editing()
} }
@ -161,8 +160,7 @@ impl Tek {
} }
} }
#[tengri_proc::expose] #[tengri_proc::expose] impl MidiPool {
impl MidiPool {
fn clip_new (&self) -> MidiClip { fn clip_new (&self) -> MidiClip {
self.new_clip() self.new_clip()
} }
@ -186,8 +184,7 @@ impl MidiPool {
} }
} }
#[tengri_proc::expose] #[tengri_proc::expose] impl MidiEditor {
impl MidiEditor {
fn time_lock (&self) -> bool { fn time_lock (&self) -> bool {
self.get_time_lock() self.get_time_lock()
} }
@ -256,27 +253,26 @@ impl MidiEditor {
} }
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl TekCommand {
impl TekCommand { fn toggle_help (tek: &mut Tek, value: bool) -> Perhaps<Self> {
fn toggle_help (&self, tek: &mut Tek, value: bool) -> Perhaps<Self> {
tek.toggle_dialog(Some(Dialog::Help)); tek.toggle_dialog(Some(Dialog::Help));
Ok(None) Ok(None)
} }
fn toggle_menu (&self, tek: &mut Tek, value: bool) -> Perhaps<Self> { fn toggle_menu (tek: &mut Tek, value: bool) -> Perhaps<Self> {
tek.toggle_dialog(Some(Dialog::Menu)); tek.toggle_dialog(Some(Dialog::Menu));
Ok(None) Ok(None)
} }
fn toggle_edit (&self, tek: &mut Tek, value: bool) -> Perhaps<Self> { fn toggle_edit (tek: &mut Tek, value: bool) -> Perhaps<Self> {
tek.toggle_editor(Some(value)); tek.toggle_editor(Some(value));
Ok(None) Ok(None)
} }
fn editor (&self, tek: &mut Tek, command: MidiEditCommand) -> Perhaps<Self> { fn editor (tek: &mut Tek, command: MidiEditCommand) -> Perhaps<Self> {
Ok(tek.editor.as_mut().map(|editor|command.execute(editor)) Ok(tek.editor.as_mut().map(|editor|command.execute(editor))
.transpose()? .transpose()?
.flatten() .flatten()
.map(|undo|Self::Editor { command: undo })) .map(|undo|Self::Editor { command: undo }))
} }
fn pool (&self, tek: &mut Tek, command: PoolCommand) -> Perhaps<Self> { fn pool (tek: &mut Tek, command: PoolCommand) -> Perhaps<Self> {
Ok(if let Some(pool) = tek.pool.as_mut() { Ok(if let Some(pool) = tek.pool.as_mut() {
let undo = command.clone().delegate(pool, |command|TekCommand::Pool{command})?; let undo = command.clone().delegate(pool, |command|TekCommand::Pool{command})?;
// update linked editor after pool action // update linked editor after pool action
@ -293,53 +289,53 @@ impl TekCommand {
None None
}) })
} }
fn sampler (&self, tek: &mut Tek, command: SamplerCommand) -> Perhaps<Self> { fn sampler (tek: &mut Tek, command: SamplerCommand) -> Perhaps<Self> {
Ok(tek.sampler_mut() Ok(tek.sampler_mut()
.map(|s|command.delegate(s, |command|Self::Sampler{command})) .map(|s|command.delegate(s, |command|Self::Sampler{command}))
.transpose()? .transpose()?
.flatten()) .flatten())
} }
fn scene (&self, tek: &mut Tek, command: SceneCommand) -> Perhaps<Self> { fn scene (tek: &mut Tek, command: SceneCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Scene{command})?) Ok(command.delegate(tek, |command|Self::Scene{command})?)
} }
fn track (&self, tek: &mut Tek, command: TrackCommand) -> Perhaps<Self> { fn track (tek: &mut Tek, command: TrackCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Track{command})?) Ok(command.delegate(tek, |command|Self::Track{command})?)
} }
fn input (&self, tek: &mut Tek, command: InputCommand) -> Perhaps<Self> { fn input (tek: &mut Tek, command: InputCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Input{command})?) Ok(command.delegate(tek, |command|Self::Input{command})?)
} }
fn output (&self, tek: &mut Tek, command: OutputCommand) -> Perhaps<Self> { fn output (tek: &mut Tek, command: OutputCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Output{command})?) Ok(command.delegate(tek, |command|Self::Output{command})?)
} }
fn clip (&self, tek: &mut Tek, command: ClipCommand) -> Perhaps<Self> { fn clip (tek: &mut Tek, command: ClipCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Clip{command})?) Ok(command.delegate(tek, |command|Self::Clip{command})?)
} }
fn clock (&self, tek: &mut Tek, command: ClockCommand) -> Perhaps<Self> { fn clock (tek: &mut Tek, command: ClockCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Clock{command})?) Ok(command.execute(&mut tek.clock)?.map(|command|Self::Clock{command}))
} }
fn device (&self, tek: &mut Tek, command: DeviceCommand) -> Perhaps<Self> { fn device (tek: &mut Tek, command: DeviceCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Device{command})?) Ok(command.delegate(tek, |command|Self::Device{command})?)
} }
fn message (&self, tek: &mut Tek, command: MessageCommand) -> Perhaps<Self> { fn message (tek: &mut Tek, command: MessageCommand) -> Perhaps<Self> {
Ok(command.delegate(tek, |command|Self::Message{command})?) Ok(command.delegate(tek, |command|Self::Message{command})?)
} }
fn color (&self, tek: &mut Tek, theme: ItemTheme) -> Perhaps<Self> { fn color (tek: &mut Tek, theme: ItemTheme) -> Perhaps<Self> {
Ok(tek.set_color(Some(theme)).map(|theme|Self::Color{theme})) Ok(tek.set_color(Some(theme)).map(|theme|Self::Color{theme}))
} }
fn enqueue (&self, tek: &mut Tek, clip: Option<Arc<RwLock<MidiClip>>>) -> Perhaps<Self> { fn enqueue (tek: &mut Tek, clip: Option<Arc<RwLock<MidiClip>>>) -> Perhaps<Self> {
todo!() todo!()
} }
fn history (&self, tek: &mut Tek, delta: isize) -> Perhaps<Self> { fn history (tek: &mut Tek, delta: isize) -> Perhaps<Self> {
todo!() todo!()
} }
fn zoom (&self, tek: &mut Tek, zoom: usize) -> Perhaps<Self> { fn zoom (tek: &mut Tek, zoom: usize) -> Perhaps<Self> {
todo!() todo!()
} }
fn launch (&self, tek: &mut Tek) -> Perhaps<Self> { fn launch (tek: &mut Tek) -> Perhaps<Self> {
tek.launch(); tek.launch();
Ok(None) Ok(None)
} }
fn select (&self, tek: &mut Tek, selection: Selection) -> Perhaps<Self> { fn select (tek: &mut Tek, selection: Selection) -> Perhaps<Self> {
tek.select(selection); tek.select(selection);
Ok(None) Ok(None)
//("select" [t: usize, s: usize] Some(match (t.expect("no track"), s.expect("no scene")) { //("select" [t: usize, s: usize] Some(match (t.expect("no track"), s.expect("no scene")) {
@ -348,129 +344,169 @@ impl TekCommand {
//(0, s) => Self::Select(Selection::Scene(s)), //(0, s) => Self::Select(Selection::Scene(s)),
//(t, s) => Self::Select(Selection::TrackClip { track: t, scene: s }) }))) //(t, s) => Self::Select(Selection::TrackClip { track: t, scene: s }) })))
} }
fn stop_all (&self, tek: &mut Tek) -> Perhaps<Self> { fn stop_all (tek: &mut Tek) -> Perhaps<Self> {
tek.stop_all(); tek.stop_all();
Ok(None) Ok(None)
} }
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl InputCommand {
impl InputCommand { fn add (tek: &mut Tek) -> Perhaps<Self> {
fn add (&self, tek: &mut Tek) -> Perhaps<Self> {
tek.midi_in_add()?; tek.midi_in_add()?;
Ok(None) Ok(None)
} }
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl OutputCommand {
impl OutputCommand { fn add (tek: &mut Tek) -> Perhaps<Self> {
fn add (&self, tek: &mut Tek) -> Perhaps<Self> {
tek.midi_out_add()?; tek.midi_out_add()?;
Ok(None) Ok(None)
} }
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl DeviceCommand {
impl DeviceCommand { fn picker (tek: &mut Tek) -> Perhaps<Self> {
fn picker (&self, tek: &mut Tek) -> Perhaps<Self> {
tek.device_picker_show(); tek.device_picker_show();
Ok(None) Ok(None)
} }
fn pick (&self, tek: &mut Tek, i: usize) -> Perhaps<Self> { fn pick (tek: &mut Tek, i: usize) -> Perhaps<Self> {
tek.device_pick(i); tek.device_pick(i);
Ok(None) Ok(None)
} }
fn add (&self, tek: &mut Tek, i: usize) -> Perhaps<Self> { fn add (tek: &mut Tek, i: usize) -> Perhaps<Self> {
tek.device_add(i); tek.device_add(i);
Ok(None) Ok(None)
} }
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl MessageCommand {
impl MessageCommand { fn dismiss (tek: &mut Tek) -> Perhaps<Self> {
fn dismiss (&self, tek: &mut Tek) -> Perhaps<Self> {
tek.message_dismiss(); tek.message_dismiss();
Ok(None) Ok(None)
} }
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl TrackCommand {
impl TrackCommand { fn toggle_play (tek: &mut Tek) -> Perhaps<Self> {
//(TogglePlay [] Some(Self::TogglePlay)) todo!()
//(ToggleSolo [] Some(Self::ToggleSolo)) }
//(SetSize [t: usize] cmd_todo!("\n\rtodo: {self:?}")) fn toggle_solo (tek: &mut Tek) -> Perhaps<Self> {
//(SetZoom [z: usize] cmd_todo!("\n\rtodo: {self:?}")) todo!()
//(Swap [a: usize, b: usize] cmd_todo!("\n\rtodo: {self:?}")) }
//(Del [index: usize] cmd!(app.track_del(index))) fn toggle_rec (tek: &mut Tek) -> Perhaps<Self> {
//(Stop [index: usize] cmd!(app.tracks[index].player.enqueue_next(None))) tek.track_toggle_record();
//(Add [] Some(Self::Del(app.track_add_focus()?))) Ok(Some(Self::ToggleRec))
//(SetColor [i: usize, c: ItemTheme] Some(Self::SetColor(i, app.track_set_color(i, c)))) }
//(ToggleRec [] { app.track_toggle_record(); Some(Self::ToggleRec) }) fn toggle_mon (tek: &mut Tek) -> Perhaps<Self> {
//(ToggleMon [] { app.track_toggle_monitor(); Some(Self::ToggleMon) })) tek.track_toggle_monitor();
//("add" [] Some(Self::Add)) Ok(Some(Self::ToggleMon))
//("size" [a: usize] Some(Self::SetSize(a.unwrap()))) }
//("zoom" [a: usize] Some(Self::SetZoom(a.unwrap()))) fn set_size (tek: &mut Tek, size: usize) -> Perhaps<Self> {
//("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::random()))) todo!()
//("delete" [a: Option<usize>] Some(Self::Del(a.flatten().unwrap()))) }
//("stop" [a: usize] Some(Self::Stop(a.unwrap()))) fn set_zoom (tek: &mut Tek, zoom: usize) -> Perhaps<Self> {
//("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap()))) todo!()
//("play" [] Some(Self::TogglePlay)) }
//("solo" [] Some(Self::ToggleSolo)) fn swap (tek: &mut Tek, index: usize, other: usize) -> Perhaps<Self> {
//("rec" [] Some(Self::ToggleRec)) todo!();
//("mon" [] Some(Self::ToggleMon)))); Ok(Some(Self::Swap { index, other }))
}
fn del (tek: &mut Tek, index: usize) -> Perhaps<Self> {
tek.track_del(index);
Ok(None)
}
fn stop (tek: &mut Tek, index: usize) -> Perhaps<Self> {
tek.tracks[index].player.enqueue_next(None);
Ok(None)
}
fn add (tek: &mut Tek) -> Perhaps<Self> {
Ok(Some(Self::Del { index: tek.track_add_focus()? }))
}
fn set_color (tek: &mut Tek, index: usize, color: ItemTheme) -> Perhaps<Self> {
Ok(Some(Self::SetColor { index, color: tek.track_set_color(index, color) }))
}
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl SceneCommand {
impl SceneCommand { fn add (tek: &mut Tek) -> Perhaps<Self> {
//(Swap [a: usize, b: usize] cmd_todo!("\n\rtodo: {self:?}")) todo!()
//(SetSize [index: usize] cmd_todo!("\n\rtodo: {self:?}")) }
//(SetZoom [zoom: usize] cmd_todo!("\n\rtodo: {self:?}")) fn del (tek: &mut Tek, index: usize) -> Perhaps<Self> {
//(Enqueue [scene: usize] cmd!(app.scene_enqueue(scene))) tek.scene_del(index);
//(Del [index: usize] cmd!(app.scene_del(index))) Ok(None)
//(Add [] Some(Self::Del(app.scene_add_focus()?))) }
//(SetColor [i: usize, c: ItemTheme] Some(Self::SetColor(i, app.scene_set_color(i, c))))) fn enqueue (tek: &mut Tek, index: usize) -> Perhaps<Self> {
//("add" [] Some(Self::Add)) tek.scene_enqueue(index);
//("delete" [a: Option<usize>] Some(Self::Del(a.flatten().unwrap()))) Ok(None)
//("zoom" [a: usize] Some(Self::SetZoom(a.unwrap()))) }
//("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::G[128]))) fn set_color (tek: &mut Tek, index: usize, color: ItemTheme) -> Perhaps<Self> {
//("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap()))) Ok(Some(Self::SetColor { index, color: tek.scene_set_color(index, color) }))
//("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))) }
fn set_size (tek: &mut Tek, index: usize, size: usize) -> Perhaps<Self> {
todo!()
}
fn set_zoom (tek: &mut Tek, index: usize, zoom: usize) -> Perhaps<Self> {
todo!()
}
fn swap (tek: &mut Tek, index: usize, other: usize) -> Perhaps<Self> {
todo!();
Ok(Some(Self::Swap { index, other }))
}
} }
#[tengri_proc::command(Tek)] #[tengri_proc::command(Tek)] impl ClipCommand {
impl ClipCommand { fn get (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//(Get [a: usize, b: usize] cmd_todo!("\n\rtodo: clip: get: {a} {b}")) //(Get [a: usize, b: usize] cmd_todo!("\n\rtodo: clip: get: {a} {b}"))
//(Edit [clip: MaybeClip] cmd_todo!("\n\rtodo: clip: edit: {clip:?}")) //("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap())))
//(SetLoop [t: usize, s: usize, l: bool] cmd_todo!("\n\rtodo: {self:?}")) todo!()
//(Put [t: usize, s: usize, c: MaybeClip] }
//Some(Self::Put(t, s, app.clip_put(t, s, c)))) fn edit (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//(Enqueue [t: usize, s: usize] //(Edit [clip: MaybeClip] cmd_todo!("\n\rtodo: clip: edit: {clip:?}"))
//cmd!(app.tracks[t].player.enqueue_next(app.scenes[s].clips[t].as_ref()))) //("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap())))
//(SetColor [t: usize, s: usize, c: ItemTheme] todo!()
//app.clip_set_color(t, s, c).map(|o|Self::SetColor(t, s, o))))); }
//("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap()))) fn set_loop (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemTheme::random()))) //(SetLoop [t: usize, s: usize, l: bool] cmd_todo!("\n\rtodo: {self:?}"))
//("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap()))) //("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap())))
//("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap()))) todo!()
//("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap()))) }
//("put" [a: usize, b: usize, c: MaybeClip] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap()))) fn put (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//(Put [t: usize, s: usize, c: MaybeClip]
//Some(Self::Put(t, s, app.clip_put(t, s, c))))
//("put" [a: usize, b: usize, c: MaybeClip] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))
todo!()
}
fn del (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//("delete" [a: usize, b: usize] Some(Self::Put(a.unwrap(), b.unwrap(), None)))) //("delete" [a: usize, b: usize] Some(Self::Put(a.unwrap(), b.unwrap(), None))))
todo!()
}
fn enqueue (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//(Enqueue [t: usize, s: usize]
//cmd!(app.tracks[t].player.enqueue_next(app.scenes[s].clips[t].as_ref())))
//("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
todo!()
}
fn set_color (tek: &mut Tek, a: usize, b: usize) -> Perhaps<Self> {
//(SetColor [t: usize, s: usize, c: ItemTheme]
//app.clip_set_color(t, s, c).map(|o|Self::SetColor(t, s, o)))));
//("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemTheme::random())))
todo!()
}
} }
#[tengri_proc::command(MidiPool)] #[tengri_proc::command(MidiPool)] impl PoolCommand {
impl PoolCommand {
/// Toggle visibility of pool /// Toggle visibility of pool
fn show (&self, pool: &mut MidiPool, visible: bool) -> Perhaps<Self> { fn show (pool: &mut MidiPool, visible: bool) -> Perhaps<Self> {
pool.visible = visible; pool.visible = visible;
Ok(Some(Self::Show(!visible))) Ok(Some(Self::Show { visible: !visible }))
} }
/// Select a clip from the clip pool /// Select a clip from the clip pool
fn select (&self, pool: &mut MidiPool, index: usize) -> Perhaps<Self> { fn select (pool: &mut MidiPool, index: usize) -> Perhaps<Self> {
pool.set_clip_index(index); pool.set_clip_index(index);
Ok(None) Ok(None)
} }
/// Rename a clip /// Rename a clip
fn rename (&self, pool: &mut MidiPool, command: ClipRenameCommand) -> Perhaps<Self> { fn rename (pool: &mut MidiPool, command: ClipRenameCommand) -> Perhaps<Self> {
Ok(match command { Ok(match command {
ClipRenameCommand::Begin => { ClipRenameCommand::Begin => {
pool.begin_clip_rename(); pool.begin_clip_rename();
@ -480,7 +516,7 @@ impl PoolCommand {
}) })
} }
/// Change the length of a clip /// Change the length of a clip
fn length (&self, pool: &mut MidiPool, command: ClipLengthCommand) -> Perhaps<Self> { fn length (pool: &mut MidiPool, command: ClipLengthCommand) -> Perhaps<Self> {
Ok(match command { Ok(match command {
ClipLengthCommand::Begin => { ClipLengthCommand::Begin => {
pool.begin_clip_length(); pool.begin_clip_length();
@ -490,9 +526,9 @@ impl PoolCommand {
}) })
} }
/// Import from file /// Import from file
fn import (&self, pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps<Self> { fn import (pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps<Self> {
Ok(match command { Ok(match command {
ClipImportCommand::Begin => { FileBrowserCommand::Begin => {
pool.begin_import(); pool.begin_import();
None None
}, },
@ -500,9 +536,9 @@ impl PoolCommand {
}) })
} }
/// Export to file /// Export to file
fn export (&self, pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps<Self> { fn export (pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps<Self> {
Ok(match command { Ok(match command {
ClipExportCommand::Begin => { FileBrowserCommand::Begin => {
pool.begin_export(); pool.begin_export();
None None
}, },
@ -510,14 +546,13 @@ impl PoolCommand {
}) })
} }
/// Update the contents of the clip pool /// Update the contents of the clip pool
fn clip (&self, pool: &mut MidiPool, command: PoolClipCommand) -> Perhaps<Self> { fn clip (pool: &mut MidiPool, command: PoolClipCommand) -> Perhaps<Self> {
command.execute(pool)?.map(|command|Self::Clip{command}) Ok(command.execute(pool)?.map(|command|Self::Clip{command}))
} }
} }
#[tengri_proc::command(MidiPool)] #[tengri_proc::command(MidiPool)] impl PoolClipCommand {
impl PoolClipCommand { fn add (pool: &mut MidiPool, index: usize, clip: MidiClip) -> Perhaps<Self> {
fn add (&self, pool: &mut MidiPool, index: usize, clip: MidiClip) -> Perhaps<Self> {
let mut index = index; let mut index = index;
let clip = Arc::new(RwLock::new(clip)); let clip = Arc::new(RwLock::new(clip));
let mut clips = pool.clips_mut(); let mut clips = pool.clips_mut();
@ -527,17 +562,17 @@ impl PoolClipCommand {
} else { } else {
clips.insert(index, clip); clips.insert(index, clip);
} }
Ok(Some(Self::Delete(index))) Ok(Some(Self::Delete { index }))
} }
fn delete (&self, pool: &mut MidiPool, index: usize) -> Perhaps<Self> { fn delete (pool: &mut MidiPool, index: usize) -> Perhaps<Self> {
let clip = pool.clips_mut().remove(index).read().unwrap().clone(); let clip = pool.clips_mut().remove(index).read().unwrap().clone();
Ok(Some(Self::Add(index, clip))) Ok(Some(Self::Add { index, clip }))
} }
fn swap (&self, pool: &mut MidiPool, index: usize, other: usize) -> Perhaps<Self> { fn swap (pool: &mut MidiPool, index: usize, other: usize) -> Perhaps<Self> {
pool.clips_mut().swap(index, other); pool.clips_mut().swap(index, other);
Ok(Some(Self::Swap(index, other))) Ok(Some(Self::Swap { index, other }))
} }
fn import (&self, pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps<Self> { fn import (pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps<Self> {
let bytes = std::fs::read(&path)?; let bytes = std::fs::read(&path)?;
let smf = Smf::parse(bytes.as_slice())?; let smf = Smf::parse(bytes.as_slice())?;
let mut t = 0u32; let mut t = 0u32;
@ -554,50 +589,49 @@ impl PoolClipCommand {
for event in events.iter() { for event in events.iter() {
clip.notes[event.0 as usize].push(event.2); clip.notes[event.0 as usize].push(event.2);
} }
Self::Add(index, clip).execute(pool)? Ok(Self::Add { index, clip }.execute(pool)?)
} }
fn export (&self, pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps<Self> { fn export (pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps<Self> {
todo!("export clip to midi file"); todo!("export clip to midi file");
} }
fn set_name (&self, pool: &mut MidiPool, index: usize, name: Arc<str>) -> Perhaps<Self> { fn set_name (pool: &mut MidiPool, index: usize, name: Arc<str>) -> Perhaps<Self> {
let clip = &mut pool.clips_mut()[index]; let clip = &mut pool.clips_mut()[index];
let old_name = clip.read().unwrap().name.clone(); let old_name = clip.read().unwrap().name.clone();
clip.write().unwrap().name = name; clip.write().unwrap().name = name;
Ok(Some(Self::SetName(index, old_name))) Ok(Some(Self::SetName { index, name: old_name }))
} }
fn set_length (&self, pool: &mut MidiPool, index: usize, length: usize) -> Perhaps<Self> { fn set_length (pool: &mut MidiPool, index: usize, length: usize) -> Perhaps<Self> {
let clip = &mut pool.clips_mut()[index]; let clip = &mut pool.clips_mut()[index];
let old_len = clip.read().unwrap().length; let old_len = clip.read().unwrap().length;
clip.write().unwrap().length = length; clip.write().unwrap().length = length;
Ok(Some(Self::SetLength(index, old_len))) Ok(Some(Self::SetLength { index, length: old_len }))
} }
fn set_color (&self, pool: &mut MidiPool, index: usize, color: ItemColor) -> Perhaps<Self> { fn set_color (pool: &mut MidiPool, index: usize, color: ItemColor) -> Perhaps<Self> {
let mut color = ItemTheme::from(color); let mut color = ItemTheme::from(color);
std::mem::swap(&mut color, &mut pool.clips()[index].write().unwrap().color); std::mem::swap(&mut color, &mut pool.clips()[index].write().unwrap().color);
Ok(Some(Self::SetColor(index, color.base))) Ok(Some(Self::SetColor { index, color: color.base }))
} }
} }
#[tengri_proc::command(MidiPool)] #[tengri_proc::command(MidiPool)] impl ClipRenameCommand {
impl ClipRenameCommand { fn begin (pool: &mut MidiPool) -> Perhaps<Self> {
fn begin (&self, pool: &mut MidiPool) -> Perhaps<Self> {
unreachable!(); unreachable!();
} }
fn cancel (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn cancel (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() { if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() {
pool.clips()[clip].write().unwrap().name = old_name.clone().into(); pool.clips()[clip].write().unwrap().name = old_name.clone().into();
} }
return Ok(None) return Ok(None)
} }
fn confirm (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn confirm (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() { if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() {
let old_name = old_name.clone(); let old_name = old_name.clone();
*pool.mode_mut() = None; *pool.mode_mut() = None;
return Ok(Some(Self::Set(old_name))) return Ok(Some(Self::Set { value: old_name }))
} }
return Ok(None) return Ok(None)
} }
fn set (&self, pool: &mut MidiPool, value: Arc<str>) -> Perhaps<Self> { fn set (pool: &mut MidiPool, value: Arc<str>) -> Perhaps<Self> {
if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() { if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() {
pool.clips()[clip].write().unwrap().name = value; pool.clips()[clip].write().unwrap().name = value;
} }
@ -605,18 +639,17 @@ impl ClipRenameCommand {
} }
} }
#[tengri_proc::command(MidiPool)] #[tengri_proc::command(MidiPool)] impl ClipLengthCommand {
impl ClipLengthCommand { fn begin (pool: &mut MidiPool) -> Perhaps<Self> {
fn begin (&self, pool: &mut MidiPool) -> Perhaps<Self> {
unreachable!() unreachable!()
} }
fn cancel (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn cancel (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some(PoolMode::Length(..)) = pool.mode_mut().clone() { if let Some(PoolMode::Length(..)) = pool.mode_mut().clone() {
*pool.mode_mut() = None; *pool.mode_mut() = None;
} }
Ok(None) Ok(None)
} }
fn set (&self, pool: &mut MidiPool, length: usize) -> Perhaps<Self> { fn set (pool: &mut MidiPool, length: usize) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone() = pool.mode_mut().clone()
{ {
@ -624,14 +657,14 @@ impl ClipLengthCommand {
{ {
let clip = pool.clips()[clip].clone();//.write().unwrap(); let clip = pool.clips()[clip].clone();//.write().unwrap();
old_length = Some(clip.read().unwrap().length); old_length = Some(clip.read().unwrap().length);
clip.write().unwrap().length = length; clip.write().unwrap().length = *length;
} }
*pool.mode_mut() = None; *pool.mode_mut() = None;
return Ok(old_length.map(Self::Set)) return Ok(old_length.map(|length|Self::Set { length }))
} }
Ok(None) Ok(None)
} }
fn next (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn next (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone() = pool.mode_mut().clone()
{ {
@ -639,7 +672,7 @@ impl ClipLengthCommand {
} }
Ok(None) Ok(None)
} }
fn prev (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn prev (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone() = pool.mode_mut().clone()
{ {
@ -647,102 +680,110 @@ impl ClipLengthCommand {
} }
Ok(None) Ok(None)
} }
fn inc (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn inc (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone() = pool.mode_mut().clone()
{ {
match focus { match focus {
Bar => { *length += 4 * PPQ }, ClipLengthFocus::Bar => { *length += 4 * PPQ },
Beat => { *length += PPQ }, ClipLengthFocus::Beat => { *length += PPQ },
Tick => { *length += 1 }, ClipLengthFocus::Tick => { *length += 1 },
} }
} }
Ok(None) Ok(None)
} }
fn dec (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn dec (pool: &mut MidiPool) -> Perhaps<Self> {
if let Some( if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
PoolMode::Length(clip, ref mut length, ref mut focus) = pool.mode_mut().clone()
) = pool.mode_mut().clone() { {
match focus { match focus {
Bar => { *length = length.saturating_sub(4 * PPQ) }, ClipLengthFocus::Bar => { *length = length.saturating_sub(4 * PPQ) },
Beat => { *length = length.saturating_sub(PPQ) }, ClipLengthFocus::Beat => { *length = length.saturating_sub(PPQ) },
Tick => { *length = length.saturating_sub(1) }, ClipLengthFocus::Tick => { *length = length.saturating_sub(1) },
} }
} }
Ok(None) Ok(None)
} }
} }
#[tengri_proc::command(MidiPool)] #[tengri_proc::command(MidiPool)] impl FileBrowserCommand {
impl FileBrowserCommand { fn begin (pool: &mut MidiPool) -> Perhaps<Self> {
fn begin (&self, pool: &mut MidiPool) -> Perhaps<Self> {
unreachable!(); unreachable!();
} }
fn cancel (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn cancel (pool: &mut MidiPool) -> Perhaps<Self> {
*pool.mode = None; pool.mode = None;
Ok(None) Ok(None)
} }
fn confirm (&self, pool: &mut MidiPool) -> Perhaps<Self> { fn confirm (pool: &mut MidiPool) -> Perhaps<Self> {
Ok(match pool.mode { Ok(match pool.mode {
Some(PoolMode::Import(index, ref mut browser)) => { Some(PoolMode::Import(index, ref mut browser)) => {
if browser.is_file() { if browser.is_file() {
let index = *index;
let path = browser.path(); let path = browser.path();
*pool.mode = None; pool.mode = None;
PoolClipCommand::Import(index, path).execute(pool)?; let _undo = PoolClipCommand::import(pool, index, path)?;
None
} else if browser.is_dir() { } else if browser.is_dir() {
*pool.mode = Some(PoolMode::Import(*index, browser.chdir()?)); pool.mode = Some(PoolMode::Import(index, browser.chdir()?));
None
} else {
None
} }
}, },
Some(PoolMode::Export(index, ref mut browser)) => match self { Some(PoolMode::Export(index, ref mut browser)) => {
Cancel => { *pool.mode = None; }, todo!()
_ => unreachable!()
}, },
_ => unreachable!(), _ => unreachable!(),
}) })
} }
fn select (&self, pool: &mut MidiPool, index: usize) -> Perhaps<Self> { fn select (pool: &mut MidiPool, index: usize) -> Perhaps<Self> {
Ok(match pool.mode {
Some(PoolMode::Import(index, ref mut browser)) => { browser.index = index; },
Some(PoolMode::Export(index, ref mut browser)) => { browser.index = index; },
_ => unreachable!(),
})
}
fn chdir (&self, pool: &mut MidiPool, dir: PathBuf) -> Perhaps<Self> {
Ok(match pool.mode { Ok(match pool.mode {
Some(PoolMode::Import(index, ref mut browser)) => { Some(PoolMode::Import(index, ref mut browser)) => {
*pool.mode = Some(PoolMode::Import(*index, FileBrowser::new(Some(dir))?)); browser.index = index;
None
}, },
Some(PoolMode::Export(index, ref mut browser)) => { Some(PoolMode::Export(index, ref mut browser)) => {
*pool.mode = Some(PoolMode::Export(*index, FileBrowser::new(Some(dir))?)); browser.index = index;
None
}, },
_ => unreachable!(), _ => unreachable!(),
}) })
} }
fn filter (&self, pool: &mut MidiPool, filter: Arc<str>) -> Perhaps<Self> { fn chdir (pool: &mut MidiPool, dir: PathBuf) -> Perhaps<Self> {
Ok(match pool.mode {
Some(PoolMode::Import(index, ref mut browser)) => {
pool.mode = Some(PoolMode::Import(index, FileBrowser::new(Some(dir))?));
None
},
Some(PoolMode::Export(index, ref mut browser)) => {
pool.mode = Some(PoolMode::Export(index, FileBrowser::new(Some(dir))?));
None
},
_ => unreachable!(),
})
}
fn filter (pool: &mut MidiPool, filter: Arc<str>) -> Perhaps<Self> {
todo!() todo!()
} }
} }
#[tengri_proc::command(MidiEditor)] #[tengri_proc::command(MidiEditor)] impl MidiEditCommand {
impl MidiEditCommand {
// TODO: 1-9 seek markers that by default start every 8th of the clip // TODO: 1-9 seek markers that by default start every 8th of the clip
fn note_append (&self, editor: &mut MidiEditor) -> Perhaps<Self> { fn note_append (editor: &mut MidiEditor) -> Perhaps<Self> {
editor.put_note(true); editor.put_note(true);
Ok(None) Ok(None)
} }
fn note_put (&self, editor: &mut MidiEditor) -> Perhaps<Self> { fn note_put (editor: &mut MidiEditor) -> Perhaps<Self> {
editor.put_note(false); editor.put_note(false);
Ok(None) Ok(None)
} }
fn note_del (&self, editor: &mut MidiEditor) -> Perhaps<Self> { fn note_del (editor: &mut MidiEditor) -> Perhaps<Self> {
todo!() todo!()
} }
fn note_pos (&self, editor: &mut MidiEditor, pos: usize) -> Perhaps<Self> { fn note_pos (editor: &mut MidiEditor, pos: usize) -> Perhaps<Self> {
editor.set_note_pos(pos.min(127)); editor.set_note_pos(pos.min(127));
Ok(None) Ok(None)
} }
fn note_len (&self, editor: &mut MidiEditor, value: usize) -> Perhaps<Self> { fn note_len (editor: &mut MidiEditor, value: usize) -> Perhaps<Self> {
//let note_len = editor.get_note_len(); //let note_len = editor.get_note_len();
//let time_zoom = editor.get_time_zoom(); //let time_zoom = editor.get_time_zoom();
editor.set_note_len(value); editor.set_note_len(value);
@ -751,28 +792,28 @@ impl MidiEditCommand {
//} //}
Ok(None) Ok(None)
} }
fn note_scroll (&self, editor: &mut MidiEditor, value: usize) { fn note_scroll (editor: &mut MidiEditor, value: usize) -> Perhaps<Self> {
editor.set_note_lo(value.min(127)); editor.set_note_lo(value.min(127));
Ok(None) Ok(None)
} }
fn time_pos (&self, editor: &mut MidiEditor, value: usize) -> Perhaps<Self> { fn time_pos (editor: &mut MidiEditor, value: usize) -> Perhaps<Self> {
editor.set_time_pos(value); editor.set_time_pos(value);
Ok(None) Ok(None)
} }
fn time_scroll (&self, editor: &mut MidiEditor, value: usize) -> Perhaps<Self> { fn time_scroll (editor: &mut MidiEditor, value: usize) -> Perhaps<Self> {
editor.set_time_start(value); editor.set_time_start(value);
Ok(None) Ok(None)
} }
fn time_zoom (&self, editor: &mut MidiEditor, value: usize) -> Perhaps<Self> { fn time_zoom (editor: &mut MidiEditor, value: usize) -> Perhaps<Self> {
editor.time_zoom().set(value); editor.set_time_zoom(value);
editor.redraw(); editor.redraw();
Ok(None) Ok(None)
} }
fn time_lock (&self, editor: &mut MidiEditor, value: bool) -> Perhaps<Self> { fn time_lock (editor: &mut MidiEditor, value: bool) -> Perhaps<Self> {
editor.set_time_lock(value); editor.set_time_lock(value);
Ok(None) Ok(None)
} }
fn show (&self, editor: &mut MidiEditor, clip: Option<Arc<RwLock<MidiClip>>>) -> Perhaps<Self> { fn show (editor: &mut MidiEditor, clip: Option<Arc<RwLock<MidiClip>>>) -> Perhaps<Self> {
editor.set_clip(clip.as_ref()); editor.set_clip(clip.as_ref());
Ok(None) Ok(None)
} }

View file

@ -53,9 +53,9 @@ impl MidiEditor {
let mut redraw = false; let mut redraw = false;
if let Some(clip) = self.clip() { if let Some(clip) = self.clip() {
let mut clip = clip.write().unwrap(); let mut clip = clip.write().unwrap();
let note_start = self.time_pos(); let note_start = self.get_time_pos();
let note_pos = self.note_pos(); let note_pos = self.get_note_pos();
let note_len = self.note_len(); let note_len = self.get_note_len();
let note_end = note_start + (note_len.saturating_sub(1)); let note_end = note_start + (note_len.saturating_sub(1));
let key: u7 = u7::from(note_pos as u8); let key: u7 = u7::from(note_pos as u8);
let vel: u7 = 100.into(); let vel: u7 = 100.into();

View file

@ -1195,8 +1195,8 @@ impl MidiViewer for PianoHorizontal {
let clip = clip.read().unwrap(); let clip = clip.read().unwrap();
let buf_size = self.buffer_size(&clip); let buf_size = self.buffer_size(&clip);
let mut buffer = BigBuffer::from(buf_size); let mut buffer = BigBuffer::from(buf_size);
let note_len = self.note_len(); let note_len = self.get_note_len();
let time_zoom = self.time_zoom().get(); let time_zoom = self.get_time_zoom();
self.time_len().set(clip.length); self.time_len().set(clip.length);
PianoHorizontal::draw_bg(&mut buffer, &clip, time_zoom, note_len); PianoHorizontal::draw_bg(&mut buffer, &clip, time_zoom, note_len);
PianoHorizontal::draw_fg(&mut buffer, &clip, time_zoom); PianoHorizontal::draw_fg(&mut buffer, &clip, time_zoom);

View file

@ -1,8 +1,17 @@
use crate::*; use crate::*;
provide_num!(u32: |self: Clock| {}); #[tengri_proc::expose]
provide!(Option<u32>: |self: Clock| {}); impl Clock {
provide!(f64: |self: Clock| {}); fn _todo_provide_u32 (&self) -> u32 {
todo!()
}
fn _todo_provide_opt_u32 (&self) -> Option<u32> {
todo!()
}
fn _todo_provide_f64 (&self) -> f64 {
todo!()
}
}
impl<T: HasClock> Command<T> for ClockCommand { impl<T: HasClock> Command<T> for ClockCommand {
fn execute (self, state: &mut T) -> Perhaps<Self> { fn execute (self, state: &mut T) -> Perhaps<Self> {
@ -12,15 +21,15 @@ impl<T: HasClock> Command<T> for ClockCommand {
#[tengri_proc::command(Clock)] #[tengri_proc::command(Clock)]
impl ClockCommand { impl ClockCommand {
fn play (self, state: &mut Clock, position: Option<u32>) -> Perhaps<Self> { fn play (state: &mut Clock, position: Option<u32>) -> Perhaps<Self> {
state.play_from(position)?; state.play_from(position)?;
Ok(None) // TODO Some(Pause(previousPosition)) Ok(None) // TODO Some(Pause(previousPosition))
} }
fn pause (self, state: &mut Clock, position: Option<u32>) -> Perhaps<Self> { fn pause (state: &mut Clock, position: Option<u32>) -> Perhaps<Self> {
state.pause_at(position)?; state.pause_at(position)?;
Ok(None) Ok(None)
} }
fn toggle_playback (self, state: &mut Clock, position: Option<u32>) -> Perhaps<Self> { fn toggle_playback (state: &mut Clock, position: Option<u32>) -> Perhaps<Self> {
if state.is_rolling() { if state.is_rolling() {
state.pause_at(position)?; state.pause_at(position)?;
} else { } else {
@ -28,25 +37,25 @@ impl ClockCommand {
} }
Ok(None) Ok(None)
} }
fn seek_usec (self, state: &mut Clock, usec: f64) -> Perhaps<Self> { fn seek_usec (state: &mut Clock, usec: f64) -> Perhaps<Self> {
state.playhead.update_from_usec(usec); state.playhead.update_from_usec(usec);
Ok(None) Ok(None)
} }
fn seek_sample (self, state: &mut Clock, sample: f64) -> Perhaps<Self> { fn seek_sample (state: &mut Clock, sample: f64) -> Perhaps<Self> {
state.playhead.update_from_sample(sample); state.playhead.update_from_sample(sample);
Ok(None) Ok(None)
} }
fn seek_pulse (self, state: &mut Clock, pulse: f64) -> Perhaps<Self> { fn seek_pulse (state: &mut Clock, pulse: f64) -> Perhaps<Self> {
state.playhead.update_from_pulse(pulse); state.playhead.update_from_pulse(pulse);
Ok(None) Ok(None)
} }
fn set_bpm (self, state: &mut Clock, bpm: f64) -> Perhaps<Self> { fn set_bpm (state: &mut Clock, bpm: f64) -> Perhaps<Self> {
Ok(Some(Self::SetBpm { bpm: state.timebase().bpm.set(bpm) })) Ok(Some(Self::SetBpm { bpm: state.timebase().bpm.set(bpm) }))
} }
fn set_quant (self, state: &mut Clock, quant: f64) -> Perhaps<Self> { fn set_quant (state: &mut Clock, quant: f64) -> Perhaps<Self> {
Ok(Some(Self::SetQuant { quant: state.quant.set(quant) })) Ok(Some(Self::SetQuant { quant: state.quant.set(quant) }))
} }
fn set_sync (self, state: &mut Clock, sync: f64) -> Perhaps<Self> { fn set_sync (state: &mut Clock, sync: f64) -> Perhaps<Self> {
Ok(Some(Self::SetSync { sync: state.sync.set(sync) })) Ok(Some(Self::SetSync { sync: state.sync.set(sync) }))
} }
} }

View file

@ -37,14 +37,23 @@ pub trait TimeRange {
fn get_time_zoom (&self) -> usize { fn get_time_zoom (&self) -> usize {
self.time_zoom().load(Ordering::Relaxed) self.time_zoom().load(Ordering::Relaxed)
} }
fn set_time_zoom (&self, value: usize) -> usize {
self.time_zoom().swap(value, Ordering::Relaxed)
}
fn time_lock (&self) -> &AtomicBool; fn time_lock (&self) -> &AtomicBool;
fn get_time_lock (&self) -> bool { fn get_time_lock (&self) -> bool {
self.time_lock().load(Ordering::Relaxed) self.time_lock().load(Ordering::Relaxed)
} }
fn set_time_lock (&self, value: bool) -> bool {
self.time_lock().swap(value, Ordering::Relaxed)
}
fn time_start (&self) -> &AtomicUsize; fn time_start (&self) -> &AtomicUsize;
fn get_time_start (&self) -> usize { fn get_time_start (&self) -> usize {
self.time_start().load(Ordering::Relaxed) self.time_start().load(Ordering::Relaxed)
} }
fn set_time_start (&self, value: usize) -> usize {
self.time_start().swap(value, Ordering::Relaxed)
}
fn time_axis (&self) -> &AtomicUsize; fn time_axis (&self) -> &AtomicUsize;
fn get_time_axis (&self) -> usize { fn get_time_axis (&self) -> usize {
self.time_axis().load(Ordering::Relaxed) self.time_axis().load(Ordering::Relaxed)

2
deps/tengri vendored

@ -1 +1 @@
Subproject commit e3bfae889792e70fa88a02fcad90e531f41059ec Subproject commit b7bb6119aac975632969719c7ec5b71d97dbe356