| 70 | _ => None, |
| 71 | }) |
| 72 | }) |
| 73 | && let Ok(mut bindings) = self.key_bindings.lock() |
| 74 | { |
| 75 | bindings.retain(|(b, _)| *b != button); |
| 76 | bindings.push((button, new_key)); |
| 77 | self.rebinding = None; |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | const fn is_pressed(key_input: u16, button: GbaButton) -> bool { |
| 82 | (key_input & (button as u16)) == 0 |
| 83 | } |
| 84 | |
| 85 | /// Compact button: small square with single char or short label. |
| 86 | fn btn(&self, ui: &mut egui::Ui, label: &str, button: GbaButton, key_input: u16) { |
| 87 | let pressed = Self::is_pressed(key_input, button); |
| 88 | let text = egui::RichText::new(label).small().color(if pressed { |
| 89 | egui::Color32::WHITE |
| 90 | } else { |
| 91 | egui::Color32::GRAY |
| 92 | }); |
| 93 | |
| 94 | let bg = if pressed { |
| 95 | egui::Color32::from_rgb(0, 120, 215) |
| 96 | } else { |
| 97 | egui::Color32::from_rgb(50, 50, 50) |
| 98 | }; |
| 99 | |
| 100 | if ui |
| 101 | .add( |
| 102 | egui::Button::new(text) |
| 103 | .fill(bg) |
| 104 | .min_size(egui::vec2(24.0, 18.0)), |
| 105 | ) |
| 106 | .clicked() |
| 107 | && let Ok(mut handle) = self.emu_handle.lock() |
| 108 | { |
| 109 | handle.send(EmuCommand::SetKey { |
| 110 | button, |
| 111 | pressed: !pressed, |
| 112 | }); |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | impl UiTool for KeypadDebug { |
| 118 | fn name(&self) -> &'static str { |
| 119 | "Keypad Debug" |
| 120 | } |
| 121 | |
| 122 | fn show(&mut self, ctx: &egui::Context, open: &mut bool) { |
| 123 | egui::Window::new(self.name()) |
| 124 | .default_width(120.0) |
| 125 | .open(open) |
| 126 | .default_pos(egui::pos2(1800.0 - 600.0, 520.0)) |
| 127 | .show(ctx, |ui| { |
| 128 | self.ui(ui); |
| 129 | }); |