shine_input/
mapping.rs

1use crate::{ButtonId, ModifierFilterMask, ModifierId};
2use std::collections::HashMap;
3
4#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
5pub enum InputMapping {
6    ScanCodeKey(winit::ScanCode),
7    VirtualKey(winit::VirtualKeyCode),
8    MouseAxis(u32),
9    MouseAxisWithDevice(winit::DeviceId, u32),
10    Gamepad(gilrs::ev::Axis),
11    GamepadWithDevice(gilrs::GamepadId, gilrs::ev::Axis),
12}
13
14pub struct Mapping {
15    axis_mapping: HashMap<InputMapping, (ButtonId, ModifierFilterMask, f32)>,
16    modifier_mapping: HashMap<InputMapping, ModifierId>,
17}
18
19impl Mapping {
20    pub fn new() -> Mapping {
21        Mapping {
22            axis_mapping: HashMap::new(),
23            modifier_mapping: HashMap::new(),
24        }
25    }
26
27    pub fn add_modifier_mapping(&mut self, input_event: InputMapping, modifier_id: ModifierId) {
28        if self.modifier_mapping.values().any(|m| *m == modifier_id) {
29            log::warn!("Multiple mapping for {:?}", modifier_id);
30        }
31        self.modifier_mapping.insert(input_event, modifier_id);
32    }
33
34    pub fn add_button_mapping(
35        &mut self,
36        input_event: InputMapping,
37        input_modifiers: Option<ModifierFilterMask>,
38        button_id: ButtonId,
39        sensitivity: f32,
40    ) {
41        if self.axis_mapping.values().any(|b| b.0 == button_id) {
42            log::warn!("Multiple mapping for {:?}", button_id);
43        }
44
45        let mask = input_modifiers.unwrap_or_default();
46        self.axis_mapping.insert(input_event, (button_id, mask, sensitivity));
47    }
48
49    pub fn map_winit_axis_to_modifier(&self, device_id: winit::DeviceId, axis: u32) -> Option<ModifierId> {
50        let mapping = &self.modifier_mapping;
51
52        if let Some(res) = mapping.get(&InputMapping::MouseAxisWithDevice(device_id.to_owned(), axis)) {
53            return Some(res.to_owned());
54        }
55
56        if let Some(res) = mapping.get(&InputMapping::MouseAxis(axis)) {
57            return Some(res.to_owned());
58        }
59
60        None
61    }
62
63    pub fn map_winit_key_to_modifier(&self, key_input: &winit::KeyboardInput) -> Option<ModifierId> {
64        let mapping = &self.modifier_mapping;
65
66        if let Some(res) = mapping.get(&InputMapping::ScanCodeKey(key_input.scancode)) {
67            return Some(res.to_owned());
68        }
69
70        if let Some(vk) = key_input.virtual_keycode {
71            if let Some(res) = mapping.get(&InputMapping::VirtualKey(vk)) {
72                return Some(res.to_owned());
73            }
74        }
75
76        None
77    }
78
79    pub fn map_winit_axis_to_button(&self, device_id: winit::DeviceId, axis: u32) -> Option<(ButtonId, ModifierFilterMask, f32)> {
80        let mapping = &self.axis_mapping;
81
82        if let Some(res) = mapping.get(&InputMapping::MouseAxisWithDevice(device_id.to_owned(), axis)) {
83            return Some(res.to_owned());
84        }
85
86        if let Some(res) = mapping.get(&InputMapping::MouseAxis(axis)) {
87            return Some(res.to_owned());
88        }
89
90        None
91    }
92
93    pub fn map_winit_key_to_button(&self, key_input: &winit::KeyboardInput) -> Option<(ButtonId, ModifierFilterMask, f32)> {
94        let mapping = &self.axis_mapping;
95
96        if let Some(res) = mapping.get(&InputMapping::ScanCodeKey(key_input.scancode)) {
97            return Some(res.to_owned());
98        }
99
100        if let Some(vk) = key_input.virtual_keycode {
101            if let Some(res) = mapping.get(&InputMapping::VirtualKey(vk)) {
102                return Some(res.to_owned());
103            }
104        }
105
106        None
107    }
108
109    pub fn map_gil_axis_to_modifier(&self, device_id: gilrs::GamepadId, axis: gilrs::ev::Axis) -> Option<ModifierId> {
110        let mapping = &self.modifier_mapping;
111
112        if let Some(res) = mapping.get(&InputMapping::GamepadWithDevice(device_id.to_owned(), axis.to_owned())) {
113            return Some(res.to_owned());
114        }
115
116        if let Some(res) = mapping.get(&InputMapping::Gamepad(axis.to_owned())) {
117            return Some(res.to_owned());
118        }
119
120        None
121    }
122
123    pub fn map_gil_axis_to_button(
124        &self,
125        device_id: gilrs::GamepadId,
126        axis: gilrs::ev::Axis,
127    ) -> Option<(ButtonId, ModifierFilterMask, f32)> {
128        let mapping = &self.axis_mapping;
129
130        if let Some(res) = mapping.get(&InputMapping::GamepadWithDevice(device_id.to_owned(), axis.to_owned())) {
131            return Some(res.to_owned());
132        }
133
134        if let Some(res) = mapping.get(&InputMapping::Gamepad(axis.to_owned())) {
135            return Some(res.to_owned());
136        }
137
138        None
139    }
140}