use crate::*; #[derive(Clone, Copy, Debug, PartialEq)] pub enum AppFocus { /// The menu bar is focused Menu, /// The app content is focused Content(T) } pub trait FocusWrap { fn wrap <'a, W: Widget> (self, focus: T, content: &'a W) -> impl Widget + 'a; } macro_rules! impl_focus { ($Struct:ident $Focus:ident $Grid:expr) => { impl HasFocus for $Struct { type Item = AppFocus<$Focus>; /// Get the currently focused item. fn focused (&self) -> Self::Item { self.focus.inner() } /// Get the currently focused item. fn set_focused (&mut self, to: Self::Item) { self.focus.set_inner(to) } } impl HasEnter for $Struct { /// Get the currently focused item. fn entered (&self) -> bool { self.focus.is_entered() } /// Get the currently focused item. fn set_entered (&mut self, entered: bool) { if entered { self.focus.to_entered() } else { self.focus.to_focused() } } } impl FocusGrid for $Struct { fn focus_cursor (&self) -> (usize, usize) { self.cursor } fn focus_cursor_mut (&mut self) -> &mut (usize, usize) { &mut self.cursor } fn focus_layout (&self) -> &[&[AppFocus<$Focus>]] { use AppFocus::*; use $Focus::*; &$Grid } } } } impl_focus!(TransportTui TransportFocus [ //&[Menu], &[ Content(PlayPause), Content(Bpm), Content(Sync), Content(Clock), Content(Quant) ], ]); impl_focus!(SequencerTui SequencerFocus [ //&[ //Menu, //Menu, //Menu, //Menu, //Menu, //], &[ Content(Transport(TransportFocus::PlayPause)), Content(Transport(TransportFocus::Bpm)), Content(Transport(TransportFocus::Sync)), Content(Transport(TransportFocus::Clock)), Content(Transport(TransportFocus::Quant)) ], &[ Content(Phrases), Content(Phrases), Content(PhraseEditor), Content(PhraseEditor), Content(PhraseEditor), ], ]); impl_focus!(ArrangerTui ArrangerFocus [ //&[ //Menu, //Menu, //Menu, //Menu, //Menu, //], &[ Content(Transport(TransportFocus::PlayPause)), Content(Transport(TransportFocus::Bpm)), Content(Transport(TransportFocus::Sync)), Content(Transport(TransportFocus::Clock)), Content(Transport(TransportFocus::Quant)) ], &[ Content(Arranger), Content(Arranger), Content(Arranger), Content(Arranger), Content(Arranger), ], &[ Content(Phrases), Content(Phrases), Content(PhraseEditor), Content(PhraseEditor), Content(PhraseEditor), ], ]);