From 073e70441f942e31355807f6c5156d7e168780e2 Mon Sep 17 00:00:00 2001 From: GarandPLG Date: Thu, 12 Mar 2026 17:31:31 +0100 Subject: [PATCH] Add group filtering and layout for keybindings UI Return the set of used groups from `binding_for_view` and adjust `keybindings_widget` to render only those groups. Introduce a vertical layout in the main widget to display a placeholder paragraph above the keybindings area, and update imports and border logic accordingly. --- src/app/keybindings/keybindings.rs | 45 +++++++++++++++++++----------- src/app/widget.rs | 31 ++++++++++++++++++-- src/app/widgets/keybindings.rs | 12 +++++--- 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/src/app/keybindings/keybindings.rs b/src/app/keybindings/keybindings.rs index 075faca..e9e3f70 100644 --- a/src/app/keybindings/keybindings.rs +++ b/src/app/keybindings/keybindings.rs @@ -1,5 +1,6 @@ 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 { @@ -24,10 +25,6 @@ impl Group { .iter() .copied() } - - pub fn len() -> usize { - Self::iter().count() - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -109,19 +106,33 @@ pub fn event_to_action(event: &KeyEvent) -> Option { .map(|b| b.action) } -pub fn binding_for_view(view: View) -> Vec<&'static KeyBinding> { +fn used_groups_in_view(keybindings: &Vec<&'static KeyBinding>) -> HashSet { + keybindings.iter().map(|b| b.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(), + ]; + + let default_keybindings: Vec<&'static KeyBinding> = vec![ + binding_for(Action::Quit).unwrap(), + binding_for(Action::Quit2).unwrap(), + binding_for(Action::Esc).unwrap(), + ]; + match view { - View::MainMenu => 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(), - ], - _ => vec![ - binding_for(Action::Quit).unwrap(), - binding_for(Action::Quit2).unwrap(), - binding_for(Action::Esc).unwrap(), - ], + View::MainMenu => ( + used_groups_in_view(&main_menu_keybindings), + main_menu_keybindings, + ), + _ => ( + used_groups_in_view(&default_keybindings), + default_keybindings, + ), } } diff --git a/src/app/widget.rs b/src/app/widget.rs index 38087e7..7a2c1ea 100644 --- a/src/app/widget.rs +++ b/src/app/widget.rs @@ -1,5 +1,13 @@ -use crate::app::{App, View, widgets::main_menu_widget}; -use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; +use crate::app::{ + App, View, + widgets::{keybindings_widget, main_menu_widget}, +}; +use ratatui::{ + buffer::Buffer, + layout::{Alignment, Constraint, Layout, Rect}, + style::Stylize, + widgets::{Block, Borders, Paragraph, Widget}, +}; impl Widget for &App { fn render(self, area: Rect, buf: &mut Buffer) @@ -8,7 +16,24 @@ impl Widget for &App { { match self.view { View::MainMenu => main_menu_widget(self, area, buf), - _ => (), + _ => { + let vertical_layout: Layout = + Layout::vertical([Constraint::Fill(1), Constraint::Length(4)]); + + let [main_area, keybindings_area] = vertical_layout.areas(area); + + Paragraph::new("Work in progress") + .alignment(Alignment::Center) + .yellow() + .block( + Block::new() + .gray() + .borders(Borders::LEFT | Borders::TOP | Borders::RIGHT), + ) + .render(main_area, buf); + + keybindings_widget(self.view).render(keybindings_area, buf); + } } } } diff --git a/src/app/widgets/keybindings.rs b/src/app/widgets/keybindings.rs index fc196cd..51de7d9 100644 --- a/src/app/widgets/keybindings.rs +++ b/src/app/widgets/keybindings.rs @@ -1,6 +1,6 @@ use crate::app::{ View, - keybindings::{Group, KeyBinding, binding_for_view}, + keybindings::{Group, binding_for_view}, }; use ratatui::{ buffer::Buffer, @@ -43,10 +43,14 @@ impl Widget for KeybindingsWidget { } pub fn keybindings_widget(view: View) -> KeybindingsWidget { - let keybindings: Vec<&'static KeyBinding> = binding_for_view(view); + let (used_groups, keybindings) = binding_for_view(view); let mut grouped_keybindings: Vec> = Vec::new(); for (i, group) in Group::iter().enumerate() { + if !used_groups.contains(&group) { + continue; + } + let grouped_lines: Vec> = keybindings .iter() .filter(|b| b.group == group) @@ -55,8 +59,8 @@ pub fn keybindings_widget(view: View) -> KeybindingsWidget { let mut block: Block<'_> = Block::default().padding(Padding::new(1, 1, 0, 0)); - if i != Group::len() - 1 { - block = block.borders(Borders::RIGHT); + if i != 0 { + block = block.borders(Borders::LEFT); } grouped_keybindings.push(