use egui::{ Button, CentralPanel, Context, Event, KeyboardShortcut, Label, Layout, Slider, Ui, ViewportBuilder, ViewportId, }; use egui_extras::{Column, TableBuilder}; use crate::input::{Command, ShortcutProvider}; use super::{AppWindow, utils::UiExt}; pub struct HotkeysWindow { shortcuts: ShortcutProvider, now_binding: Option, } impl HotkeysWindow { pub fn new(shortcuts: ShortcutProvider) -> Self { Self { shortcuts, now_binding: None, } } fn show_shortcuts(&mut self, ui: &mut Ui) { let row_height = ui.spacing().interact_size.y; ui.section("Shortcuts", |ui| { let width = ui.available_width() - 16.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 && 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; } } fn show_ff_settings(&mut self, ui: &mut Ui) { let row_height = ui.spacing().interact_size.y; ui.section("Fast Forward", |ui| { let width = ui.available_width() - 8.0; let mut ff_settings = self.shortcuts.ff_settings(); let mut updated = false; TableBuilder::new(ui) .column(Column::exact(width * 0.5)) .column(Column::exact(width * 0.5)) .body(|mut body| { body.row(row_height, |mut row| { row.col(|ui| { ui.label("Treat button as toggle"); }); row.col(|ui| { if ui.checkbox(&mut ff_settings.toggle, "").changed() { updated = true; } }); }); body.row(row_height, |mut row| { row.col(|ui| { ui.label("Speed multiplier"); }); row.col(|ui| { if ui .add_sized( ui.available_size(), Slider::new(&mut ff_settings.speed, 1..=15), ) .changed() { updated = true; } }); }); }); if updated { self.shortcuts.update_ff_settings(ff_settings); } }); } } impl AppWindow for HotkeysWindow { 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| { ui.horizontal(|ui| { if ui.button("Use defaults").clicked() { self.shortcuts.reset(); } }); ui.separator(); self.show_shortcuts(ui); self.show_ff_settings(ui); }); } }