diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/global_keys.rs | 75 | ||||
-rw-r--r-- | src/components/mod.rs | 1 | ||||
-rw-r--r-- | src/components/status.rs | 74 |
3 files changed, 107 insertions, 43 deletions
diff --git a/src/components/global_keys.rs b/src/components/global_keys.rs index d0a5800..39ec1b7 100644 --- a/src/components/global_keys.rs +++ b/src/components/global_keys.rs @@ -24,60 +24,49 @@ pub struct GlobalKeys { impl Component for GlobalKeys { fn init(&mut self) -> eyre::Result<()> { - self.key_commands.append(&mut vec![KeyCommand { - key_code: "?".to_string(), - description: "Toggle help menu".to_string(), - action: None, - }]); - self.scroll_state = ScrollbarState::new(self.key_commands.len()).position(self.scroll); Ok(()) } + fn handle_action(&mut self, action: AppAction) { + match action { + AppAction::ScrollUp => { + if self.scroll > 0 { + self.scroll -= 1; + } + } + AppAction::ScrollDown => { + if self.scroll < self.key_commands.len() - 1 { + self.scroll += 1; + } + } + AppAction::ScrollTop => { + self.scroll = 0; + } + AppAction::ScrollBottom => { + self.scroll = self.key_commands.len() - 1; + } + AppAction::ShowHelpMenu => { + self.should_show = !self.should_show; + self.scroll = 0; + } + + _ => {} + } + self.scroll_state = self.scroll_state.position(self.scroll); + } + fn handle_key_event( &mut self, key: KeyEvent, ) -> eyre::Result<Option<AppAction>> { if key.kind == KeyEventKind::Press { let key_event = serialize_key_event(key); - let eat_input = match key_event.as_str() { - "?" => { - self.should_show = !self.should_show; - self.scroll = 0; - true - } - "g" => { - self.scroll = 0; - true - } - "G" => { - self.scroll = self.key_commands.len() - 1; - true - } - "down" | "j" => { - if self.scroll < self.key_commands.len() - 1 { - self.scroll += 1; - } - true - } - "up" | "k" => { - if self.scroll > 0 { - self.scroll -= 1; - } - true - } - _ => false, - }; - self.scroll_state = self.scroll_state.position(self.scroll); - 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.clone()); + return Ok(Some(key_command.action.clone())); } } } @@ -108,7 +97,8 @@ impl Component for GlobalKeys { Title::from("Keyboard shortcuts").alignment(Alignment::Center), ) .borders(Borders::ALL) - .border_type(BorderType::Thick); + .border_type(BorderType::Thick) + .style(Style::default().bg(Color::DarkGray)); let mut lines: Vec<Line> = vec![]; for key_command in &mut self.key_commands { @@ -124,8 +114,7 @@ impl Component for GlobalKeys { let commands = Paragraph::new(lines) .block(block) .wrap(Wrap { trim: true }) - .scroll((u16::try_from(self.scroll)?, 0)) - .style(Style::default().bg(Color::DarkGray).fg(Color::White)); + .scroll((u16::try_from(self.scroll)?, 0)); if self.should_show { frame.render_widget(Clear, center); diff --git a/src/components/mod.rs b/src/components/mod.rs index 07fe4d8..a779415 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1 +1,2 @@ pub mod global_keys; +pub mod status; diff --git a/src/components/status.rs b/src/components/status.rs new file mode 100644 index 0000000..d91782f --- /dev/null +++ b/src/components/status.rs @@ -0,0 +1,74 @@ +use ratatui::prelude::*; +use ratatui::widgets::*; + +use crate::app_action::AppAction; +use crate::component::Component; +use crate::keys::key_commands::serialize_key_event; + +#[derive(Default, Clone)] +pub struct StatusBar { + message: String, + current_key: String, + error: bool, +} + +impl Component for StatusBar { + fn handle_key_event( + &mut self, + key: crossterm::event::KeyEvent, + ) -> eyre::Result<Option<AppAction>> { + let key_str = serialize_key_event(key); + self.current_key = key_str; + + Ok(None) + } + + fn handle_action(&mut self, action: crate::app_action::AppAction) { + match action { + AppAction::StatusBarSetMessage(message) => { + self.error = false; + self.message = message; + } + AppAction::StatusBarSetError(message) => { + self.error = true; + self.message = message; + } + AppAction::StatusBarGetInput(_prompt) => todo!(), + _ => { + self.current_key += " "; + self.current_key += &action.to_string(); + } + } + } + + fn render( + &mut self, + frame: &mut ratatui::prelude::Frame, + rect: ratatui::prelude::Rect, + ) -> eyre::Result<()> { + let block = + Block::default().style(Style::default().bg(if self.error { + Color::Red + } else { + Color::DarkGray + })); + + let layout = Layout::default() + .direction(Direction::Horizontal) + .constraints(vec![ + Constraint::Percentage(50), + Constraint::Percentage(50), + ]) + .split(rect); + + let message = Paragraph::new(self.message.clone()).block(block.clone()); + let current_key = Paragraph::new(self.current_key.clone()) + .block(block) + .alignment(Alignment::Right); + + frame.render_widget(message, layout[0]); + frame.render_widget(current_key, layout[1]); + + Ok(()) + } +} |