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.
This commit is contained in:
2026-03-12 17:31:31 +01:00
parent 8b7c2c55ce
commit 073e70441f
3 changed files with 64 additions and 24 deletions
+28 -17
View File
@@ -1,5 +1,6 @@
use crate::app::View; use crate::app::View;
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
use std::collections::HashSet;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Action { pub enum Action {
@@ -24,10 +25,6 @@ impl Group {
.iter() .iter()
.copied() .copied()
} }
pub fn len() -> usize {
Self::iter().count()
}
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -109,19 +106,33 @@ pub fn event_to_action(event: &KeyEvent) -> Option<Action> {
.map(|b| b.action) .map(|b| b.action)
} }
pub fn binding_for_view(view: View) -> Vec<&'static KeyBinding> { fn used_groups_in_view(keybindings: &Vec<&'static KeyBinding>) -> HashSet<Group> {
keybindings.iter().map(|b| b.group).collect()
}
pub fn binding_for_view(view: View) -> (HashSet<Group>, 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 { match view {
View::MainMenu => vec![ View::MainMenu => (
binding_for(Action::Up).unwrap(), used_groups_in_view(&main_menu_keybindings),
binding_for(Action::Down).unwrap(), main_menu_keybindings,
binding_for(Action::Space).unwrap(), ),
binding_for(Action::Quit).unwrap(), _ => (
binding_for(Action::Quit2).unwrap(), used_groups_in_view(&default_keybindings),
], default_keybindings,
_ => vec![ ),
binding_for(Action::Quit).unwrap(),
binding_for(Action::Quit2).unwrap(),
binding_for(Action::Esc).unwrap(),
],
} }
} }
+28 -3
View File
@@ -1,5 +1,13 @@
use crate::app::{App, View, widgets::main_menu_widget}; use crate::app::{
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; 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 { impl Widget for &App {
fn render(self, area: Rect, buf: &mut Buffer) fn render(self, area: Rect, buf: &mut Buffer)
@@ -8,7 +16,24 @@ impl Widget for &App {
{ {
match self.view { match self.view {
View::MainMenu => main_menu_widget(self, area, buf), 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);
}
} }
} }
} }
+8 -4
View File
@@ -1,6 +1,6 @@
use crate::app::{ use crate::app::{
View, View,
keybindings::{Group, KeyBinding, binding_for_view}, keybindings::{Group, binding_for_view},
}; };
use ratatui::{ use ratatui::{
buffer::Buffer, buffer::Buffer,
@@ -43,10 +43,14 @@ impl Widget for KeybindingsWidget {
} }
pub fn keybindings_widget(view: View) -> 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<Paragraph<'static>> = Vec::new(); let mut grouped_keybindings: Vec<Paragraph<'static>> = Vec::new();
for (i, group) in Group::iter().enumerate() { for (i, group) in Group::iter().enumerate() {
if !used_groups.contains(&group) {
continue;
}
let grouped_lines: Vec<Line<'_>> = keybindings let grouped_lines: Vec<Line<'_>> = keybindings
.iter() .iter()
.filter(|b| b.group == group) .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)); let mut block: Block<'_> = Block::default().padding(Padding::new(1, 1, 0, 0));
if i != Group::len() - 1 { if i != 0 {
block = block.borders(Borders::RIGHT); block = block.borders(Borders::LEFT);
} }
grouped_keybindings.push( grouped_keybindings.push(