mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 04:36:45 +01:00
wip: component refactor
This commit is contained in:
parent
5082bf9fdf
commit
c18aa2cbbd
14 changed files with 374 additions and 272 deletions
180
src/layout/focus.rs
Normal file
180
src/layout/focus.rs
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub trait Focus {
|
||||
fn unfocus (&mut self);
|
||||
fn focused (&self) -> Option<&Box<dyn Device>>;
|
||||
fn focused_mut (&mut self) -> Option<&mut Box<dyn Device>>;
|
||||
fn handle_focus (&mut self, event: &FocusEvent) -> Usually<bool>;
|
||||
}
|
||||
|
||||
pub enum FocusEvent { Forward, Backward, Inward, Outward, }
|
||||
|
||||
pub fn handle_focus <T: Focus> (
|
||||
state: &mut T,
|
||||
event: &AppEvent,
|
||||
keymap: &[KeyBinding<T>]
|
||||
) -> Usually<bool> {
|
||||
let handled = if let Some(focused) = state.focused_mut() {
|
||||
focused.handle(event)
|
||||
} else {
|
||||
Ok(false)
|
||||
};
|
||||
return Ok(handled? || handle_keymap(
|
||||
state, event, keymap
|
||||
)?)
|
||||
}
|
||||
|
||||
pub struct FocusColumn(pub Option<usize>, pub Column);
|
||||
|
||||
impl Device for FocusColumn {
|
||||
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
|
||||
handle_focus(self, event, KEYMAP_FOCUS_COLUMN)
|
||||
}
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let (rect, rects) = super::render_column(self.1.0.as_ref(), buf, area, )?;
|
||||
//if i == self.focus {
|
||||
//if self.focused {
|
||||
//draw_box_styled(buf, result, Some(Style::default().white().not_dim()))
|
||||
//} else {
|
||||
//draw_box_styled_dotted(buf, result, Some(Style::default().white().dim()))
|
||||
//};
|
||||
//};
|
||||
Ok(rect)
|
||||
}
|
||||
}
|
||||
|
||||
const KEYMAP_FOCUS_COLUMN: &'static [KeyBinding<FocusColumn>] = keymap!(FocusColumn {
|
||||
[Up, NONE, "focus_up", "focus row above",
|
||||
|s: &mut FocusColumn|s.handle_focus(&FocusEvent::Backward)],
|
||||
[Down, NONE, "focus_down", "focus row below",
|
||||
|s: &mut FocusColumn|s.handle_focus(&FocusEvent::Forward)],
|
||||
[Enter, NONE, "focus_down", "focus row below",
|
||||
|s: &mut FocusColumn|s.handle_focus(&FocusEvent::Inward)],
|
||||
[Esc, NONE, "focus_down", "focus row below",
|
||||
|s: &mut FocusColumn|s.handle_focus(&FocusEvent::Outward)]
|
||||
});
|
||||
|
||||
impl Focus for FocusColumn {
|
||||
fn unfocus (&mut self) {
|
||||
self.0 = None
|
||||
}
|
||||
fn focused (&self) -> Option<&Box<dyn Device>> {
|
||||
self.0.map(|index|self.1.0.get(index))?
|
||||
}
|
||||
fn focused_mut (&mut self) -> Option<&mut Box<dyn Device>> {
|
||||
self.0.map(|index|self.1.0.get_mut(index))?
|
||||
}
|
||||
fn handle_focus (&mut self, event: &FocusEvent) -> Usually<bool> {
|
||||
Ok(match event {
|
||||
FocusEvent::Backward => match self.0 {
|
||||
Some(i) => {
|
||||
self.0 = Some(if i == 0 {
|
||||
self.1.0.len() - 1
|
||||
} else {
|
||||
i - 1
|
||||
});
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
FocusEvent::Forward => match self.0 {
|
||||
Some(i) => {
|
||||
self.0 = Some(if i >= self.1.0.len() {
|
||||
0
|
||||
} else {
|
||||
i + 1
|
||||
});
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
FocusEvent::Inward => match self.0 {
|
||||
None => {
|
||||
self.0 = Some(0);
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
FocusEvent::Outward => match self.0 {
|
||||
Some(i) => {
|
||||
self.0 = None;
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FocusRow(pub Option<usize>, pub Row);
|
||||
|
||||
impl Device for FocusRow {
|
||||
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
|
||||
handle_focus(self, event, keymap!(Self {
|
||||
[Left, NONE, "focus_up", "focus row above",
|
||||
|s: &mut Self|s.handle_focus(&FocusEvent::Backward)],
|
||||
[Right, NONE, "focus_down", "focus row below",
|
||||
|s: &mut Self|s.handle_focus(&FocusEvent::Forward)],
|
||||
[Enter, NONE, "focus_down", "focus row below",
|
||||
|s: &mut Self|s.handle_focus(&FocusEvent::Inward)],
|
||||
[Esc, NONE, "focus_down", "focus row below",
|
||||
|s: &mut Self|s.handle_focus(&FocusEvent::Outward)]
|
||||
}))
|
||||
}
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let (rect, rects) = super::render_row(&self.1.0, buf, area)?;
|
||||
Ok(rect)
|
||||
}
|
||||
}
|
||||
|
||||
impl Focus for FocusRow {
|
||||
fn unfocus (&mut self) {
|
||||
self.0 = None
|
||||
}
|
||||
fn focused (&self) -> Option<&Box<dyn Device>> {
|
||||
self.0.map(|index|self.1.0.get(index))?
|
||||
}
|
||||
fn focused_mut (&mut self) -> Option<&mut Box<dyn Device>> {
|
||||
self.0.map(|index|self.1.0.get_mut(index))?
|
||||
}
|
||||
fn handle_focus (&mut self, event: &FocusEvent) -> Usually<bool> {
|
||||
Ok(match event {
|
||||
FocusEvent::Backward => match self.0 {
|
||||
Some(i) => {
|
||||
self.0 = Some(if i == 0 {
|
||||
self.1.0.len() - 1
|
||||
} else {
|
||||
i - 1
|
||||
});
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
FocusEvent::Forward => match self.0 {
|
||||
Some(i) => {
|
||||
self.0 = Some(if i >= self.1.0.len() {
|
||||
0
|
||||
} else {
|
||||
i + 1
|
||||
});
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
FocusEvent::Inward => match self.0 {
|
||||
None => {
|
||||
self.0 = Some(0);
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
FocusEvent::Outward => match self.0 {
|
||||
Some(i) => {
|
||||
self.0 = None;
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue