wip: directional focus!

This commit is contained in:
🪞👃🪞 2024-10-09 14:49:00 +03:00
parent ec3eb40bb4
commit 225eda0d24
5 changed files with 118 additions and 59 deletions

View file

@ -1,5 +1,70 @@
use crate::*;
pub trait FocusGrid<T> {
fn layout (&self) -> &[&[T]];
fn cursor (&self) -> (usize, usize);
fn cursor_mut (&mut self) -> &mut (usize, usize);
fn focused (&self) -> &T {
let (x, y) = self.cursor();
&self.layout()[y][x]
}
fn focus_up (&mut self) {
let layout = self.layout();
let (x, y) = self.cursor();
let next_y = if y == 0 { layout.len() - 1 } else { y - 1 };
let next_x = if layout[y].len() == layout[next_y].len() { x } else {
((x as f32 / layout[y].len() as f32) * layout[next_y].len() as f32) as usize
};
*self.cursor_mut() = (next_x, next_y);
}
fn focus_down (&mut self) {
let layout = self.layout();
let (x, y) = self.cursor();
let next_y = if y >= layout.len() - 1 { 0 } else { y + 1 };
let next_x = if layout[y].len() == layout[next_y].len() { x } else {
((x as f32 / layout[y].len() as f32) * layout[next_y].len() as f32) as usize
};
*self.cursor_mut() = (next_x, next_y);
}
fn focus_left (&mut self) {
let layout = self.layout();
let (x, y) = self.cursor();
let next_x = if x == 0 { layout[y].len() - 1 } else { x - 1 };
*self.cursor_mut() = (next_x, y);
}
fn focus_right (&mut self) {
let layout = self.layout();
let (x, y) = self.cursor();
let next_x = if x >= layout[y].len() - 1 { 0 } else { x - 1 };
*self.cursor_mut() = (next_x, y);
}
fn focus_next (&mut self) {
todo!();
}
fn focus_prev (&mut self) {
todo!();
}
}
//pub struct FocusFrame<'a, E: Engine>(usize, Vec<FocusCell<'a, E>>);
//pub struct FocusCell<'a, E: Engine> {
//item: &'a dyn Handle<E>,
//next: Option<&'a FocusCell<'a, E>>,
//prev: Option<&'a FocusCell<'a, E>>,
//up: Option<&'a FocusCell<'a, E>>,
//down: Option<&'a FocusCell<'a, E>>,
//left: Option<&'a FocusCell<'a, E>>,
//right: Option<&'a FocusCell<'a, E>>,
//}
pub trait FocusContainer<E: Engine> {
fn focused (&mut self) -> &mut dyn Handle<E>;
fn handle_focus (&mut self, _: &E::Input) -> Perhaps<bool> {
Ok(None)
}
}
/// A component that may contain [Focusable] components.
pub trait Focus <const N: usize, E: Engine>: Widget<Engine = E> + Handle<E> {
fn focus (&self) -> usize;

View file

@ -219,6 +219,14 @@ pub type KeyMap<T> = [KeyBinding<T>];
kind: crossterm::event::KeyEventKind::Press,
state: crossterm::event::KeyEventState::NONE
}))
};
(Shift-$code:pat) => {
TuiEvent::Input(crossterm::event::Event::Key(crossterm::event::KeyEvent {
code: $code,
modifiers: crossterm::event::KeyModifiers::SHIFT,
kind: crossterm::event::KeyEventKind::Press,
state: crossterm::event::KeyEventState::NONE
}))
}
}
pub struct TuiOutput {