diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/global_keys.rs | 95 | ||||
-rw-r--r-- | src/components/hello_world.rs | 20 |
2 files changed, 86 insertions, 29 deletions
diff --git a/src/components/global_keys.rs b/src/components/global_keys.rs index 67b1b6a..27adab0 100644 --- a/src/components/global_keys.rs +++ b/src/components/global_keys.rs @@ -1,27 +1,38 @@ -use crossterm::event::{KeyCode, KeyEvent, KeyEventKind}; -use ratatui::prelude::*; -use ratatui::widgets::*; +use crossterm::event::{KeyEvent, KeyEventKind}; +use ratatui::prelude::{ + Alignment, Color, Constraint, Direction, Frame, Layout, Line, Margin, Rect, + Span, Style, Stylize, +}; +use ratatui::widgets::block::{Block, BorderType, Title}; +use ratatui::widgets::{ + Borders, Clear, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState, + Wrap, +}; use crate::app_action::AppAction; use crate::component::Component; -use crate::keys::key_commands::*; +use crate::keys::key_commands::{serialize_key_event, KeyCommand}; #[derive(Default)] pub struct GlobalKeys { pub key_commands: Vec<KeyCommand>, pub should_show: bool, - pub scroll: u16, + pub scroll: usize, + pub scroll_state: ScrollbarState, } impl Component for GlobalKeys { fn init(&mut self) -> eyre::Result<()> { self.key_commands.push(KeyCommand { key_code: "?".to_string(), - description: "Show help menu".to_string(), + description: "Toggle help menu".to_string(), action: None, }); + self.scroll_state = + ScrollbarState::new(self.key_commands.len()).position(self.scroll); + Ok(()) } @@ -30,12 +41,36 @@ impl Component for GlobalKeys { key: KeyEvent, ) -> eyre::Result<Option<AppAction>> { if key.kind == KeyEventKind::Press { - for key_command in self.key_commands.iter_mut() { - if key_command.key_code == serialize_key_event(key) { - if serialize_key_event(key) == "?" { - self.should_show = !self.should_show; + let key_event = serialize_key_event(key); + let eat_input = match key_event.as_str() { + "?" => { + self.should_show = !self.should_show; + true + } + "down" => { + if self.scroll < self.key_commands.len() - 1 { + self.scroll += 1; + self.scroll_state = + self.scroll_state.position(self.scroll); + } + true + } + "up" => { + if self.scroll > 0 { + self.scroll -= 1; + self.scroll_state = + self.scroll_state.position(self.scroll); } + true + } + _ => false, + }; + if eat_input && self.should_show { + return Ok(None); + } + for key_command in &mut self.key_commands { + if key_command.key_code == key_event { return Ok(key_command.action); } } @@ -45,12 +80,32 @@ impl Component for GlobalKeys { } fn render(&mut self, frame: &mut Frame, rect: Rect) -> eyre::Result<()> { + let vertical_center = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage(50 / 2), + Constraint::Percentage(50), + Constraint::Percentage(50 / 2), + ]) + .split(rect); + let center = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(50 / 2), + Constraint::Percentage(50), + Constraint::Percentage(50 / 2), + ]) + .split(vertical_center[1])[1]; + let block = Block::default() - .title("Keyboard shortcuts") - .borders(Borders::ALL); + .title( + Title::from("Keyboard shortcuts").alignment(Alignment::Center), + ) + .borders(Borders::ALL) + .border_type(BorderType::Thick); let mut lines: Vec<Line> = vec![]; - for key_command in self.key_commands.iter_mut() { + for key_command in &mut self.key_commands { let command = Span::from(key_command.key_code.clone()); let description = Span::from(key_command.description.clone()).italic(); @@ -63,10 +118,20 @@ impl Component for GlobalKeys { let commands = Paragraph::new(lines) .block(block) .wrap(Wrap { trim: true }) - .scroll((self.scroll, 0)); + .scroll((u16::try_from(self.scroll)?, 0)) + .style(Style::default().bg(Color::DarkGray).fg(Color::LightYellow)); if self.should_show { - frame.render_widget(commands, rect); + frame.render_widget(Clear, center); + frame.render_widget(commands, center); + frame.render_stateful_widget( + Scrollbar::new(ScrollbarOrientation::VerticalRight), + center.inner(&Margin { + vertical: 1, + horizontal: 0, + }), + &mut self.scroll_state, + ); } Ok(()) diff --git a/src/components/hello_world.rs b/src/components/hello_world.rs index 2e3a2ee..ac9d02b 100644 --- a/src/components/hello_world.rs +++ b/src/components/hello_world.rs @@ -1,9 +1,7 @@ -use ratatui::prelude::*; -use ratatui::widgets::Paragraph; +use ratatui::prelude::{Frame, Rect}; +use ratatui::widgets::{Paragraph, Wrap}; -use crate::app_action::AppAction; use crate::component::Component; -use crate::keys::key_commands::*; #[derive(Default, Clone)] pub struct HelloWorld { @@ -16,17 +14,11 @@ impl Component for HelloWorld { Ok(()) } - fn handle_key_event( - &mut self, - key: crossterm::event::KeyEvent, - ) -> eyre::Result<Option<AppAction>> { - self.text = serialize_key_event(key); - Ok(None) - } - fn render(&mut self, frame: &mut Frame, rect: Rect) -> eyre::Result<()> { - - frame.render_widget(Paragraph::new(self.text.clone()), rect); + frame.render_widget( + Paragraph::new(self.text.clone()).wrap(Wrap { trim: true }), + rect, + ); Ok(()) } |