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#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
155pub enum AxisSign { Pos, Neg }
156#[cfg(feature = "gamepad")]
157pub use gamepad::*;
158#[cfg(feature = "gamepad")]
159mod gamepad {
160    use crate::InputCode;
161    use gilrs::{Axis, Button};
162    #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
163    pub enum GamepadInput {
164        LeftStickLeft,
165        /// the left stick, moved to the right
166        LeftStickRight,
167        LeftStickUp,
168        LeftStickDown,
169        LeftStickPress,
170
171        /// the right stick, moved to the left
172        RightStickLeft,
173        RightStickRight,
174        RightStickUp,
175        RightStickDown,
176        RightStickPress,
177
178        DPadLeft,
179        DPadRight,
180        DPadUp,
181        DPadDown,
182
183        LeftZ,
184        RightZ,
185
186        South,
187        East,
188        North,
189        West,
190
191        LeftTrigger,
192        LeftTrigger2,
193        RightTrigger,
194        RightTrigger2,
195
196        Select,
197        Start,
198        Mode,
199        /// unfortunately gilrs doesnt give enough infomation to have multiple 'Other' input binds
200        Other
201    }
202    impl GamepadInput {
203        pub fn with_id(self, id: gilrs::GamepadId) -> InputCode {
204            InputCode::Gamepad { id: SpecifyGamepad::Id(id), input: self }
205        }
206        pub fn with_sid(self, id: SpecifyGamepad) -> InputCode {
207            InputCode::Gamepad { id, input: self }
208        }
209    }
210    pub fn axis_neg(axis: Axis) -> GamepadInput {
211        match axis {
212            Axis::LeftStickX => GamepadInput::LeftStickRight,
213            Axis::LeftStickY => GamepadInput::LeftStickDown,
214            Axis::RightStickX => GamepadInput::RightStickRight,
215            Axis::RightStickY => GamepadInput::RightStickDown,
216            Axis::LeftZ => GamepadInput::LeftZ,
217            Axis::RightZ => GamepadInput::RightZ,
218            Axis::DPadX => GamepadInput::DPadRight,
219            Axis::DPadY => GamepadInput::DPadDown,
220            Axis::Unknown => GamepadInput::Other
221        }
222    }
223    pub fn axis_pos(axis: Axis) -> GamepadInput {
224        match axis {
225            Axis::LeftStickX => GamepadInput::LeftStickLeft,
226            Axis::LeftStickY => GamepadInput::LeftStickUp,
227            Axis::RightStickX => GamepadInput::RightStickLeft,
228            Axis::RightStickY => GamepadInput::RightStickUp,
229            Axis::LeftZ => GamepadInput::LeftZ,
230            Axis::RightZ => GamepadInput::RightZ,
231            Axis::DPadX => GamepadInput::DPadLeft,
232            Axis::DPadY => GamepadInput::DPadUp,
233            Axis::Unknown => GamepadInput::Other,
234        }
235    }
236    impl From<Button> for GamepadInput {
237        fn from(value: Button) -> Self {
238            match value {
239                Button::South => GamepadInput::South,
240                Button::East => GamepadInput::East,
241                Button::North => GamepadInput::North,
242                Button::West => GamepadInput::West,
243                Button::LeftTrigger => GamepadInput::LeftTrigger,
244                Button::LeftTrigger2 => GamepadInput::LeftTrigger2,
245                Button::RightTrigger2 => GamepadInput::RightTrigger2,
246                Button::RightTrigger => GamepadInput::RightTrigger,
247                Button::DPadUp => GamepadInput::DPadUp,
248                Button::DPadDown => GamepadInput::DPadDown,
249                Button::DPadLeft => GamepadInput::DPadLeft,
250                Button::DPadRight => GamepadInput::DPadRight,
251                Button::Z => GamepadInput::RightZ,
252                Button::C => GamepadInput::LeftZ,
253                Button::Select => GamepadInput::Select,
254                Button::Start => GamepadInput::Start,
255                Button::Mode => GamepadInput::Mode,
256                Button::RightThumb => GamepadInput::RightStickPress,
257                Button::LeftThumb  => GamepadInput::LeftStickPress,
258                Button::Unknown => GamepadInput::Other 
259            }
260        }
261    }
262    impl From<GamepadInput> for InputCode {
263        fn from(value: GamepadInput) -> InputCode {
264            Self::Gamepad { input: value, id: Default::default() }
265        }
266    }
267    /// Specify gamepad to listen to. defaults to any and can be specified later on at runtime
268    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Hash)]
269    pub enum SpecifyGamepad {
270        /// cant be set at compile time. use `Any` as default and then let the user select a specific
271        /// gamepad at runtime
272        Id(gilrs::GamepadId),
273        /// use as default
274        #[default]
275        Any
276    }
277}