diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 8a189f0..248fe68 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -1,6 +1,6 @@ use crate::app::{ App, View, - keybindings::{default_view_keybindings, main_menu_keybindings}, + keybindings::{default_view_keybindings, main_menu_keybindings, settings_keybindings}, }; use ratatui::crossterm::event::KeyEvent; use std::io::Result; @@ -8,6 +8,7 @@ use std::io::Result; pub fn handle_keybindings(app: &mut App, key_event: KeyEvent) -> Result<()> { match app.view { View::MainMenu => main_menu_keybindings(app, &key_event), + View::Settings => settings_keybindings(app, &key_event), _ => default_view_keybindings(app, &key_event), } diff --git a/src/app/keybindings/keybindings.rs b/src/app/keybindings/keybindings.rs index dbbcfe1..f132a6f 100644 --- a/src/app/keybindings/keybindings.rs +++ b/src/app/keybindings/keybindings.rs @@ -9,6 +9,7 @@ pub enum Action { Up, Down, Space, + Enter, Esc, } @@ -84,6 +85,15 @@ pub static KEYBINDINGS: &[KeyBinding] = &[ symbol: "Space", description: "Select", }, + KeyBinding { + action: Action::Enter, + code: KeyCode::Enter, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::NONE, + group: Group::Select, + symbol: "Enter", + description: "Submit", + }, KeyBinding { action: Action::Esc, code: KeyCode::Esc, @@ -106,23 +116,36 @@ pub fn event_to_action(event: &KeyEvent) -> Option { .map(|b| b.action) } -fn used_groups_in_view(keybindings: &Vec<&'static KeyBinding>) -> HashSet { - keybindings.iter().map(|b| b.group).collect() +fn used_groups_in_view(keybindings: &Vec>) -> HashSet { + keybindings + .iter() + .filter_map(|b| b.map(|binding| binding.group)) + .collect() } -pub fn binding_for_view(view: View) -> (HashSet, Vec<&'static KeyBinding>) { - let main_menu_keybindings: Vec<&'static KeyBinding> = vec![ - binding_for(Action::Up).unwrap(), - binding_for(Action::Down).unwrap(), - binding_for(Action::Space).unwrap(), - binding_for(Action::Quit).unwrap(), - binding_for(Action::Quit2).unwrap(), +pub fn binding_for_view(view: View) -> (HashSet, Vec>) { + let main_menu_keybindings: Vec> = vec![ + binding_for(Action::Up), + binding_for(Action::Down), + binding_for(Action::Space), + binding_for(Action::Quit), + binding_for(Action::Quit2), ]; - let default_keybindings: Vec<&'static KeyBinding> = vec![ - binding_for(Action::Quit).unwrap(), - binding_for(Action::Quit2).unwrap(), - binding_for(Action::Esc).unwrap(), + let settings_keybinding: Vec> = vec![ + binding_for(Action::Up), + binding_for(Action::Down), + binding_for(Action::Space), + binding_for(Action::Enter), + binding_for(Action::Quit), + binding_for(Action::Quit2), + binding_for(Action::Esc), + ]; + + let default_keybindings: Vec> = vec![ + binding_for(Action::Quit), + binding_for(Action::Quit2), + binding_for(Action::Esc), ]; match view { @@ -130,6 +153,10 @@ pub fn binding_for_view(view: View) -> (HashSet, Vec<&'static KeyBinding> used_groups_in_view(&main_menu_keybindings), main_menu_keybindings, ), + View::Settings => ( + used_groups_in_view(&settings_keybinding), + settings_keybinding, + ), _ => ( used_groups_in_view(&default_keybindings), default_keybindings, diff --git a/src/app/keybindings/mod.rs b/src/app/keybindings/mod.rs index 54d6e2e..ae8fa91 100644 --- a/src/app/keybindings/mod.rs +++ b/src/app/keybindings/mod.rs @@ -1,9 +1,11 @@ pub mod default; pub mod keybindings; pub mod main_menu; +pub mod settings; pub use default::default_view_keybindings; pub use keybindings::{ Action, Group, KEYBINDINGS, KeyBinding, binding_for, binding_for_view, event_to_action, }; pub use main_menu::main_menu_keybindings; +pub use settings::settings_keybindings; diff --git a/src/app/keybindings/settings.rs b/src/app/keybindings/settings.rs new file mode 100644 index 0000000..ffcbabb --- /dev/null +++ b/src/app/keybindings/settings.rs @@ -0,0 +1,16 @@ +use crate::app::{ + App, View, + keybindings::{Action, event_to_action}, +}; +use ratatui::crossterm::event::KeyEvent; + +pub fn settings_keybindings(app: &mut App, key_event: &KeyEvent) { + if let Some(action) = event_to_action(&key_event) { + match action { + Action::Quit => app.exit = true, + Action::Quit2 => app.exit = true, + Action::Esc => app.view = View::MainMenu, + _ => (), + } + } +} diff --git a/src/app/widget.rs b/src/app/widget.rs index 08c90a0..5a37083 100644 --- a/src/app/widget.rs +++ b/src/app/widget.rs @@ -1,6 +1,6 @@ use crate::app::{ App, View, - widgets::{default_view_widget, main_menu_widget}, + widgets::{default_view_widget, main_menu_widget, settings_widget}, }; use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; @@ -11,6 +11,7 @@ impl Widget for &App { { match self.view { View::MainMenu => main_menu_widget(self, area, buf), + View::Settings => settings_widget(self, area, buf), _ => default_view_widget(self, area, buf), } } diff --git a/src/app/widgets/keybindings.rs b/src/app/widgets/keybindings.rs index 7bdca8d..ea7f5d4 100644 --- a/src/app/widgets/keybindings.rs +++ b/src/app/widgets/keybindings.rs @@ -26,9 +26,15 @@ impl KeybindingsWidget { let grouped_lines: Vec> = keybindings .iter() - .filter(|b| b.group == group) - .map(|b| { - Line::from_iter([b.symbol.red().bold(), " - ".into(), b.description.into()]) + .filter(|b| b.as_ref().map_or(false, |kb| kb.group == group)) + .filter_map(|b| { + b.as_ref().map(|kb| { + Line::from_iter([ + kb.symbol.red().bold(), + " - ".into(), + kb.description.into(), + ]) + }) }) .collect(); diff --git a/src/app/widgets/main_menu.rs b/src/app/widgets/main_menu.rs index fd0edf4..63e4802 100644 --- a/src/app/widgets/main_menu.rs +++ b/src/app/widgets/main_menu.rs @@ -12,15 +12,15 @@ fn view_options() -> Vec<(usize, String)> { View::value_variants() .iter() .enumerate() - .map(|(i, v)| { - let name = v - .to_possible_value() - .unwrap() - .get_name() - .replace('-', " ") - .to_uppercase() - .to_string(); - (i, name) + .filter_map(|(i, v)| { + v.to_possible_value().map(|possible_value| { + let name = possible_value + .get_name() + .replace('-', " ") + .to_uppercase() + .to_string(); + (i, name) + }) }) .filter(|(_, v)| v != "MAIN MENU") .collect() diff --git a/src/app/widgets/mod.rs b/src/app/widgets/mod.rs index 3285731..8873193 100644 --- a/src/app/widgets/mod.rs +++ b/src/app/widgets/mod.rs @@ -1,7 +1,9 @@ pub mod default; pub mod keybindings; pub mod main_menu; +pub mod settings; pub use default::default_view_widget; pub use keybindings::KeybindingsWidget; pub use main_menu::main_menu_widget; +pub use settings::settings_widget; diff --git a/src/app/widgets/settings.rs b/src/app/widgets/settings.rs new file mode 100644 index 0000000..9da3048 --- /dev/null +++ b/src/app/widgets/settings.rs @@ -0,0 +1,41 @@ +use crate::app::{App, widgets::KeybindingsWidget}; +use ratatui::{ + buffer::Buffer, + layout::{Alignment, Constraint, Layout, Rect}, + style::Stylize, + widgets::{Block, Borders, Padding, Paragraph, Widget}, +}; + +pub fn settings_widget(app: &App, area: Rect, buf: &mut Buffer) { + let vertical_layout: Layout = Layout::vertical([ + Constraint::Length(10), + Constraint::Fill(1), + Constraint::Length(4), + ]); + + let [title_area, main_area, keybindings_area] = vertical_layout.areas(area); + + Paragraph::new("War in tunnels") + .alignment(Alignment::Left) + .yellow() + .block( + Block::new() + .gray() + .borders(Borders::LEFT | Borders::TOP | Borders::RIGHT) + .padding(Padding::new(1, 1, 1, 1)), + ) + .render(title_area, buf); + + Paragraph::new("Settings") + .alignment(Alignment::Center) + .yellow() + .block( + Block::new() + .gray() + .borders(Borders::LEFT | Borders::RIGHT) + .padding(Padding::new(1, 1, 1, 1)), + ) + .render(main_area, buf); + + KeybindingsWidget::new(app.view).render(keybindings_area, buf); +}