Out with dear imgui, in with egui
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
use egui::{
|
||||
Button, CentralPanel, Context, Label, Layout, TopBottomPanel, Ui, ViewportBuilder, ViewportId,
|
||||
};
|
||||
use egui_extras::{Column, TableBuilder};
|
||||
|
||||
use crate::{
|
||||
emulator::{SimId, VBKey},
|
||||
input::MappingProvider,
|
||||
};
|
||||
|
||||
use super::AppWindow;
|
||||
|
||||
pub struct InputWindow {
|
||||
mappings: MappingProvider,
|
||||
now_binding: Option<(SimId, VBKey)>,
|
||||
active_tab: InputTab,
|
||||
}
|
||||
|
||||
const KEY_NAMES: [(VBKey, &str); 14] = [
|
||||
(VBKey::LU, "Up"),
|
||||
(VBKey::LD, "Down"),
|
||||
(VBKey::LL, "Left"),
|
||||
(VBKey::LR, "Right"),
|
||||
(VBKey::SEL, "Select"),
|
||||
(VBKey::STA, "Start"),
|
||||
(VBKey::B, "B"),
|
||||
(VBKey::A, "A"),
|
||||
(VBKey::LT, "L-Trigger"),
|
||||
(VBKey::RT, "R-Trigger"),
|
||||
(VBKey::RU, "R-Up"),
|
||||
(VBKey::RD, "R-Down"),
|
||||
(VBKey::RL, "R-Left"),
|
||||
(VBKey::RR, "R-Right"),
|
||||
];
|
||||
|
||||
impl InputWindow {
|
||||
pub fn new(mappings: MappingProvider) -> Self {
|
||||
Self {
|
||||
mappings,
|
||||
now_binding: None,
|
||||
active_tab: InputTab::Player1,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_key_bindings(&mut self, ui: &mut Ui, sim_id: SimId) {
|
||||
let mappings = self.mappings.for_sim(sim_id);
|
||||
let binding_names = {
|
||||
let mapping = mappings.read().unwrap();
|
||||
mapping.keyboard_mapping_names()
|
||||
};
|
||||
TableBuilder::new(ui)
|
||||
.column(Column::remainder())
|
||||
.column(Column::remainder())
|
||||
.cell_layout(Layout::left_to_right(egui::Align::Center))
|
||||
.body(|mut body| {
|
||||
for keys in KEY_NAMES.chunks_exact(2) {
|
||||
body.row(20.0, |mut row| {
|
||||
for (key, name) in keys {
|
||||
let binding = binding_names.get(key).map(|s| s.as_str());
|
||||
row.col(|ui| {
|
||||
let size = ui.available_size_before_wrap();
|
||||
let width = size.x;
|
||||
let height = size.y;
|
||||
ui.add_sized((width * 0.2, height), Label::new(*name));
|
||||
let label_text = if self.now_binding == Some((sim_id, *key)) {
|
||||
"Press any input"
|
||||
} else {
|
||||
binding.unwrap_or("")
|
||||
};
|
||||
if ui
|
||||
.add_sized((width * 0.6, height), Button::new(label_text))
|
||||
.clicked()
|
||||
{
|
||||
self.now_binding = Some((sim_id, *key))
|
||||
}
|
||||
if ui
|
||||
.add_sized(ui.available_size(), Button::new("Clear"))
|
||||
.clicked()
|
||||
{
|
||||
let mut mapping = mappings.write().unwrap();
|
||||
mapping.clear_keyboard_mappings(*key);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl AppWindow for InputWindow {
|
||||
fn viewport_id(&self) -> ViewportId {
|
||||
ViewportId::from_hash_of("input")
|
||||
}
|
||||
|
||||
fn initial_viewport(&self) -> ViewportBuilder {
|
||||
ViewportBuilder::default()
|
||||
.with_title("Bind Inputs")
|
||||
.with_inner_size((600.0, 400.0))
|
||||
}
|
||||
|
||||
fn show(&mut self, ctx: &Context) {
|
||||
TopBottomPanel::top("options").show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.selectable_value(&mut self.active_tab, InputTab::Player1, "Player 1");
|
||||
ui.selectable_value(&mut self.active_tab, InputTab::Player2, "Player 2");
|
||||
});
|
||||
});
|
||||
CentralPanel::default().show(ctx, |ui| {
|
||||
match self.active_tab {
|
||||
InputTab::Player1 => self.render_key_bindings(ui, SimId::Player1),
|
||||
InputTab::Player2 => self.render_key_bindings(ui, SimId::Player2),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_key_event(&mut self, event: &winit::event::KeyEvent) {
|
||||
if !event.state.is_pressed() {
|
||||
return;
|
||||
}
|
||||
let Some((sim_id, vb)) = self.now_binding.take() else {
|
||||
return;
|
||||
};
|
||||
let mut mappings = self.mappings.for_sim(sim_id).write().unwrap();
|
||||
mappings.add_keyboard_mapping(vb, event.physical_key);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
enum InputTab {
|
||||
Player1,
|
||||
Player2,
|
||||
}
|
||||
Reference in New Issue
Block a user