From 11fd29c9c60ada37837e5ad800449bf42dcd81ca Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Thu, 3 Apr 2025 14:25:00 +0200 Subject: [PATCH] show input conflicts in binding menu --- src/input.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/input.rs b/src/input.rs index fb5cb22..d15dd18 100644 --- a/src/input.rs +++ b/src/input.rs @@ -140,6 +140,17 @@ impl Input { let x = binding_text_x + 10 + d.measure_text(&trigger, 20); let modifiers = format!("{:?}", binding.modifiers); d.draw_text(&modifiers, x, y + 5, 20, Color::LIGHTBLUE); + let conflicts = conflicts(&self.bindings, binding, action); + if !conflicts.is_empty() { + let x = x + 10 + d.measure_text(&modifiers, 20); + d.draw_text( + &format!("also used by: {conflicts:?}"), + x, + y + 5, + 20, + Color::ORANGERED, + ); + } y += 32; } if text_button(d, &globals.mouse, buttons_x, y, 130, "add binding") { @@ -151,15 +162,15 @@ impl Input { if let Some((action, binding_index, edit_state)) = &mut self.editing_binding { globals.mouse.update(d); - let border = screen_centered_rect(d, 368, 128); + let border = screen_centered_rect(d, 408, 128); d.draw_rectangle_rec(border, BG_LIGHT); - let bounds = screen_centered_rect(d, 360, 120); + let bounds = screen_centered_rect(d, 400, 120); d.draw_rectangle_rec(bounds, BG_DARK); let x = bounds.x as i32; let y = bounds.y as i32; d.draw_text( &format!("editing binding for {action:?}"), - x + 5, + x + 10, y + 5, 20, Color::WHITE, @@ -217,6 +228,17 @@ impl Input { }; let text = format!("{:?} + {:?}", b.modifiers, b.trigger); d.draw_text(&text, x + 5, y + 5, 20, colour); + + let conflicts = conflicts(&self.bindings, b, *action); + if !conflicts.is_empty() { + d.draw_text( + &format!("conflicts: {conflicts:?}"), + x + 200, + y + 40, + 20, + Color::ORANGERED, + ); + } } if text_button(d, &globals.mouse, ok_btn_x, ok_btn_y, ok_btn_width, "ok") { if let BindingEdit::Releasing(binding) = edit_state { @@ -273,6 +295,29 @@ impl Input { } } +fn conflicts( + bindings: &[Vec; ActionId::SIZE], + search: &Binding, + skip: ActionId, +) -> Vec { + let mut matches = Vec::new(); + + for i in 0..ActionId::SIZE { + if skip as usize == i { + continue; + } + let bindings = &bindings[i]; + for binding in bindings { + if binding == search { + matches.push(ActionId::from_usize(i).unwrap()); + break; + } + } + } + + matches +} + impl ActionId { pub const SIZE: usize = Self::_EnumSize as usize; @@ -285,7 +330,7 @@ impl ActionId { } } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct Binding { modifiers: Vec