diff --git a/.old/demo.rs.old b/.old/demo.rs.old deleted file mode 100644 index 6b205580..00000000 --- a/.old/demo.rs.old +++ /dev/null @@ -1,112 +0,0 @@ -use tek::*; - -fn main () -> Usually<()> { - Tui::run(Arc::new(RwLock::new(Demo::new())))?; - Ok(()) -} - -pub struct Demo { - index: usize, - items: Vec>> -} - -impl Demo { - fn new () -> Self { - Self { - index: 0, - items: vec![] - } - } -} - -impl Content for Demo { - type Engine = Tui; - fn content (&self) -> dyn Render { - 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 for Demo { - fn handle (&mut self, from: &TuiIn) -> Perhaps { - 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)) - } -} diff --git a/crates/app/src/api.rs b/crates/app/src/api.rs index aa33ef34..61beb763 100644 --- a/crates/app/src/api.rs +++ b/crates/app/src/api.rs @@ -17,7 +17,8 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm None })); -#[tengri_proc::expose] impl Tek { +#[tengri_proc::expose] +impl Tek { fn focus_editor (&self) -> bool { self.is_editing() } @@ -160,7 +161,8 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } } -#[tengri_proc::expose] impl MidiPool { +#[tengri_proc::expose] +impl MidiPool { fn clip_new (&self) -> MidiClip { self.new_clip() } @@ -184,7 +186,8 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } } -#[tengri_proc::expose] impl MidiEditor { +#[tengri_proc::expose] +impl MidiEditor { fn time_lock (&self) -> bool { self.get_time_lock() } @@ -253,26 +256,27 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } } -#[tengri_proc::command(Tek)] impl TekCommand { - fn toggle_help (tek: &mut Tek, value: bool) -> Perhaps { +#[tengri_proc::command(Tek)] +impl TekCommand { + fn toggle_help (&self, tek: &mut Tek, value: bool) -> Perhaps { tek.toggle_dialog(Some(Dialog::Help)); Ok(None) } - fn toggle_menu (tek: &mut Tek, value: bool) -> Perhaps { + fn toggle_menu (&self, tek: &mut Tek, value: bool) -> Perhaps { tek.toggle_dialog(Some(Dialog::Menu)); Ok(None) } - fn toggle_edit (tek: &mut Tek, value: bool) -> Perhaps { + fn toggle_edit (&self, tek: &mut Tek, value: bool) -> Perhaps { tek.toggle_editor(Some(value)); Ok(None) } - fn editor (tek: &mut Tek, command: MidiEditCommand) -> Perhaps { + fn editor (&self, tek: &mut Tek, command: MidiEditCommand) -> Perhaps { Ok(tek.editor.as_mut().map(|editor|command.execute(editor)) .transpose()? .flatten() .map(|undo|Self::Editor { command: undo })) } - fn pool (tek: &mut Tek, command: PoolCommand) -> Perhaps { + fn pool (&self, tek: &mut Tek, command: PoolCommand) -> Perhaps { Ok(if let Some(pool) = tek.pool.as_mut() { let undo = command.clone().delegate(pool, |command|TekCommand::Pool{command})?; // update linked editor after pool action @@ -289,53 +293,53 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm None }) } - fn sampler (tek: &mut Tek, command: SamplerCommand) -> Perhaps { + fn sampler (&self, tek: &mut Tek, command: SamplerCommand) -> Perhaps { Ok(tek.sampler_mut() .map(|s|command.delegate(s, |command|Self::Sampler{command})) .transpose()? .flatten()) } - fn scene (tek: &mut Tek, command: SceneCommand) -> Perhaps { + fn scene (&self, tek: &mut Tek, command: SceneCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Scene{command})?) } - fn track (tek: &mut Tek, command: TrackCommand) -> Perhaps { + fn track (&self, tek: &mut Tek, command: TrackCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Track{command})?) } - fn input (tek: &mut Tek, command: InputCommand) -> Perhaps { + fn input (&self, tek: &mut Tek, command: InputCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Input{command})?) } - fn output (tek: &mut Tek, command: OutputCommand) -> Perhaps { + fn output (&self, tek: &mut Tek, command: OutputCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Output{command})?) } - fn clip (tek: &mut Tek, command: ClipCommand) -> Perhaps { + fn clip (&self, tek: &mut Tek, command: ClipCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Clip{command})?) } - fn clock (tek: &mut Tek, command: ClockCommand) -> Perhaps { - Ok(command.execute(&mut tek.clock)?.map(|command|Self::Clock{command})) + fn clock (&self, tek: &mut Tek, command: ClockCommand) -> Perhaps { + Ok(command.delegate(tek, |command|Self::Clock{command})?) } - fn device (tek: &mut Tek, command: DeviceCommand) -> Perhaps { + fn device (&self, tek: &mut Tek, command: DeviceCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Device{command})?) } - fn message (tek: &mut Tek, command: MessageCommand) -> Perhaps { + fn message (&self, tek: &mut Tek, command: MessageCommand) -> Perhaps { Ok(command.delegate(tek, |command|Self::Message{command})?) } - fn color (tek: &mut Tek, theme: ItemTheme) -> Perhaps { + fn color (&self, tek: &mut Tek, theme: ItemTheme) -> Perhaps { Ok(tek.set_color(Some(theme)).map(|theme|Self::Color{theme})) } - fn enqueue (tek: &mut Tek, clip: Option>>) -> Perhaps { + fn enqueue (&self, tek: &mut Tek, clip: Option>>) -> Perhaps { todo!() } - fn history (tek: &mut Tek, delta: isize) -> Perhaps { + fn history (&self, tek: &mut Tek, delta: isize) -> Perhaps { todo!() } - fn zoom (tek: &mut Tek, zoom: usize) -> Perhaps { + fn zoom (&self, tek: &mut Tek, zoom: usize) -> Perhaps { todo!() } - fn launch (tek: &mut Tek) -> Perhaps { + fn launch (&self, tek: &mut Tek) -> Perhaps { tek.launch(); Ok(None) } - fn select (tek: &mut Tek, selection: Selection) -> Perhaps { + fn select (&self, tek: &mut Tek, selection: Selection) -> Perhaps { tek.select(selection); Ok(None) //("select" [t: usize, s: usize] Some(match (t.expect("no track"), s.expect("no scene")) { @@ -344,169 +348,129 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm //(0, s) => Self::Select(Selection::Scene(s)), //(t, s) => Self::Select(Selection::TrackClip { track: t, scene: s }) }))) } - fn stop_all (tek: &mut Tek) -> Perhaps { + fn stop_all (&self, tek: &mut Tek) -> Perhaps { tek.stop_all(); Ok(None) } } -#[tengri_proc::command(Tek)] impl InputCommand { - fn add (tek: &mut Tek) -> Perhaps { +#[tengri_proc::command(Tek)] +impl InputCommand { + fn add (&self, tek: &mut Tek) -> Perhaps { tek.midi_in_add()?; Ok(None) } } -#[tengri_proc::command(Tek)] impl OutputCommand { - fn add (tek: &mut Tek) -> Perhaps { +#[tengri_proc::command(Tek)] +impl OutputCommand { + fn add (&self, tek: &mut Tek) -> Perhaps { tek.midi_out_add()?; Ok(None) } } -#[tengri_proc::command(Tek)] impl DeviceCommand { - fn picker (tek: &mut Tek) -> Perhaps { +#[tengri_proc::command(Tek)] +impl DeviceCommand { + fn picker (&self, tek: &mut Tek) -> Perhaps { tek.device_picker_show(); Ok(None) } - fn pick (tek: &mut Tek, i: usize) -> Perhaps { + fn pick (&self, tek: &mut Tek, i: usize) -> Perhaps { tek.device_pick(i); Ok(None) } - fn add (tek: &mut Tek, i: usize) -> Perhaps { + fn add (&self, tek: &mut Tek, i: usize) -> Perhaps { tek.device_add(i); Ok(None) } } -#[tengri_proc::command(Tek)] impl MessageCommand { - fn dismiss (tek: &mut Tek) -> Perhaps { +#[tengri_proc::command(Tek)] +impl MessageCommand { + fn dismiss (&self, tek: &mut Tek) -> Perhaps { tek.message_dismiss(); Ok(None) } } -#[tengri_proc::command(Tek)] impl TrackCommand { - fn toggle_play (tek: &mut Tek) -> Perhaps { - todo!() - } - fn toggle_solo (tek: &mut Tek) -> Perhaps { - todo!() - } - fn toggle_rec (tek: &mut Tek) -> Perhaps { - tek.track_toggle_record(); - Ok(Some(Self::ToggleRec)) - } - fn toggle_mon (tek: &mut Tek) -> Perhaps { - tek.track_toggle_monitor(); - Ok(Some(Self::ToggleMon)) - } - fn set_size (tek: &mut Tek, size: usize) -> Perhaps { - todo!() - } - fn set_zoom (tek: &mut Tek, zoom: usize) -> Perhaps { - todo!() - } - fn swap (tek: &mut Tek, index: usize, other: usize) -> Perhaps { - todo!(); - Ok(Some(Self::Swap { index, other })) - } - fn del (tek: &mut Tek, index: usize) -> Perhaps { - tek.track_del(index); - Ok(None) - } - fn stop (tek: &mut Tek, index: usize) -> Perhaps { - tek.tracks[index].player.enqueue_next(None); - Ok(None) - } - fn add (tek: &mut Tek) -> Perhaps { - Ok(Some(Self::Del { index: tek.track_add_focus()? })) - } - fn set_color (tek: &mut Tek, index: usize, color: ItemTheme) -> Perhaps { - Ok(Some(Self::SetColor { index, color: tek.track_set_color(index, color) })) - } +#[tengri_proc::command(Tek)] +impl TrackCommand { + //(TogglePlay [] Some(Self::TogglePlay)) + //(ToggleSolo [] Some(Self::ToggleSolo)) + //(SetSize [t: usize] cmd_todo!("\n\rtodo: {self:?}")) + //(SetZoom [z: usize] cmd_todo!("\n\rtodo: {self:?}")) + //(Swap [a: usize, b: usize] cmd_todo!("\n\rtodo: {self:?}")) + //(Del [index: usize] cmd!(app.track_del(index))) + //(Stop [index: usize] cmd!(app.tracks[index].player.enqueue_next(None))) + //(Add [] Some(Self::Del(app.track_add_focus()?))) + //(SetColor [i: usize, c: ItemTheme] Some(Self::SetColor(i, app.track_set_color(i, c)))) + //(ToggleRec [] { app.track_toggle_record(); Some(Self::ToggleRec) }) + //(ToggleMon [] { app.track_toggle_monitor(); Some(Self::ToggleMon) })) + //("add" [] Some(Self::Add)) + //("size" [a: usize] Some(Self::SetSize(a.unwrap()))) + //("zoom" [a: usize] Some(Self::SetZoom(a.unwrap()))) + //("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::random()))) + //("delete" [a: Option] Some(Self::Del(a.flatten().unwrap()))) + //("stop" [a: usize] Some(Self::Stop(a.unwrap()))) + //("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap()))) + //("play" [] Some(Self::TogglePlay)) + //("solo" [] Some(Self::ToggleSolo)) + //("rec" [] Some(Self::ToggleRec)) + //("mon" [] Some(Self::ToggleMon)))); } -#[tengri_proc::command(Tek)] impl SceneCommand { - fn add (tek: &mut Tek) -> Perhaps { - todo!() - } - fn del (tek: &mut Tek, index: usize) -> Perhaps { - tek.scene_del(index); - Ok(None) - } - fn enqueue (tek: &mut Tek, index: usize) -> Perhaps { - tek.scene_enqueue(index); - Ok(None) - } - fn set_color (tek: &mut Tek, index: usize, color: ItemTheme) -> Perhaps { - Ok(Some(Self::SetColor { index, color: tek.scene_set_color(index, color) })) - } - fn set_size (tek: &mut Tek, index: usize, size: usize) -> Perhaps { - todo!() - } - fn set_zoom (tek: &mut Tek, index: usize, zoom: usize) -> Perhaps { - todo!() - } - fn swap (tek: &mut Tek, index: usize, other: usize) -> Perhaps { - todo!(); - Ok(Some(Self::Swap { index, other })) - } +#[tengri_proc::command(Tek)] +impl SceneCommand { + //(Swap [a: usize, b: usize] cmd_todo!("\n\rtodo: {self:?}")) + //(SetSize [index: usize] cmd_todo!("\n\rtodo: {self:?}")) + //(SetZoom [zoom: usize] cmd_todo!("\n\rtodo: {self:?}")) + //(Enqueue [scene: usize] cmd!(app.scene_enqueue(scene))) + //(Del [index: usize] cmd!(app.scene_del(index))) + //(Add [] Some(Self::Del(app.scene_add_focus()?))) + //(SetColor [i: usize, c: ItemTheme] Some(Self::SetColor(i, app.scene_set_color(i, c))))) + //("add" [] Some(Self::Add)) + //("delete" [a: Option] Some(Self::Del(a.flatten().unwrap()))) + //("zoom" [a: usize] Some(Self::SetZoom(a.unwrap()))) + //("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemTheme::G[128]))) + //("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap()))) + //("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))) } -#[tengri_proc::command(Tek)] impl ClipCommand { - fn get (tek: &mut Tek, a: usize, b: usize) -> Perhaps { - //(Get [a: usize, b: usize] cmd_todo!("\n\rtodo: clip: get: {a} {b}")) - //("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap()))) - todo!() - } - fn edit (tek: &mut Tek, a: usize, b: usize) -> Perhaps { - //(Edit [clip: MaybeClip] cmd_todo!("\n\rtodo: clip: edit: {clip:?}")) - //("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap()))) - todo!() - } - fn set_loop (tek: &mut Tek, a: usize, b: usize) -> Perhaps { - //(SetLoop [t: usize, s: usize, l: bool] cmd_todo!("\n\rtodo: {self:?}")) - //("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap()))) - todo!() - } - fn put (tek: &mut Tek, a: usize, b: usize) -> Perhaps { - //(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 { +#[tengri_proc::command(Tek)] +impl ClipCommand { + //(Get [a: usize, b: usize] cmd_todo!("\n\rtodo: clip: get: {a} {b}")) + //(Edit [clip: MaybeClip] cmd_todo!("\n\rtodo: clip: edit: {clip:?}")) + //(SetLoop [t: usize, s: usize, l: bool] cmd_todo!("\n\rtodo: {self:?}")) + //(Put [t: usize, s: usize, c: MaybeClip] + //Some(Self::Put(t, s, app.clip_put(t, s, c)))) + //(Enqueue [t: usize, s: usize] + //cmd!(app.tracks[t].player.enqueue_next(app.scenes[s].clips[t].as_ref()))) + //(SetColor [t: usize, s: usize, c: ItemTheme] + //app.clip_set_color(t, s, c).map(|o|Self::SetColor(t, s, o))))); + //("edit" [a: MaybeClip] Some(Self::Edit(a.unwrap()))) + //("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemTheme::random()))) + //("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap()))) + //("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap()))) + //("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()))) //("delete" [a: usize, b: usize] Some(Self::Put(a.unwrap(), b.unwrap(), None)))) - todo!() - } - fn enqueue (tek: &mut Tek, a: usize, b: usize) -> Perhaps { - //(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 { - //(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)] impl PoolCommand { +#[tengri_proc::command(MidiPool)] +impl PoolCommand { /// Toggle visibility of pool - fn show (pool: &mut MidiPool, visible: bool) -> Perhaps { + fn show (&self, pool: &mut MidiPool, visible: bool) -> Perhaps { pool.visible = visible; - Ok(Some(Self::Show { visible: !visible })) + Ok(Some(Self::Show(!visible))) } /// Select a clip from the clip pool - fn select (pool: &mut MidiPool, index: usize) -> Perhaps { + fn select (&self, pool: &mut MidiPool, index: usize) -> Perhaps { pool.set_clip_index(index); Ok(None) } /// Rename a clip - fn rename (pool: &mut MidiPool, command: ClipRenameCommand) -> Perhaps { + fn rename (&self, pool: &mut MidiPool, command: ClipRenameCommand) -> Perhaps { Ok(match command { ClipRenameCommand::Begin => { pool.begin_clip_rename(); @@ -516,7 +480,7 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm }) } /// Change the length of a clip - fn length (pool: &mut MidiPool, command: ClipLengthCommand) -> Perhaps { + fn length (&self, pool: &mut MidiPool, command: ClipLengthCommand) -> Perhaps { Ok(match command { ClipLengthCommand::Begin => { pool.begin_clip_length(); @@ -526,9 +490,9 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm }) } /// Import from file - fn import (pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps { + fn import (&self, pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps { Ok(match command { - FileBrowserCommand::Begin => { + ClipImportCommand::Begin => { pool.begin_import(); None }, @@ -536,9 +500,9 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm }) } /// Export to file - fn export (pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps { + fn export (&self, pool: &mut MidiPool, command: FileBrowserCommand) -> Perhaps { Ok(match command { - FileBrowserCommand::Begin => { + ClipExportCommand::Begin => { pool.begin_export(); None }, @@ -546,13 +510,14 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm }) } /// Update the contents of the clip pool - fn clip (pool: &mut MidiPool, command: PoolClipCommand) -> Perhaps { - Ok(command.execute(pool)?.map(|command|Self::Clip{command})) + fn clip (&self, pool: &mut MidiPool, command: PoolClipCommand) -> Perhaps { + command.execute(pool)?.map(|command|Self::Clip{command}) } } -#[tengri_proc::command(MidiPool)] impl PoolClipCommand { - fn add (pool: &mut MidiPool, index: usize, clip: MidiClip) -> Perhaps { +#[tengri_proc::command(MidiPool)] +impl PoolClipCommand { + fn add (&self, pool: &mut MidiPool, index: usize, clip: MidiClip) -> Perhaps { let mut index = index; let clip = Arc::new(RwLock::new(clip)); let mut clips = pool.clips_mut(); @@ -562,17 +527,17 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } else { clips.insert(index, clip); } - Ok(Some(Self::Delete { index })) + Ok(Some(Self::Delete(index))) } - fn delete (pool: &mut MidiPool, index: usize) -> Perhaps { + fn delete (&self, pool: &mut MidiPool, index: usize) -> Perhaps { let clip = pool.clips_mut().remove(index).read().unwrap().clone(); - Ok(Some(Self::Add { index, clip })) + Ok(Some(Self::Add(index, clip))) } - fn swap (pool: &mut MidiPool, index: usize, other: usize) -> Perhaps { + fn swap (&self, pool: &mut MidiPool, index: usize, other: usize) -> Perhaps { pool.clips_mut().swap(index, other); - Ok(Some(Self::Swap { index, other })) + Ok(Some(Self::Swap(index, other))) } - fn import (pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps { + fn import (&self, pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps { let bytes = std::fs::read(&path)?; let smf = Smf::parse(bytes.as_slice())?; let mut t = 0u32; @@ -589,49 +554,50 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm for event in events.iter() { clip.notes[event.0 as usize].push(event.2); } - Ok(Self::Add { index, clip }.execute(pool)?) + Self::Add(index, clip).execute(pool)? } - fn export (pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps { + fn export (&self, pool: &mut MidiPool, index: usize, path: PathBuf) -> Perhaps { todo!("export clip to midi file"); } - fn set_name (pool: &mut MidiPool, index: usize, name: Arc) -> Perhaps { + fn set_name (&self, pool: &mut MidiPool, index: usize, name: Arc) -> Perhaps { let clip = &mut pool.clips_mut()[index]; let old_name = clip.read().unwrap().name.clone(); clip.write().unwrap().name = name; - Ok(Some(Self::SetName { index, name: old_name })) + Ok(Some(Self::SetName(index, old_name))) } - fn set_length (pool: &mut MidiPool, index: usize, length: usize) -> Perhaps { + fn set_length (&self, pool: &mut MidiPool, index: usize, length: usize) -> Perhaps { let clip = &mut pool.clips_mut()[index]; let old_len = clip.read().unwrap().length; clip.write().unwrap().length = length; - Ok(Some(Self::SetLength { index, length: old_len })) + Ok(Some(Self::SetLength(index, old_len))) } - fn set_color (pool: &mut MidiPool, index: usize, color: ItemColor) -> Perhaps { + fn set_color (&self, pool: &mut MidiPool, index: usize, color: ItemColor) -> Perhaps { let mut color = ItemTheme::from(color); std::mem::swap(&mut color, &mut pool.clips()[index].write().unwrap().color); - Ok(Some(Self::SetColor { index, color: color.base })) + Ok(Some(Self::SetColor(index, color.base))) } } -#[tengri_proc::command(MidiPool)] impl ClipRenameCommand { - fn begin (pool: &mut MidiPool) -> Perhaps { +#[tengri_proc::command(MidiPool)] +impl ClipRenameCommand { + fn begin (&self, pool: &mut MidiPool) -> Perhaps { unreachable!(); } - fn cancel (pool: &mut MidiPool) -> Perhaps { + fn cancel (&self, pool: &mut MidiPool) -> Perhaps { if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() { pool.clips()[clip].write().unwrap().name = old_name.clone().into(); } return Ok(None) } - fn confirm (pool: &mut MidiPool) -> Perhaps { + fn confirm (&self, pool: &mut MidiPool) -> Perhaps { if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() { let old_name = old_name.clone(); *pool.mode_mut() = None; - return Ok(Some(Self::Set { value: old_name })) + return Ok(Some(Self::Set(old_name))) } return Ok(None) } - fn set (pool: &mut MidiPool, value: Arc) -> Perhaps { + fn set (&self, pool: &mut MidiPool, value: Arc) -> Perhaps { if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() { pool.clips()[clip].write().unwrap().name = value; } @@ -639,17 +605,18 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } } -#[tengri_proc::command(MidiPool)] impl ClipLengthCommand { - fn begin (pool: &mut MidiPool) -> Perhaps { +#[tengri_proc::command(MidiPool)] +impl ClipLengthCommand { + fn begin (&self, pool: &mut MidiPool) -> Perhaps { unreachable!() } - fn cancel (pool: &mut MidiPool) -> Perhaps { + fn cancel (&self, pool: &mut MidiPool) -> Perhaps { if let Some(PoolMode::Length(..)) = pool.mode_mut().clone() { *pool.mode_mut() = None; } Ok(None) } - fn set (pool: &mut MidiPool, length: usize) -> Perhaps { + fn set (&self, pool: &mut MidiPool, length: usize) -> Perhaps { if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) = pool.mode_mut().clone() { @@ -657,14 +624,14 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm { let clip = pool.clips()[clip].clone();//.write().unwrap(); old_length = Some(clip.read().unwrap().length); - clip.write().unwrap().length = *length; + clip.write().unwrap().length = length; } *pool.mode_mut() = None; - return Ok(old_length.map(|length|Self::Set { length })) + return Ok(old_length.map(Self::Set)) } Ok(None) } - fn next (pool: &mut MidiPool) -> Perhaps { + fn next (&self, pool: &mut MidiPool) -> Perhaps { if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) = pool.mode_mut().clone() { @@ -672,7 +639,7 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } Ok(None) } - fn prev (pool: &mut MidiPool) -> Perhaps { + fn prev (&self, pool: &mut MidiPool) -> Perhaps { if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) = pool.mode_mut().clone() { @@ -680,110 +647,102 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm } Ok(None) } - fn inc (pool: &mut MidiPool) -> Perhaps { + fn inc (&self, pool: &mut MidiPool) -> Perhaps { if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) = pool.mode_mut().clone() { match focus { - ClipLengthFocus::Bar => { *length += 4 * PPQ }, - ClipLengthFocus::Beat => { *length += PPQ }, - ClipLengthFocus::Tick => { *length += 1 }, + Bar => { *length += 4 * PPQ }, + Beat => { *length += PPQ }, + Tick => { *length += 1 }, } } Ok(None) } - fn dec (pool: &mut MidiPool) -> Perhaps { - if let Some(PoolMode::Length(clip, ref mut length, ref mut focus)) - = pool.mode_mut().clone() - { + fn dec (&self, pool: &mut MidiPool) -> Perhaps { + if let Some( + PoolMode::Length(clip, ref mut length, ref mut focus) + ) = pool.mode_mut().clone() { match focus { - ClipLengthFocus::Bar => { *length = length.saturating_sub(4 * PPQ) }, - ClipLengthFocus::Beat => { *length = length.saturating_sub(PPQ) }, - ClipLengthFocus::Tick => { *length = length.saturating_sub(1) }, + Bar => { *length = length.saturating_sub(4 * PPQ) }, + Beat => { *length = length.saturating_sub(PPQ) }, + Tick => { *length = length.saturating_sub(1) }, } } Ok(None) } } -#[tengri_proc::command(MidiPool)] impl FileBrowserCommand { - fn begin (pool: &mut MidiPool) -> Perhaps { +#[tengri_proc::command(MidiPool)] +impl FileBrowserCommand { + fn begin (&self, pool: &mut MidiPool) -> Perhaps { unreachable!(); } - fn cancel (pool: &mut MidiPool) -> Perhaps { - pool.mode = None; + fn cancel (&self, pool: &mut MidiPool) -> Perhaps { + *pool.mode = None; Ok(None) } - fn confirm (pool: &mut MidiPool) -> Perhaps { + fn confirm (&self, pool: &mut MidiPool) -> Perhaps { Ok(match pool.mode { Some(PoolMode::Import(index, ref mut browser)) => { if browser.is_file() { + let index = *index; let path = browser.path(); - pool.mode = None; - let _undo = PoolClipCommand::import(pool, index, path)?; - None + *pool.mode = None; + PoolClipCommand::Import(index, path).execute(pool)?; } else if browser.is_dir() { - pool.mode = Some(PoolMode::Import(index, browser.chdir()?)); - None - } else { - None + *pool.mode = Some(PoolMode::Import(*index, browser.chdir()?)); } }, - Some(PoolMode::Export(index, ref mut browser)) => { - todo!() + Some(PoolMode::Export(index, ref mut browser)) => match self { + Cancel => { *pool.mode = None; }, + _ => unreachable!() }, _ => unreachable!(), }) } - fn select (pool: &mut MidiPool, index: usize) -> Perhaps { + fn select (&self, pool: &mut MidiPool, index: usize) -> Perhaps { + 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 { Ok(match pool.mode { Some(PoolMode::Import(index, ref mut browser)) => { - browser.index = index; - None + *pool.mode = Some(PoolMode::Import(*index, FileBrowser::new(Some(dir))?)); }, Some(PoolMode::Export(index, ref mut browser)) => { - browser.index = index; - None + *pool.mode = Some(PoolMode::Export(*index, FileBrowser::new(Some(dir))?)); }, _ => unreachable!(), }) } - fn chdir (pool: &mut MidiPool, dir: PathBuf) -> Perhaps { - 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) -> Perhaps { + fn filter (&self, pool: &mut MidiPool, filter: Arc) -> Perhaps { todo!() } } -#[tengri_proc::command(MidiEditor)] impl MidiEditCommand { +#[tengri_proc::command(MidiEditor)] +impl MidiEditCommand { // TODO: 1-9 seek markers that by default start every 8th of the clip - fn note_append (editor: &mut MidiEditor) -> Perhaps { + fn note_append (&self, editor: &mut MidiEditor) -> Perhaps { editor.put_note(true); Ok(None) } - fn note_put (editor: &mut MidiEditor) -> Perhaps { + fn note_put (&self, editor: &mut MidiEditor) -> Perhaps { editor.put_note(false); Ok(None) } - fn note_del (editor: &mut MidiEditor) -> Perhaps { + fn note_del (&self, editor: &mut MidiEditor) -> Perhaps { todo!() } - fn note_pos (editor: &mut MidiEditor, pos: usize) -> Perhaps { + fn note_pos (&self, editor: &mut MidiEditor, pos: usize) -> Perhaps { editor.set_note_pos(pos.min(127)); Ok(None) } - fn note_len (editor: &mut MidiEditor, value: usize) -> Perhaps { + fn note_len (&self, editor: &mut MidiEditor, value: usize) -> Perhaps { //let note_len = editor.get_note_len(); //let time_zoom = editor.get_time_zoom(); editor.set_note_len(value); @@ -792,28 +751,28 @@ handle!(TuiIn: |self: Tek, input|Ok(if let Some(command) = self.config.keys.comm //} Ok(None) } - fn note_scroll (editor: &mut MidiEditor, value: usize) -> Perhaps { + fn note_scroll (&self, editor: &mut MidiEditor, value: usize) { editor.set_note_lo(value.min(127)); Ok(None) } - fn time_pos (editor: &mut MidiEditor, value: usize) -> Perhaps { + fn time_pos (&self, editor: &mut MidiEditor, value: usize) -> Perhaps { editor.set_time_pos(value); Ok(None) } - fn time_scroll (editor: &mut MidiEditor, value: usize) -> Perhaps { + fn time_scroll (&self, editor: &mut MidiEditor, value: usize) -> Perhaps { editor.set_time_start(value); Ok(None) } - fn time_zoom (editor: &mut MidiEditor, value: usize) -> Perhaps { - editor.set_time_zoom(value); + fn time_zoom (&self, editor: &mut MidiEditor, value: usize) -> Perhaps { + editor.time_zoom().set(value); editor.redraw(); Ok(None) } - fn time_lock (editor: &mut MidiEditor, value: bool) -> Perhaps { + fn time_lock (&self, editor: &mut MidiEditor, value: bool) -> Perhaps { editor.set_time_lock(value); Ok(None) } - fn show (editor: &mut MidiEditor, clip: Option>>) -> Perhaps { + fn show (&self, editor: &mut MidiEditor, clip: Option>>) -> Perhaps { editor.set_clip(clip.as_ref()); Ok(None) } diff --git a/crates/app/src/model/editor.rs b/crates/app/src/model/editor.rs index fec878b1..9a9d5836 100644 --- a/crates/app/src/model/editor.rs +++ b/crates/app/src/model/editor.rs @@ -53,9 +53,9 @@ impl MidiEditor { let mut redraw = false; if let Some(clip) = self.clip() { let mut clip = clip.write().unwrap(); - let note_start = self.get_time_pos(); - let note_pos = self.get_note_pos(); - let note_len = self.get_note_len(); + let note_start = self.time_pos(); + let note_pos = self.note_pos(); + let note_len = self.note_len(); let note_end = note_start + (note_len.saturating_sub(1)); let key: u7 = u7::from(note_pos as u8); let vel: u7 = 100.into(); diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index 2f1bfdd9..d1377bee 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -1195,8 +1195,8 @@ impl MidiViewer for PianoHorizontal { let clip = clip.read().unwrap(); let buf_size = self.buffer_size(&clip); let mut buffer = BigBuffer::from(buf_size); - let note_len = self.get_note_len(); - let time_zoom = self.get_time_zoom(); + let note_len = self.note_len(); + let time_zoom = self.time_zoom().get(); self.time_len().set(clip.length); PianoHorizontal::draw_bg(&mut buffer, &clip, time_zoom, note_len); PianoHorizontal::draw_fg(&mut buffer, &clip, time_zoom); diff --git a/crates/device/src/clock/clock_api.rs b/crates/device/src/clock/clock_api.rs index e9161ec4..097867fc 100644 --- a/crates/device/src/clock/clock_api.rs +++ b/crates/device/src/clock/clock_api.rs @@ -1,17 +1,8 @@ use crate::*; -#[tengri_proc::expose] -impl Clock { - fn _todo_provide_u32 (&self) -> u32 { - todo!() - } - fn _todo_provide_opt_u32 (&self) -> Option { - todo!() - } - fn _todo_provide_f64 (&self) -> f64 { - todo!() - } -} +provide_num!(u32: |self: Clock| {}); +provide!(Option: |self: Clock| {}); +provide!(f64: |self: Clock| {}); impl Command for ClockCommand { fn execute (self, state: &mut T) -> Perhaps { @@ -21,15 +12,15 @@ impl Command for ClockCommand { #[tengri_proc::command(Clock)] impl ClockCommand { - fn play (state: &mut Clock, position: Option) -> Perhaps { + fn play (self, state: &mut Clock, position: Option) -> Perhaps { state.play_from(position)?; Ok(None) // TODO Some(Pause(previousPosition)) } - fn pause (state: &mut Clock, position: Option) -> Perhaps { + fn pause (self, state: &mut Clock, position: Option) -> Perhaps { state.pause_at(position)?; Ok(None) } - fn toggle_playback (state: &mut Clock, position: Option) -> Perhaps { + fn toggle_playback (self, state: &mut Clock, position: Option) -> Perhaps { if state.is_rolling() { state.pause_at(position)?; } else { @@ -37,25 +28,25 @@ impl ClockCommand { } Ok(None) } - fn seek_usec (state: &mut Clock, usec: f64) -> Perhaps { + fn seek_usec (self, state: &mut Clock, usec: f64) -> Perhaps { state.playhead.update_from_usec(usec); Ok(None) } - fn seek_sample (state: &mut Clock, sample: f64) -> Perhaps { + fn seek_sample (self, state: &mut Clock, sample: f64) -> Perhaps { state.playhead.update_from_sample(sample); Ok(None) } - fn seek_pulse (state: &mut Clock, pulse: f64) -> Perhaps { + fn seek_pulse (self, state: &mut Clock, pulse: f64) -> Perhaps { state.playhead.update_from_pulse(pulse); Ok(None) } - fn set_bpm (state: &mut Clock, bpm: f64) -> Perhaps { + fn set_bpm (self, state: &mut Clock, bpm: f64) -> Perhaps { Ok(Some(Self::SetBpm { bpm: state.timebase().bpm.set(bpm) })) } - fn set_quant (state: &mut Clock, quant: f64) -> Perhaps { + fn set_quant (self, state: &mut Clock, quant: f64) -> Perhaps { Ok(Some(Self::SetQuant { quant: state.quant.set(quant) })) } - fn set_sync (state: &mut Clock, sync: f64) -> Perhaps { + fn set_sync (self, state: &mut Clock, sync: f64) -> Perhaps { Ok(Some(Self::SetSync { sync: state.sync.set(sync) })) } } diff --git a/crates/engine/src/note/note_range.rs b/crates/engine/src/note/note_range.rs index 40e7acc0..6804bd7a 100644 --- a/crates/engine/src/note/note_range.rs +++ b/crates/engine/src/note/note_range.rs @@ -37,23 +37,14 @@ pub trait TimeRange { fn get_time_zoom (&self) -> usize { 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 get_time_lock (&self) -> bool { 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 get_time_start (&self) -> usize { 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 get_time_axis (&self) -> usize { self.time_axis().load(Ordering::Relaxed) diff --git a/deps/tengri b/deps/tengri index b7bb6119..e3bfae88 160000 --- a/deps/tengri +++ b/deps/tengri @@ -1 +1 @@ -Subproject commit b7bb6119aac975632969719c7ec5b71d97dbe356 +Subproject commit e3bfae889792e70fa88a02fcad90e531f41059ec