Add bindable keyboard shortcuts
This commit is contained in:
+88
-11
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user