use egui::{ Button, CentralPanel, Context, Event, KeyboardShortcut, Label, Layout, Ui, ViewportBuilder, ViewportId, }; use egui_extras::{Column, TableBuilder}; use crate::input::{Command, ShortcutProvider}; use super::AppWindow; pub struct ShortcutsWindow { shortcuts: ShortcutProvider, now_binding: Option, } impl ShortcutsWindow { pub fn new(shortcuts: ShortcutProvider) -> Self { Self { shortcuts, now_binding: None, } } fn show_shortcuts(&mut self, ui: &mut Ui) { ui.horizontal(|ui| { if ui.button("Use defaults").clicked() { self.shortcuts.reset(); } }); ui.separator(); let row_height = ui.spacing().interact_size.y; let width = ui.available_width() - 20.0; TableBuilder::new(ui) .column(Column::exact(width * 0.3)) .column(Column::exact(width * 0.5)) .column(Column::exact(width * 0.2)) .cell_layout(Layout::left_to_right(egui::Align::Center)) .body(|mut body| { for command in Command::all() { body.row(row_height, |mut row| { row.col(|ui| { ui.add_sized(ui.available_size(), Label::new(command.name())); }); row.col(|ui| { let button = if self.now_binding == Some(command) { Button::new("Binding...") } else if let Some(shortcut) = self.shortcuts.shortcut_for(command) { Button::new(ui.ctx().format_shortcut(&shortcut)) } else { Button::new("") }; if ui.add_sized(ui.available_size(), button).clicked() { self.now_binding = Some(command); } }); row.col(|ui| { if ui .add_sized(ui.available_size(), Button::new("Clear")) .clicked() { self.shortcuts.unset(command); self.now_binding = None; } }); }); } }); if let Some(command) = self.now_binding { if let Some(shortcut) = ui.input_mut(|i| { i.events.iter().find_map(|event| match event { Event::Key { key, pressed: true, modifiers, .. } => Some(KeyboardShortcut::new(*modifiers, *key)), _ => None, }) }) { self.shortcuts.set(command, shortcut); self.now_binding = None; } } } } impl AppWindow for ShortcutsWindow { fn viewport_id(&self) -> ViewportId { ViewportId::from_hash_of("shortcuts") } fn initial_viewport(&self) -> ViewportBuilder { ViewportBuilder::default() .with_title("Keyboard Shortcuts") .with_inner_size((400.0, 400.0)) } fn show(&mut self, ctx: &Context) { CentralPanel::default().show(ctx, |ui| { self.show_shortcuts(ui); }); } }