use crate::prelude::*; pub struct Rows { focused: bool, focus: usize, items: Vec>, } impl Rows { pub fn new (focused: bool, items: Vec>) -> Self { Self { focused, focus: 0, items } } } impl Device for Rows { fn handle (&mut self, event: &AppEvent) -> Usually { Ok(self.items[self.focus].handle(event)? || match event { AppEvent::Input(event) => match event { Event::Key(KeyEvent { code: KeyCode::Up, .. }) => { if self.focus == 0 { self.focus = self.items.len(); } self.focus = self.focus - 1; true }, Event::Key(KeyEvent { code: KeyCode::Down, .. }) => { self.focus = self.focus + 1; if self.focus >= self.items.len() { self.focus = 0; } true }, Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => { self.focused = false; self.items[self.focus].handle(&AppEvent::Focus)?; true }, Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => { self.focused = true; self.items[self.focus].handle(&AppEvent::Blur)?; true }, _ => { false } }, _ => false }) } fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { let mut w = 0u16; let mut h = 0u16; for (i, device) in self.items.iter().enumerate() { let result = device.render(buf, Rect { x: area.x, y: area.y + h, width: area.width, height: area.height - h })?; if !self.focused && i == self.focus { draw_box_styled(buf, result, Some(Style::default().green().dim().bold())); } w = w.max(result.width); h = h + result.height; } Ok(Rect { x: area.x, y: area.y, width: w, height: h }) } } pub struct Columns { focused: bool, focus: usize, items: Vec>, } impl Columns { pub fn new (focused: bool, items: Vec>) -> Self { Self { focused, focus: 0, items } } } impl Device for Columns { fn handle (&mut self, event: &AppEvent) -> Usually { let focused = match self.focused { true => Some(self.items.get_mut(self.focus).unwrap()), false => None }; let handled = if let Some(item) = focused { item.handle(event)? } else { false }; if handled { return Ok(true); } Ok(match event { AppEvent::Input(event) => match event { Event::Key(KeyEvent { code: KeyCode::Left, .. }) => { if self.focus == 0 { self.focus = self.items.len(); } self.focus = self.focus - 1; true }, Event::Key(KeyEvent { code: KeyCode::Right, .. }) => { self.focus = self.focus + 1; if self.focus >= self.items.len() { self.focus = 0; } true }, Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => { self.focused = true; self.items[self.focus].handle(&AppEvent::Focus)?; true }, Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => { self.focused = false; self.items[self.focus].handle(&AppEvent::Blur)?; true }, _ => false }, _ => false }) } fn render (&self, buf: &mut Buffer, area: Rect) -> Usually { let mut w = 0u16; let mut h = 0u16; for (i, device) in self.items.iter().enumerate() { let result = device.render(buf, Rect { x: area.x + w, y: area.y, width: area.width - w, height: area.height })?; if !self.focused && i == self.focus { draw_box_styled(buf, result, Some(Style::default().green())); } w = w + result.width; h = h.max(result.height); } Ok(Rect { x: area.x, y: area.y, width: w, height: h }) } }