stack modes

This commit is contained in:
i do not exist 2026-09-23 13:21:51 +03:00
parent 9e3cc1139d
commit f321397d6f
11 changed files with 570 additions and 498 deletions

View file

@ -23,13 +23,23 @@ impl_from!(AppCmd: |x: TracksCmd| AppCmd::Tracks { command: x });
}
/// Enter a contextual mode.
#[command(Enter = "enter")] pub fn cmd_mode_enter (&mut self, mode: Arc<str>) -> Perhaps<AppCmd> {
self.modes_mut().push(mode);
Ok(Some(AppCmd::Leave))
let mut modes = self.modes_mut();
Ok(if modes.last() != Some(&mode) {
modes.push(mode);
Some(AppCmd::Leave)
} else {
None
})
}
/// Leave a contextual mode.
#[command(Leave = "leave")] fn cmd_mode_leave (&mut self) -> Perhaps<AppCmd> {
let mode = self.modes_mut().pop();
Ok(mode.map(|mode|AppCmd::Enter { mode }))
let mut modes = self.modes_mut();
if modes.len() > 1 {
let mode = modes.pop();
Ok(mode.map(|mode|AppCmd::Enter { mode }))
} else {
Ok(None)
}
}
/// Navigate along a contextual axis.
#[command(Axis = "axis")] pub fn cmd_axis (&mut self, command: AxisCmd) -> Perhaps<AppCmd> {
@ -607,6 +617,87 @@ impl<T: HasClip + HasEditor
// TODO: 1-9 seek markers that by default start every 8th of the clip
}
impl<T> MidiClipControl for T where T: HasClip
+ Namespace<Option<bool>> + Namespace<Option<ItemTheme>> {}
#[tek_proc::commands(MidiClipCmd)] pub trait MidiClipControl: HasClip
+ Namespace<Option<bool>> + Namespace<Option<ItemTheme>>
{
/// Create a clip at the current position if it does not already exist.
#[command(Upsert = "upsert")] fn clip_upsert (
&mut self
) -> Perhaps<MidiClipCmd> {
Ok(self.clip_mut().map(|mut clip|if clip.is_none() {
*clip = Some(Default::default());
None // TODO undo
} else {
None
}).flatten())
}
#[command(SetColor = "color")] fn clip_set_color (
&mut self, color: Option<ItemTheme>
) -> Perhaps<MidiClipCmd> {
Ok(self.clip_slot().map_inner_mut(|clip|MidiClipCmd::SetColor {
color: Some(clip.set_color(color))
}))
}
/// Toggle looping for the active clip
#[command(SetLoop = "loop")] fn clip_toggle_loop (
&mut self, looping: Option<bool>
) -> Perhaps<MidiClipCmd> {
Ok(self.clip_slot().map_inner_mut(|clip|MidiClipCmd::SetLoop {
looping: Some(clip.toggle_loop(looping))
}))
}
}
impl<T> BrowseControl for T where T:
Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>> {}
#[tek_proc::commands(BrowseCmd = "browse")] pub trait BrowseControl:
Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>>
{
/// Toggle visibility of browser
#[command(Show = "show")] fn show (&mut self) -> Perhaps<BrowseCmd> {
todo!()
}
/// Set current directory
#[command(Chdir = "chdir")] fn chdir (&mut self, _path: PathBuf) -> Perhaps<BrowseCmd> {
todo!()
}
/// Set current filter
#[command(SetSearch = "set-search")] fn set_search (&mut self, _filter: Arc<str>) -> Perhaps<BrowseCmd> {
todo!()
}
/// Set selected item
#[command(SetCursor = "set-cursor")] fn set_cursor (&mut self, _index: usize) -> Perhaps<BrowseCmd> {
todo!()
}
}
#[tek_proc::commands(AxisCmd)] impl App {
/// Increment the given data axis.
#[command(Inc = "inc")] pub fn inc (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
Ok(match (&self.dialog, axis) {
(Dialog::None, _) => todo!(),
(Dialog::Menu(_, _), ControlAxis::Y) => {
AppCmd::Dialog { dialog: self.dialog.menu_next() }.dispatch(self)?;
None
},
_ => todo!()
})
}
/// Decrement the given data axis.
#[command(Dec = "dec")] pub fn dec (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
Ok(match (&self.dialog, axis) {
(Dialog::None, _) => None,
(Dialog::Menu(_, _), ControlAxis::Y) => {
AppCmd::Dialog { dialog: self.dialog.menu_prev() }.dispatch(self)?;
None
},
_ => todo!()
})
}
}
//impl<T: HasPool
//+ Namespace<bool>
//+ Namespace<usize>
@ -822,84 +913,3 @@ impl<T: HasClip + HasEditor
////})
////}
//}
impl<T> MidiClipControl for T where T: HasClip
+ Namespace<Option<bool>> + Namespace<Option<ItemTheme>> {}
#[tek_proc::commands(MidiClipCmd)] pub trait MidiClipControl: HasClip
+ Namespace<Option<bool>> + Namespace<Option<ItemTheme>>
{
/// Create a clip at the current position if it does not already exist.
#[command(Upsert = "upsert")] fn clip_upsert (
&mut self
) -> Perhaps<MidiClipCmd> {
Ok(self.clip_mut().map(|mut clip|if clip.is_none() {
*clip = Some(Default::default());
None // TODO undo
} else {
None
}).flatten())
}
#[command(SetColor = "color")] fn clip_set_color (
&mut self, color: Option<ItemTheme>
) -> Perhaps<MidiClipCmd> {
Ok(self.clip_slot().map_inner_mut(|clip|MidiClipCmd::SetColor {
color: Some(clip.set_color(color))
}))
}
/// Toggle looping for the active clip
#[command(SetLoop = "loop")] fn clip_toggle_loop (
&mut self, looping: Option<bool>
) -> Perhaps<MidiClipCmd> {
Ok(self.clip_slot().map_inner_mut(|clip|MidiClipCmd::SetLoop {
looping: Some(clip.toggle_loop(looping))
}))
}
}
impl<T> BrowseControl for T where T:
Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>> {}
#[tek_proc::commands(BrowseCmd = "browse")] pub trait BrowseControl:
Namespace<usize> + Namespace<PathBuf> + Namespace<Arc<str>>
{
/// Toggle visibility of browser
#[command(Show = "show")] fn show (&mut self) -> Perhaps<BrowseCmd> {
todo!()
}
/// Set current directory
#[command(Chdir = "chdir")] fn chdir (&mut self, _path: PathBuf) -> Perhaps<BrowseCmd> {
todo!()
}
/// Set current filter
#[command(SetSearch = "set-search")] fn set_search (&mut self, _filter: Arc<str>) -> Perhaps<BrowseCmd> {
todo!()
}
/// Set selected item
#[command(SetCursor = "set-cursor")] fn set_cursor (&mut self, _index: usize) -> Perhaps<BrowseCmd> {
todo!()
}
}
#[tek_proc::commands(AxisCmd)] impl App {
/// Increment the given data axis.
#[command(Inc = "inc")] pub fn inc (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
Ok(match (&self.dialog, axis) {
(Dialog::None, _) => todo!(),
(Dialog::Menu(_, _), ControlAxis::Y) => {
AppCmd::Dialog { dialog: self.dialog.menu_next() }.dispatch(self)?;
None
},
_ => todo!()
})
}
/// Decrement the given data axis.
#[command(Dec = "dec")] pub fn dec (&mut self, axis: ControlAxis) -> Perhaps<AxisCmd> {
Ok(match (&self.dialog, axis) {
(Dialog::None, _) => None,
(Dialog::Menu(_, _), ControlAxis::Y) => {
AppCmd::Dialog { dialog: self.dialog.menu_prev() }.dispatch(self)?;
None
},
_ => todo!()
})
}
}