Add bindable keyboard shortcuts

This commit is contained in:
2025-03-03 00:06:14 -05:00
parent fcfb75fead
commit bbffde50ec
5 changed files with 411 additions and 15 deletions
+88 -11
View File
@@ -3,6 +3,7 @@ use std::sync::mpsc;
use crate::{
app::UserEvent,
emulator::{EmulatorClient, EmulatorCommand, EmulatorState, SimId, SimState},
input::{Command, ShortcutProvider},
persistence::Persistence,
};
use egui::{
@@ -38,6 +39,7 @@ pub struct GameWindow {
client: EmulatorClient,
proxy: EventLoopProxy<UserEvent>,
persistence: Persistence,
shortcuts: ShortcutProvider,
sim_id: SimId,
config: GameConfig,
screen: Option<GameScreen>,
@@ -50,6 +52,7 @@ impl GameWindow {
client: EmulatorClient,
proxy: EventLoopProxy<UserEvent>,
persistence: Persistence,
shortcuts: ShortcutProvider,
sim_id: SimId,
) -> Self {
let config = load_config(&persistence, sim_id);
@@ -57,6 +60,7 @@ impl GameWindow {
client,
proxy,
persistence,
shortcuts,
sim_id,
config,
screen: None,
@@ -66,8 +70,53 @@ impl GameWindow {
}
fn show_menu(&mut self, ctx: &Context, ui: &mut Ui) {
let state = self.client.emulator_state();
let is_ready = self.client.sim_state(self.sim_id) == SimState::Ready;
let can_pause = is_ready && state == EmulatorState::Running;
let can_resume = is_ready && state == EmulatorState::Paused;
let can_frame_advance = is_ready && state != EmulatorState::Debugging;
for command in ui.input_mut(|input| self.shortcuts.consume_all(input)) {
match command {
Command::OpenRom => {
let rom = rfd::FileDialog::new()
.add_filter("Virtual Boy ROMs", &["vb", "vbrom"])
.pick_file();
if let Some(path) = rom {
self.client
.send_command(EmulatorCommand::LoadGame(self.sim_id, path));
}
}
Command::Quit => {
let _ = self.proxy.send_event(UserEvent::Quit(self.sim_id));
}
Command::PauseResume => {
if state == EmulatorState::Paused && can_resume {
self.client.send_command(EmulatorCommand::Resume);
}
if state == EmulatorState::Running && can_pause {
self.client.send_command(EmulatorCommand::Pause);
}
}
Command::Reset => {
if is_ready {
self.client
.send_command(EmulatorCommand::Reset(self.sim_id));
}
}
Command::FrameAdvance => {
if can_frame_advance {
self.client.send_command(EmulatorCommand::FrameAdvance);
}
}
}
}
ui.menu_button("ROM", |ui| {
if ui.button("Open ROM").clicked() {
if ui
.add(self.button_for(ui.ctx(), "Open ROM", Command::OpenRom))
.clicked()
{
let rom = rfd::FileDialog::new()
.add_filter("Virtual Boy ROMs", &["vb", "vbrom"])
.pick_file();
@@ -77,33 +126,49 @@ impl GameWindow {
}
ui.close_menu();
}
if ui.button("Quit").clicked() {
if ui
.add(self.button_for(ui.ctx(), "Quit", Command::Quit))
.clicked()
{
let _ = self.proxy.send_event(UserEvent::Quit(self.sim_id));
}
});
ui.menu_button("Emulation", |ui| {
let state = self.client.emulator_state();
let is_ready = self.client.sim_state(self.sim_id) == SimState::Ready;
let can_pause = is_ready && state == EmulatorState::Running;
let can_resume = is_ready && state == EmulatorState::Paused;
let can_frame_advance = is_ready && state != EmulatorState::Debugging;
if state == EmulatorState::Running {
if ui.add_enabled(can_pause, Button::new("Pause")).clicked() {
if ui
.add_enabled(
can_pause,
self.button_for(ui.ctx(), "Pause", Command::PauseResume),
)
.clicked()
{
self.client.send_command(EmulatorCommand::Pause);
ui.close_menu();
}
} else if ui.add_enabled(can_resume, Button::new("Resume")).clicked() {
} else if ui
.add_enabled(
can_resume,
self.button_for(ui.ctx(), "Resume", Command::PauseResume),
)
.clicked()
{
self.client.send_command(EmulatorCommand::Resume);
ui.close_menu();
}
if ui.add_enabled(is_ready, Button::new("Reset")).clicked() {
if ui
.add_enabled(is_ready, self.button_for(ui.ctx(), "Reset", Command::Reset))
.clicked()
{
self.client
.send_command(EmulatorCommand::Reset(self.sim_id));
ui.close_menu();
}
ui.separator();
if ui
.add_enabled(can_frame_advance, Button::new("Frame Advance"))
.add_enabled(
can_frame_advance,
self.button_for(ui.ctx(), "Frame Advance", Command::FrameAdvance),
)
.clicked()
{
self.client.send_command(EmulatorCommand::FrameAdvance);
@@ -293,6 +358,10 @@ impl GameWindow {
ui.close_menu();
}
});
if ui.button("Key Shortcuts").clicked() {
self.proxy.send_event(UserEvent::OpenShortcuts).unwrap();
ui.close_menu();
}
}
fn show_color_picker(&mut self, ui: &mut Ui) {
@@ -334,6 +403,14 @@ impl GameWindow {
}
self.config = new_config;
}
fn button_for(&self, ctx: &Context, text: &str, command: Command) -> Button {
let button = Button::new(text);
match self.shortcuts.shortcut_for(command) {
Some(shortcut) => button.shortcut_text(ctx.format_shortcut(&shortcut)),
None => button,
}
}
}
fn config_filename(sim_id: SimId) -> &'static str {