winit_input_map/
input_code.rs

1#[cfg(feature = "mice-keyboard")]
2use winit::keyboard::{ KeyCode, PhysicalKey };
3#[cfg(feature = "mice-keyboard")]
4use winit::event::*;
5#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
6/// Enum that specifies an input
7pub enum InputCode {
8    #[cfg(feature = "mice-keyboard")]
9    Device { id: SpecifyDevice, input: DeviceInput },
10    #[cfg(feature = "gamepad")]
11    Gamepad { id: SpecifyGamepad, input: GamepadInput }
12}
13impl InputCode {
14    /// sets `SpecifyGamepad` or `SpecifyDevice` to any
15    pub fn set_any(self) -> Self {
16        match self {
17            #[cfg(feature = "gamepad")]
18            Self::Gamepad { input, .. } => input.into(),
19            #[cfg(feature = "mice-keyboard")]
20            Self::Device  { input, .. } => input.into(),
21        }
22    }
23    pub fn is_any(self) -> bool {
24        match self {
25            #[cfg(feature = "gamepad")]
26            Self::Gamepad { id, .. } => id == SpecifyGamepad::Any,
27            #[cfg(feature = "mice-keyboard")]
28            Self::Device  { id, .. } => id == SpecifyDevice::Any,
29        }
30    }
31    #[cfg(feature = "mice-keyboard")]
32    pub fn has_device_id(&self, id: DeviceId) -> bool {
33        match self {
34            Self::Device { id: SpecifyDevice::Id(cid), .. } => *cid == id,
35            Self::Device { id: SpecifyDevice::Any,     .. } => true,
36            _ => false
37        }
38    }
39    #[cfg(feature = "gamepad")]
40    pub fn has_gamepad_id(&self, id: gilrs::GamepadId) -> bool {
41        match self {
42            Self::Gamepad { id: SpecifyGamepad::Id(cid), .. } => *cid == id,
43            Self::Gamepad { id: SpecifyGamepad::Any,     .. } => true,
44            _ => false
45        }
46    }
47    #[cfg(feature = "gamepad")]
48    #[allow(irrefutable_let_patterns)]
49    /// sets the gamepad id. if its a device it does nothing.
50    pub fn set_gamepad_id(self, id: gilrs::GamepadId) -> Self {
51        if let Self::Gamepad { input, .. } = self { input.with_id(id) }
52        else { self }
53    }
54    #[cfg(feature = "mice-keyboard")]
55    #[allow(irrefutable_let_patterns)]
56    /// sets the device id. if its a gamepad it does nothing.
57    pub fn set_device_id(self, id: DeviceId) -> Self {
58        if let Self::Device { input, .. } = self { input.with_id(id) }
59        else { self }
60    }
61}
62#[cfg(feature = "mice-keyboard")]
63impl From<DeviceInput> for InputCode {
64    fn from(value: DeviceInput) -> Self {
65        Self::Device { id: SpecifyDevice::Any, input: value }
66    }
67}
68#[cfg(feature = "mice-keyboard")]
69impl From<MouseButton> for InputCode {
70    fn from(value: MouseButton) -> Self {
71        Self::Device { id: SpecifyDevice::Any, input: value.into() }
72    }
73}
74#[cfg(feature = "mice-keyboard")]
75impl From<PhysicalKey> for InputCode {
76    fn from(value: PhysicalKey) -> Self {
77        Self::Device { id: SpecifyDevice::Any, input: value.into() }
78    }
79}
80#[cfg(feature = "mice-keyboard")]
81impl From<KeyCode> for InputCode {
82    fn from(value: KeyCode) -> Self {
83        Self::Device { id: SpecifyDevice::Any, input: value.into() }
84    }
85}
86/// imports everything needed to reduce boilerplate when creating an input_map
87pub mod base_input_codes {
88    #![allow(ambiguous_glob_reexports)]
89    use crate::input_code::*;
90
91    #[cfg(feature = "gamepad")]
92    pub use GamepadInput::*;
93    #[cfg(feature = "mice-keyboard")]
94    pub use DeviceInput::*;
95
96    #[cfg(feature = "mice-keyboard")]
97    pub use winit::{
98        keyboard::{KeyCode::*, PhysicalKey::*},
99        event::MouseButton
100    };
101}
102#[cfg(feature = "mice-keyboard")]
103#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
104pub enum DeviceInput {
105    Button(MouseButton),
106    Key(PhysicalKey),
107    MouseMoveLeft,
108    MouseMoveRight,
109    MouseMoveUp,
110    MouseMoveDown,
111    MouseScrollUp,
112    MouseScrollDown,
113    MouseScrollLeft,
114    MouseScrollRight,
115}
116#[cfg(feature = "mice-keyboard")]
117impl DeviceInput {
118    pub fn with_id(self, id: DeviceId) -> InputCode {
119        InputCode::Device { id: SpecifyDevice::Id(id), input: self }
120    }
121    pub fn with_sid(self, id: SpecifyDevice) -> InputCode {
122        InputCode::Device { id, input: self }
123    }
124}
125#[cfg(feature = "mice-keyboard")]
126impl From<MouseButton> for DeviceInput {
127    fn from(value: MouseButton) -> Self {
128        Self::Button(value) 
129    }
130}
131#[cfg(feature = "mice-keyboard")]
132impl From<KeyCode> for DeviceInput {
133    fn from(value: KeyCode) -> Self {
134        Self::Key(value.into()) 
135    }
136}
137#[cfg(feature = "mice-keyboard")]
138impl From<PhysicalKey> for DeviceInput {
139    fn from(value: PhysicalKey) -> Self {
140        Self::Key(value)
141    }
142}
143/// specify device to listen to. defaults to any and can be specified later on at runtime
144#[cfg(feature = "mice-keyboard")]
145#[derive(Default, Debug, PartialEq, Eq, Clone, Copy, Hash)]
146pub enum SpecifyDevice {
147    /// cant be set at compile time. use `Any` as default and then let the user select a specific
148    /// gamepad at runtime
149    Id(DeviceId),
150    /// use as default
151    #[default]
152    Any
153}
154#[cfg(feature = "gamepad")]
155pub use gamepad::*;
156#[cfg(feature = "gamepad")]
157mod gamepad {
158    use crate::InputCode;
159    use gilrs::{Axis, Button};
160    #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
161    pub enum GamepadInput {
162        LeftStickLeft,
163        /// the left stick, moved to the right
164        LeftStickRight,
165        LeftStickUp,
166        LeftStickDown,
167        LeftStickPress,
168
169        /// the right stick, moved to the left
170        RightStickLeft,
171        RightStickRight,
172        RightStickUp,
173        RightStickDown,
174        RightStickPress,
175
176        DPadLeft,
177        DPadRight,
178        DPadUp,
179        DPadDown,
180
181        LeftZ,
182        RightZ,
183
184        South,
185        East,
186        North,
187        West,
188
189        LeftBumper,
190        LeftTrigger,
191        RightBumper,
192        RightTrigger,
193
194        Select,
195        Start,
196        Mode,
197        /// unfortunately gilrs doesnt give enough infomation to have multiple 'Other' input binds
198        Other
199    }
200    impl GamepadInput {
201        pub fn with_id(self, id: gilrs::GamepadId) -> InputCode {
202            InputCode::Gamepad { id: SpecifyGamepad::Id(id), input: self }
203        }
204        pub fn with_sid(self, id: SpecifyGamepad) -> InputCode {
205            InputCode::Gamepad { id, input: self }
206        }
207    }
208    pub fn axis_neg(axis: Axis) -> GamepadInput {
209        match axis {
210            Axis::LeftStickX => GamepadInput::LeftStickLeft,
211            Axis::LeftStickY => GamepadInput::LeftStickDown,
212            Axis::RightStickX => GamepadInput::RightStickLeft,
213            Axis::RightStickY => GamepadInput::RightStickDown,
214            Axis::LeftZ => GamepadInput::LeftZ,
215            Axis::RightZ => GamepadInput::RightZ,
216            Axis::DPadX => GamepadInput::DPadLeft,
217            Axis::DPadY => GamepadInput::DPadDown,
218            Axis::Unknown => GamepadInput::Other
219        }
220    }
221    pub fn axis_pos(axis: Axis) -> GamepadInput {
222        match axis {
223            Axis::LeftStickX => GamepadInput::LeftStickRight,
224            Axis::LeftStickY => GamepadInput::LeftStickUp,
225            Axis::RightStickX => GamepadInput::RightStickRight,
226            Axis::RightStickY => GamepadInput::RightStickUp,
227            Axis::LeftZ => GamepadInput::LeftZ,
228            Axis::RightZ => GamepadInput::RightZ,
229            Axis::DPadX => GamepadInput::DPadRight,
230            Axis::DPadY => GamepadInput::DPadUp,
231            Axis::Unknown => GamepadInput::Other,
232        }
233    }
234    impl From<Button> for GamepadInput {
235        fn from(value: Button) -> Self {
236            match value {
237                Button::South => GamepadInput::South,
238                Button::East => GamepadInput::East,
239                Button::North => GamepadInput::North,
240                Button::West => GamepadInput::West,
241                Button::LeftTrigger => GamepadInput::LeftBumper,
242                Button::LeftTrigger2 => GamepadInput::LeftTrigger,
243                Button::RightTrigger2 => GamepadInput::RightTrigger,
244                Button::RightTrigger => GamepadInput::RightBumper,
245                Button::DPadUp => GamepadInput::DPadUp,
246                Button::DPadDown => GamepadInput::DPadDown,
247                Button::DPadLeft => GamepadInput::DPadLeft,
248                Button::DPadRight => GamepadInput::DPadRight,
249                Button::Z => GamepadInput::RightZ,
250                Button::C => GamepadInput::LeftZ,
251                Button::Select => GamepadInput::Select,
252                Button::Start => GamepadInput::Start,
253                Button::Mode => GamepadInput::Mode,
254                Button::RightThumb => GamepadInput::RightStickPress,
255                Button::LeftThumb  => GamepadInput::LeftStickPress,
256                Button::Unknown => GamepadInput::Other 
257            }
258        }
259    }
260    impl From<GamepadInput> for InputCode {
261        fn from(value: GamepadInput) -> InputCode {
262            Self::Gamepad { input: value, id: Default::default() }
263        }
264    }
265    /// Specify gamepad to listen to. defaults to any and can be specified later on at runtime
266    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Hash)]
267    pub enum SpecifyGamepad {
268        /// cant be set at compile time. use `Any` as default and then let the user select a specific
269        /// gamepad at runtime
270        Id(gilrs::GamepadId),
271        /// use as default
272        #[default]
273        Any
274    }
275}