raylib/core/
input.rs

1//! Keyboard, Controller, and Mouse related functions
2use raylib_sys::{GamepadButton, TraceLogLevel};
3
4use crate::consts::Gesture;
5use crate::core::math::Vector2;
6use crate::core::RaylibHandle;
7use crate::ffi;
8
9use std::ffi::c_char;
10use std::ffi::CStr;
11
12impl RaylibHandle {
13    /// Detect if a key has been pressed once.
14    #[inline]
15    pub fn is_key_pressed(&self, key: crate::consts::KeyboardKey) -> bool {
16        unsafe { ffi::IsKeyPressed((key as u32) as i32) }
17    }
18
19    /// Check if a key has been pressed again
20    #[inline]
21    pub fn is_key_pressed_repeat(&self, key: crate::consts::KeyboardKey) -> bool {
22        unsafe { ffi::IsKeyPressedRepeat((key as u32) as i32) }
23    }
24
25    /// Detect if a key is being pressed.
26    #[inline]
27    pub fn is_key_down(&self, key: crate::consts::KeyboardKey) -> bool {
28        unsafe { ffi::IsKeyDown((key as u32) as i32) }
29    }
30
31    /// Detect if a key has been released once.
32    #[inline]
33    pub fn is_key_released(&self, key: crate::consts::KeyboardKey) -> bool {
34        unsafe { ffi::IsKeyReleased((key as u32) as i32) }
35    }
36
37    /// Detect if a key is NOT being pressed.
38    #[inline]
39    pub fn is_key_up(&self, key: crate::consts::KeyboardKey) -> bool {
40        unsafe { ffi::IsKeyUp((key as u32) as i32) }
41    }
42
43    /// Gets latest key pressed.
44    #[inline]
45    pub fn get_key_pressed(&mut self) -> Option<crate::consts::KeyboardKey> {
46        let key = unsafe { ffi::GetKeyPressed() };
47        if key > 0 {
48            return key_from_i32(key);
49        }
50        None
51    }
52
53    /// Gets latest key pressed.
54    #[inline]
55    pub fn get_key_pressed_number(&mut self) -> Option<u32> {
56        let key = unsafe { ffi::GetKeyPressed() };
57        if key > 0 {
58            return Some(key as u32);
59        }
60        None
61    }
62
63    /// Gets latest char (unicode) pressed
64    #[inline]
65    pub fn get_char_pressed(&mut self) -> Option<char> {
66        let char_code = unsafe { ffi::GetCharPressed() };
67        if char_code > 0 {
68            return char::from_u32(char_code as u32);
69        }
70        None
71    }
72
73    /// Sets a custom key to exit program (default is ESC).
74    // #[inline]
75    pub fn set_exit_key(&mut self, key: Option<crate::consts::KeyboardKey>) {
76        unsafe {
77            match key {
78                Some(k) => ffi::SetExitKey((k as u32) as i32),
79                None => ffi::SetExitKey(0),
80            }
81        }
82    }
83
84    /// Detect if a gamepad is available.
85    #[inline]
86    pub fn is_gamepad_available(&self, gamepad: i32) -> bool {
87        unsafe { ffi::IsGamepadAvailable(gamepad) }
88    }
89
90    /// Returns gamepad internal name id.
91    #[inline]
92    pub fn get_gamepad_name(&self, gamepad: i32) -> Option<String> {
93        unsafe {
94            let name = ffi::GetGamepadName(gamepad);
95            match name.is_null() {
96                false => match CStr::from_ptr(name).to_str() {
97                    Ok(a) => Some(a.to_owned()),
98                    Err(err) => {
99                        self.trace_log(
100                            TraceLogLevel::LOG_WARNING,
101                            format!("Result of get_gamepad_name was not valid UTF-8; \"{}\". Returning None.",err).as_str(),
102                        );
103                        None
104                    }
105                },
106                true => None,
107            }
108        }
109    }
110
111    /// Detect if a gamepad button has been pressed once.
112    #[inline]
113    pub fn is_gamepad_button_pressed(
114        &self,
115        gamepad: i32,
116        button: crate::consts::GamepadButton,
117    ) -> bool {
118        unsafe { ffi::IsGamepadButtonPressed(gamepad, button as i32) }
119    }
120
121    /// Detect if a gamepad button is being pressed.
122    #[inline]
123    pub fn is_gamepad_button_down(
124        &self,
125        gamepad: i32,
126        button: crate::consts::GamepadButton,
127    ) -> bool {
128        unsafe { ffi::IsGamepadButtonDown(gamepad, button as i32) }
129    }
130
131    /// Detect if a gamepad button has been released once.
132    #[inline]
133    pub fn is_gamepad_button_released(
134        &self,
135        gamepad: i32,
136        button: crate::consts::GamepadButton,
137    ) -> bool {
138        unsafe { ffi::IsGamepadButtonReleased(gamepad, button as i32) }
139    }
140
141    /// Detect if a gamepad button is NOT being pressed.
142    #[inline]
143    pub fn is_gamepad_button_up(&self, gamepad: i32, button: crate::consts::GamepadButton) -> bool {
144        unsafe { ffi::IsGamepadButtonUp(gamepad, button as i32) }
145    }
146
147    /// Gets the last gamepad button pressed.
148    #[inline]
149    pub fn get_gamepad_button_pressed(&self) -> Option<crate::consts::GamepadButton> {
150        let button = unsafe { ffi::GetGamepadButtonPressed() };
151        if button != raylib_sys::GamepadButton::GAMEPAD_BUTTON_UNKNOWN as i32 {
152            return Some(unsafe { std::mem::transmute(button as u32) });
153        }
154        None
155    }
156
157    /// Returns gamepad axis count for a gamepad.
158    #[inline]
159    pub fn get_gamepad_axis_count(&self, gamepad: i32) -> i32 {
160        unsafe { ffi::GetGamepadAxisCount(gamepad) }
161    }
162
163    /// Returns axis movement value for a gamepad axis.
164    #[inline]
165    pub fn get_gamepad_axis_movement(&self, gamepad: i32, axis: crate::consts::GamepadAxis) -> f32 {
166        unsafe { ffi::GetGamepadAxisMovement(gamepad, axis as i32) }
167    }
168
169    /// Detect if a mouse button has been pressed once.
170    #[inline]
171    pub fn is_mouse_button_pressed(&self, button: crate::consts::MouseButton) -> bool {
172        unsafe { ffi::IsMouseButtonPressed(button as i32) }
173    }
174
175    /// Detect if a mouse button is being pressed.
176    #[inline]
177    pub fn is_mouse_button_down(&self, button: crate::consts::MouseButton) -> bool {
178        unsafe { ffi::IsMouseButtonDown(button as i32) }
179    }
180
181    /// Detect if a mouse button has been released once.
182    #[inline]
183    pub fn is_mouse_button_released(&self, button: crate::consts::MouseButton) -> bool {
184        unsafe { ffi::IsMouseButtonReleased(button as i32) }
185    }
186
187    /// Detect if a mouse button is NOT being pressed.
188    #[inline]
189    pub fn is_mouse_button_up(&self, button: crate::consts::MouseButton) -> bool {
190        unsafe { ffi::IsMouseButtonUp(button as i32) }
191    }
192
193    /// Returns mouse position X.
194    #[inline]
195    pub fn get_mouse_x(&self) -> i32 {
196        unsafe { ffi::GetMouseX() }
197    }
198
199    /// Returns mouse position Y.
200    #[inline]
201    pub fn get_mouse_y(&self) -> i32 {
202        unsafe { ffi::GetMouseY() }
203    }
204
205    /// Returns mouse position.
206    #[inline]
207    pub fn get_mouse_position(&self) -> Vector2 {
208        unsafe { ffi::GetMousePosition().into() }
209    }
210
211    /// Returns mouse delta between frames.
212    #[inline]
213    pub fn get_mouse_delta(&self) -> Vector2 {
214        unsafe { ffi::GetMouseDelta().into() }
215    }
216
217    /// Sets mouse position.
218    #[inline]
219    pub fn set_mouse_position(&mut self, position: impl Into<Vector2>) {
220        unsafe {
221            let Vector2 { x, y } = position.into();
222            ffi::SetMousePosition(x as i32, y as i32);
223        }
224    }
225
226    /// Sets mouse offset.
227    #[inline]
228    pub fn set_mouse_offset(&mut self, offset: impl Into<Vector2>) {
229        unsafe {
230            let Vector2 { x, y } = offset.into();
231            ffi::SetMouseOffset(x as i32, y as i32);
232        }
233    }
234
235    /// Sets mouse scaling.
236    #[inline]
237    pub fn set_mouse_scale(&mut self, scale_x: f32, scale_y: f32) {
238        unsafe {
239            ffi::SetMouseScale(scale_x, scale_y);
240        }
241    }
242
243    /// Get mouse wheel movement for X or Y, whichever is larger
244    #[inline]
245    pub fn get_mouse_wheel_move(&self) -> f32 {
246        unsafe { ffi::GetMouseWheelMove() }
247    }
248
249    /// Get mouse wheel movement for both X and Y
250    #[inline]
251    pub fn get_mouse_wheel_move_v(&self) -> raylib_sys::Vector2 {
252        unsafe { ffi::GetMouseWheelMoveV() }
253    }
254
255    /// Returns touch position X for touch point 0 (relative to screen size).
256    #[inline]
257    pub fn get_touch_x(&self) -> i32 {
258        unsafe { ffi::GetTouchX() }
259    }
260
261    /// Returns touch position Y for touch point 0 (relative to screen size).
262    #[inline]
263    pub fn get_touch_y(&self) -> i32 {
264        unsafe { ffi::GetTouchY() }
265    }
266
267    /// Returns touch position XY for a touch point index (relative to screen size).
268    #[inline]
269    pub fn get_touch_position(&self, index: u32) -> Vector2 {
270        unsafe { ffi::GetTouchPosition(index as i32).into() }
271    }
272
273    /// Enables a set of gestures using flags.
274    #[inline]
275    pub fn set_gestures_enabled(&self, gesture_flags: u32) {
276        unsafe {
277            ffi::SetGesturesEnabled(gesture_flags as u32);
278        }
279    }
280
281    /// Set internal gamepad mappings (SDL_GameControllerDB)
282    pub fn set_gamepad_mappings(&self, bind: &[c_char]) -> i32 {
283        unsafe { ffi::SetGamepadMappings(bind.as_ptr()) }
284    }
285
286    /// Set gamepad vibration for both motors
287    pub fn set_gamepad_vibration(
288        &mut self,
289        gamepad: i32,
290        left_motor: f32,
291        right_motor: f32,
292        duration: f32,
293    ) {
294        unsafe { ffi::SetGamepadVibration(gamepad, left_motor, right_motor, duration) }
295    }
296
297    /// Checks if a gesture have been detected.
298    #[inline]
299    pub fn is_gesture_detected(&self, gesture: Gesture) -> bool {
300        unsafe { ffi::IsGestureDetected(gesture as u32) }
301    }
302
303    /// Gets latest detected gesture.
304    #[inline]
305    pub fn get_gesture_detected(&self) -> Gesture {
306        unsafe { std::mem::transmute(ffi::GetGestureDetected()) }
307    }
308
309    /// Get touch point identifier for given index
310    #[inline]
311    pub fn get_touch_point_id(&self, index: u32) -> i32 {
312        unsafe { ffi::GetTouchPointId(index as i32) }
313    }
314
315    /// Gets touch points count.
316    #[inline]
317    pub fn get_touch_point_count(&self) -> u32 {
318        unsafe { ffi::GetTouchPointCount() as u32 }
319    }
320
321    /// Gets gesture hold time in milliseconds.
322    #[inline]
323    pub fn get_gesture_hold_duration(&self) -> f32 {
324        unsafe { ffi::GetGestureHoldDuration() }
325    }
326
327    /// Gets gesture drag vector.
328    #[inline]
329    pub fn get_gesture_drag_vector(&self) -> Vector2 {
330        unsafe { ffi::GetGestureDragVector().into() }
331    }
332
333    /// Gets gesture drag angle.
334    #[inline]
335    pub fn get_gesture_drag_angle(&self) -> f32 {
336        unsafe { ffi::GetGestureDragAngle() }
337    }
338
339    /// Gets gesture pinch delta.
340    #[inline]
341    pub fn get_gesture_pinch_vector(&self) -> Vector2 {
342        unsafe { ffi::GetGesturePinchVector().into() }
343    }
344
345    /// Gets gesture pinch angle.
346    #[inline]
347    pub fn get_gesture_pinch_angle(&self) -> f32 {
348        unsafe { ffi::GetGesturePinchAngle() }
349    }
350}
351
352pub fn key_from_i32(key: i32) -> Option<crate::consts::KeyboardKey> {
353    use crate::consts::KeyboardKey::*;
354    match key {
355        39 => Some(KEY_APOSTROPHE),
356        44 => Some(KEY_COMMA),
357        45 => Some(KEY_MINUS),
358        46 => Some(KEY_PERIOD),
359        47 => Some(KEY_SLASH),
360        48 => Some(KEY_ZERO),
361        49 => Some(KEY_ONE),
362        50 => Some(KEY_TWO),
363        51 => Some(KEY_THREE),
364        52 => Some(KEY_FOUR),
365        53 => Some(KEY_FIVE),
366        54 => Some(KEY_SIX),
367        55 => Some(KEY_SEVEN),
368        56 => Some(KEY_EIGHT),
369        57 => Some(KEY_NINE),
370        59 => Some(KEY_SEMICOLON),
371        61 => Some(KEY_EQUAL),
372        65 => Some(KEY_A),
373        66 => Some(KEY_B),
374        67 => Some(KEY_C),
375        68 => Some(KEY_D),
376        69 => Some(KEY_E),
377        70 => Some(KEY_F),
378        71 => Some(KEY_G),
379        72 => Some(KEY_H),
380        73 => Some(KEY_I),
381        74 => Some(KEY_J),
382        75 => Some(KEY_K),
383        76 => Some(KEY_L),
384        77 => Some(KEY_M),
385        78 => Some(KEY_N),
386        79 => Some(KEY_O),
387        80 => Some(KEY_P),
388        81 => Some(KEY_Q),
389        82 => Some(KEY_R),
390        83 => Some(KEY_S),
391        84 => Some(KEY_T),
392        85 => Some(KEY_U),
393        86 => Some(KEY_V),
394        87 => Some(KEY_W),
395        88 => Some(KEY_X),
396        89 => Some(KEY_Y),
397        90 => Some(KEY_Z),
398        32 => Some(KEY_SPACE),
399        256 => Some(KEY_ESCAPE),
400        257 => Some(KEY_ENTER),
401        258 => Some(KEY_TAB),
402        259 => Some(KEY_BACKSPACE),
403        260 => Some(KEY_INSERT),
404        261 => Some(KEY_DELETE),
405        262 => Some(KEY_RIGHT),
406        263 => Some(KEY_LEFT),
407        264 => Some(KEY_DOWN),
408        265 => Some(KEY_UP),
409        266 => Some(KEY_PAGE_UP),
410        267 => Some(KEY_PAGE_DOWN),
411        268 => Some(KEY_HOME),
412        269 => Some(KEY_END),
413        280 => Some(KEY_CAPS_LOCK),
414        281 => Some(KEY_SCROLL_LOCK),
415        282 => Some(KEY_NUM_LOCK),
416        283 => Some(KEY_PRINT_SCREEN),
417        284 => Some(KEY_PAUSE),
418        290 => Some(KEY_F1),
419        291 => Some(KEY_F2),
420        292 => Some(KEY_F3),
421        293 => Some(KEY_F4),
422        294 => Some(KEY_F5),
423        295 => Some(KEY_F6),
424        296 => Some(KEY_F7),
425        297 => Some(KEY_F8),
426        298 => Some(KEY_F9),
427        299 => Some(KEY_F10),
428        300 => Some(KEY_F11),
429        301 => Some(KEY_F12),
430        340 => Some(KEY_LEFT_SHIFT),
431        341 => Some(KEY_LEFT_CONTROL),
432        342 => Some(KEY_LEFT_ALT),
433        343 => Some(KEY_LEFT_SUPER),
434        344 => Some(KEY_RIGHT_SHIFT),
435        345 => Some(KEY_RIGHT_CONTROL),
436        346 => Some(KEY_RIGHT_ALT),
437        347 => Some(KEY_RIGHT_SUPER),
438        348 => Some(KEY_KB_MENU),
439        91 => Some(KEY_LEFT_BRACKET),
440        92 => Some(KEY_BACKSLASH),
441        93 => Some(KEY_RIGHT_BRACKET),
442        96 => Some(KEY_GRAVE),
443        320 => Some(KEY_KP_0),
444        321 => Some(KEY_KP_1),
445        322 => Some(KEY_KP_2),
446        323 => Some(KEY_KP_3),
447        324 => Some(KEY_KP_4),
448        325 => Some(KEY_KP_5),
449        326 => Some(KEY_KP_6),
450        327 => Some(KEY_KP_7),
451        328 => Some(KEY_KP_8),
452        329 => Some(KEY_KP_9),
453        330 => Some(KEY_KP_DECIMAL),
454        331 => Some(KEY_KP_DIVIDE),
455        332 => Some(KEY_KP_MULTIPLY),
456        333 => Some(KEY_KP_SUBTRACT),
457        334 => Some(KEY_KP_ADD),
458        335 => Some(KEY_KP_ENTER),
459        336 => Some(KEY_KP_EQUAL),
460        _ => None,
461    }
462}