From 61e9dedfe84a802a00b7a9518b59d3d981db8486 Mon Sep 17 00:00:00 2001 From: GarandPLG Date: Fri, 13 Mar 2026 20:10:49 +0100 Subject: [PATCH] Refactor view handling and keybinding API Move the `View` enum to a dedicated module and implement `Widget` for `&App` there. Rename `default_view_keybindings` to `default_keybindings` and adjust its signature. Redesign `KeybindingsWidget` to accept an explicit list of bindings instead of a `View`. Update imports, function signatures, and rendering logic across the codebase to reflect these changes. --- src/app/app.rs | 14 ++----- src/app/keybind.rs | 12 +++--- src/app/keybindings/default.rs | 2 +- src/app/keybindings/keybindings.rs | 50 ------------------------- src/app/keybindings/mod.rs | 6 +-- src/app/mod.rs | 6 ++- src/app/view.rs | 28 ++++++++++++++ src/app/{widgets => views}/default.rs | 17 +++++++-- src/app/{widgets => views}/main_menu.rs | 20 ++++++++-- src/app/views/mod.rs | 7 ++++ src/app/{widgets => views}/settings.rs | 22 +++++++++-- src/app/widget.rs | 18 --------- src/app/widgets/keybindings.rs | 14 ++++--- src/app/widgets/mod.rs | 6 --- src/cli.rs | 2 +- 15 files changed, 109 insertions(+), 115 deletions(-) create mode 100644 src/app/view.rs rename src/app/{widgets => views}/default.rs (58%) rename src/app/{widgets => views}/main_menu.rs (83%) create mode 100644 src/app/views/mod.rs rename src/app/{widgets => views}/settings.rs (62%) delete mode 100644 src/app/widget.rs diff --git a/src/app/app.rs b/src/app/app.rs index f9bb9f9..e2ece48 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -1,5 +1,5 @@ use crate::{ - app::{GameStates, handle_keybindings}, + app::{GameStates, handle_keybindings, view::View}, cli::Cli, }; use clap::ValueEnum; @@ -34,15 +34,6 @@ pub struct App { pub skill_points_limit: u16, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)] -pub enum View { - MainMenu, - Skirmish, - PerkDecks, - SkillsConfig, - Settings, -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)] pub enum GameMode { LastManStanding, @@ -100,7 +91,8 @@ impl App { } fn handle_key_event(&mut self, key_event: KeyEvent) -> Result<()> { - handle_keybindings(self, key_event) + handle_keybindings(self, key_event); + Ok(()) } } diff --git a/src/app/keybind.rs b/src/app/keybind.rs index 248fe68..e7ffdb4 100644 --- a/src/app/keybind.rs +++ b/src/app/keybind.rs @@ -1,16 +1,14 @@ use crate::app::{ - App, View, - keybindings::{default_view_keybindings, main_menu_keybindings, settings_keybindings}, + App, + keybindings::{default_keybindings, main_menu_keybindings, settings_keybindings}, + view::View, }; use ratatui::crossterm::event::KeyEvent; -use std::io::Result; -pub fn handle_keybindings(app: &mut App, key_event: KeyEvent) -> Result<()> { +pub fn handle_keybindings(app: &mut App, key_event: KeyEvent) { match app.view { View::MainMenu => main_menu_keybindings(app, &key_event), View::Settings => settings_keybindings(app, &key_event), - _ => default_view_keybindings(app, &key_event), + _ => default_keybindings(app, &key_event), } - - Ok(()) } diff --git a/src/app/keybindings/default.rs b/src/app/keybindings/default.rs index bd39769..fd04762 100644 --- a/src/app/keybindings/default.rs +++ b/src/app/keybindings/default.rs @@ -4,7 +4,7 @@ use crate::app::{ }; use ratatui::crossterm::event::KeyEvent; -pub fn default_view_keybindings(app: &mut App, key_event: &KeyEvent) { +pub fn default_keybindings(app: &mut App, key_event: &KeyEvent) { if let Some(action) = event_to_action(&key_event) { match action { Action::Quit => app.exit = true, diff --git a/src/app/keybindings/keybindings.rs b/src/app/keybindings/keybindings.rs index f132a6f..46391c6 100644 --- a/src/app/keybindings/keybindings.rs +++ b/src/app/keybindings/keybindings.rs @@ -1,6 +1,4 @@ -use crate::app::View; use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; -use std::collections::HashSet; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Action { @@ -115,51 +113,3 @@ pub fn event_to_action(event: &KeyEvent) -> Option { .find(|b| b.code == event.code && b.kind == event.kind && b.modifiers == event.modifiers) .map(|b| b.action) } - -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>) { - 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 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 { - View::MainMenu => ( - 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 ae8fa91..66e8e40 100644 --- a/src/app/keybindings/mod.rs +++ b/src/app/keybindings/mod.rs @@ -3,9 +3,7 @@ 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 default::default_keybindings; +pub use keybindings::{Action, Group, KEYBINDINGS, KeyBinding, binding_for, event_to_action}; pub use main_menu::main_menu_keybindings; pub use settings::settings_keybindings; diff --git a/src/app/mod.rs b/src/app/mod.rs index 56c8397..e3f6ca7 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -2,11 +2,13 @@ pub mod app; pub mod game_states; pub mod keybind; pub mod keybindings; -pub mod widget; +pub mod view; +pub mod views; pub mod widgets; -pub use app::{App, Event, GameMode, PerkDecks, View, handle_input_events}; +pub use app::{App, Event, GameMode, PerkDecks, handle_input_events}; pub use game_states::{ GameStates, MainMenuState, PerkDecksState, SettingsState, SkillsConfigState, SkirmishState, }; pub use keybind::handle_keybindings; +pub use view::View; diff --git a/src/app/view.rs b/src/app/view.rs new file mode 100644 index 0000000..2506604 --- /dev/null +++ b/src/app/view.rs @@ -0,0 +1,28 @@ +use crate::app::{ + App, + views::{default_view, main_menu_view, settings_view}, +}; +use clap::ValueEnum; +use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)] +pub enum View { + MainMenu, + Skirmish, + PerkDecks, + SkillsConfig, + Settings, +} + +impl Widget for &App { + fn render(self, area: Rect, buf: &mut Buffer) + where + Self: Sized, + { + match self.view { + View::MainMenu => main_menu_view(self, area, buf), + View::Settings => settings_view(self, area, buf), + _ => default_view(area, buf), + } + } +} diff --git a/src/app/widgets/default.rs b/src/app/views/default.rs similarity index 58% rename from src/app/widgets/default.rs rename to src/app/views/default.rs index f52c076..8978dd1 100644 --- a/src/app/widgets/default.rs +++ b/src/app/views/default.rs @@ -1,4 +1,7 @@ -use crate::app::{App, widgets::KeybindingsWidget}; +use crate::app::{ + keybindings::{Action, KeyBinding, binding_for}, + widgets::KeybindingsWidget, +}; use ratatui::{ buffer::Buffer, layout::{Alignment, Constraint, Layout, Rect}, @@ -6,7 +9,7 @@ use ratatui::{ widgets::{Block, Borders, Paragraph, Widget}, }; -pub fn default_view_widget(app: &App, area: Rect, buf: &mut Buffer) { +pub fn default_view(area: Rect, buf: &mut Buffer) { let vertical_layout: Layout = Layout::vertical([Constraint::Fill(1), Constraint::Length(4)]); let [main_area, keybindings_area] = vertical_layout.areas(area); @@ -21,5 +24,13 @@ pub fn default_view_widget(app: &App, area: Rect, buf: &mut Buffer) { ) .render(main_area, buf); - KeybindingsWidget::new(app.view).render(keybindings_area, buf); + { + let keybindings: Vec> = vec![ + binding_for(Action::Quit), + binding_for(Action::Quit2), + binding_for(Action::Esc), + ]; + + KeybindingsWidget::new(keybindings).render(keybindings_area, buf); + } } diff --git a/src/app/widgets/main_menu.rs b/src/app/views/main_menu.rs similarity index 83% rename from src/app/widgets/main_menu.rs rename to src/app/views/main_menu.rs index 63e4802..64419cc 100644 --- a/src/app/widgets/main_menu.rs +++ b/src/app/views/main_menu.rs @@ -1,4 +1,8 @@ -use crate::app::{App, View, widgets::KeybindingsWidget}; +use crate::app::{ + App, View, + keybindings::{Action, KeyBinding, binding_for}, + widgets::KeybindingsWidget, +}; use clap::ValueEnum; use ratatui::{ buffer::Buffer, @@ -26,7 +30,7 @@ fn view_options() -> Vec<(usize, String)> { .collect() } -pub fn main_menu_widget(app: &App, area: Rect, buf: &mut Buffer) { +pub fn main_menu_view(app: &App, area: Rect, buf: &mut Buffer) { let vertical_layout: Layout = Layout::vertical([Constraint::Fill(1), Constraint::Length(4)]); let [main_menu_area, keybindings_area] = vertical_layout.areas(area); @@ -81,5 +85,15 @@ pub fn main_menu_widget(app: &App, area: Rect, buf: &mut Buffer) { .render(options_area, buf); } - KeybindingsWidget::new(View::MainMenu).render(keybindings_area, buf); + { + let keybindings: Vec> = vec![ + binding_for(Action::Up), + binding_for(Action::Down), + binding_for(Action::Space), + binding_for(Action::Quit), + binding_for(Action::Quit2), + ]; + + KeybindingsWidget::new(keybindings).render(keybindings_area, buf); + } } diff --git a/src/app/views/mod.rs b/src/app/views/mod.rs new file mode 100644 index 0000000..0b2fc93 --- /dev/null +++ b/src/app/views/mod.rs @@ -0,0 +1,7 @@ +pub mod default; +pub mod main_menu; +pub mod settings; + +pub use default::default_view; +pub use main_menu::main_menu_view; +pub use settings::settings_view; diff --git a/src/app/widgets/settings.rs b/src/app/views/settings.rs similarity index 62% rename from src/app/widgets/settings.rs rename to src/app/views/settings.rs index 9da3048..acb8e0a 100644 --- a/src/app/widgets/settings.rs +++ b/src/app/views/settings.rs @@ -1,4 +1,8 @@ -use crate::app::{App, widgets::KeybindingsWidget}; +use crate::app::{ + App, + keybindings::{Action, KeyBinding, binding_for}, + widgets::KeybindingsWidget, +}; use ratatui::{ buffer::Buffer, layout::{Alignment, Constraint, Layout, Rect}, @@ -6,7 +10,7 @@ use ratatui::{ widgets::{Block, Borders, Padding, Paragraph, Widget}, }; -pub fn settings_widget(app: &App, area: Rect, buf: &mut Buffer) { +pub fn settings_view(app: &App, area: Rect, buf: &mut Buffer) { let vertical_layout: Layout = Layout::vertical([ Constraint::Length(10), Constraint::Fill(1), @@ -37,5 +41,17 @@ pub fn settings_widget(app: &App, area: Rect, buf: &mut Buffer) { ) .render(main_area, buf); - KeybindingsWidget::new(app.view).render(keybindings_area, buf); + { + let keybindings: 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), + ]; + + KeybindingsWidget::new(keybindings).render(keybindings_area, buf); + } } diff --git a/src/app/widget.rs b/src/app/widget.rs deleted file mode 100644 index 5a37083..0000000 --- a/src/app/widget.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::app::{ - App, View, - widgets::{default_view_widget, main_menu_widget, settings_widget}, -}; -use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; - -impl Widget for &App { - fn render(self, area: Rect, buf: &mut Buffer) - where - Self: Sized, - { - 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 ea7f5d4..3f74db8 100644 --- a/src/app/widgets/keybindings.rs +++ b/src/app/widgets/keybindings.rs @@ -1,7 +1,6 @@ -use crate::app::{ - View, - keybindings::{Group, binding_for_view}, -}; +use std::collections::HashSet; + +use crate::app::keybindings::{Group, KeyBinding}; use ratatui::{ buffer::Buffer, layout::{Alignment, Constraint, Layout, Rect}, @@ -15,8 +14,11 @@ pub struct KeybindingsWidget { } impl KeybindingsWidget { - pub fn new(view: View) -> Self { - let (used_groups, keybindings) = binding_for_view(view); + pub fn new(keybindings: Vec>) -> Self { + let used_groups: HashSet = keybindings + .iter() + .filter_map(|b| b.map(|binding| binding.group)) + .collect(); let mut grouped_keybindings: Vec> = Vec::new(); for (i, group) in Group::iter().enumerate() { diff --git a/src/app/widgets/mod.rs b/src/app/widgets/mod.rs index 8873193..008492d 100644 --- a/src/app/widgets/mod.rs +++ b/src/app/widgets/mod.rs @@ -1,9 +1,3 @@ -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/cli.rs b/src/cli.rs index c637a41..90ad819 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use crate::app::{GameMode, PerkDecks, View}; +use crate::app::{GameMode, PerkDecks, view::View}; use clap::Parser; #[derive(Parser, Debug)]