dear_imgui_rs/
input.rs

1//! Input types (mouse, keyboard, cursors)
2//!
3//! Strongly-typed identifiers for mouse buttons, mouse cursors and keyboard
4//! keys used by Dear ImGui. Backends typically translate platform events into
5//! these enums when feeding input into `Io`.
6//!
7//! See [`io`] for the per-frame input state and configuration.
8//!
9#![allow(
10    clippy::cast_possible_truncation,
11    clippy::cast_sign_loss,
12    clippy::as_conversions
13)]
14use crate::sys;
15use bitflags::bitflags;
16#[cfg(feature = "serde")]
17use serde::{Deserialize, Serialize};
18
19/// Mouse button identifier
20#[repr(i32)]
21#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
22#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23pub enum MouseButton {
24    /// Left mouse button
25    Left = sys::ImGuiMouseButton_Left as i32,
26    /// Right mouse button
27    Right = sys::ImGuiMouseButton_Right as i32,
28    /// Middle mouse button
29    Middle = sys::ImGuiMouseButton_Middle as i32,
30    /// Extra mouse button 1 (typically Back)
31    Extra1 = 3,
32    /// Extra mouse button 2 (typically Forward)
33    Extra2 = 4,
34}
35
36/// Mouse cursor types
37#[repr(i32)]
38#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub enum MouseCursor {
41    /// No cursor
42    None = sys::ImGuiMouseCursor_None,
43    /// Arrow cursor
44    Arrow = sys::ImGuiMouseCursor_Arrow,
45    /// Text input I-beam cursor
46    TextInput = sys::ImGuiMouseCursor_TextInput,
47    /// Resize all directions cursor
48    ResizeAll = sys::ImGuiMouseCursor_ResizeAll,
49    /// Resize north-south cursor
50    ResizeNS = sys::ImGuiMouseCursor_ResizeNS,
51    /// Resize east-west cursor
52    ResizeEW = sys::ImGuiMouseCursor_ResizeEW,
53    /// Resize northeast-southwest cursor
54    ResizeNESW = sys::ImGuiMouseCursor_ResizeNESW,
55    /// Resize northwest-southeast cursor
56    ResizeNWSE = sys::ImGuiMouseCursor_ResizeNWSE,
57    /// Hand cursor
58    Hand = sys::ImGuiMouseCursor_Hand,
59    /// Not allowed cursor
60    NotAllowed = sys::ImGuiMouseCursor_NotAllowed,
61}
62
63/// Source of mouse-like input events.
64///
65/// Backends can use this to mark whether a mouse event originates from a
66/// physical mouse, a touch screen, or a pen/stylus so Dear ImGui can
67/// correctly handle multiple input sources.
68#[repr(i32)]
69#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
70#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
71pub enum MouseSource {
72    /// Events coming from a physical mouse
73    Mouse = sys::ImGuiMouseSource_Mouse as i32,
74    /// Events coming from a touch screen
75    TouchScreen = sys::ImGuiMouseSource_TouchScreen as i32,
76    /// Events coming from a pen or stylus
77    Pen = sys::ImGuiMouseSource_Pen as i32,
78}
79
80/// Key identifier for keyboard input
81#[repr(i32)]
82#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
83#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
84pub enum Key {
85    /// No key
86    None = sys::ImGuiKey_None as i32,
87    /// Tab key
88    Tab = sys::ImGuiKey_Tab as i32,
89    /// Left arrow key
90    LeftArrow = sys::ImGuiKey_LeftArrow as i32,
91    /// Right arrow key
92    RightArrow = sys::ImGuiKey_RightArrow as i32,
93    /// Up arrow key
94    UpArrow = sys::ImGuiKey_UpArrow as i32,
95    /// Down arrow key
96    DownArrow = sys::ImGuiKey_DownArrow as i32,
97    /// Page up key
98    PageUp = sys::ImGuiKey_PageUp as i32,
99    /// Page down key
100    PageDown = sys::ImGuiKey_PageDown as i32,
101    /// Home key
102    Home = sys::ImGuiKey_Home as i32,
103    /// End key
104    End = sys::ImGuiKey_End as i32,
105    /// Insert key
106    Insert = sys::ImGuiKey_Insert as i32,
107    /// Delete key
108    Delete = sys::ImGuiKey_Delete as i32,
109    /// Backspace key
110    Backspace = sys::ImGuiKey_Backspace as i32,
111    /// Space key
112    Space = sys::ImGuiKey_Space as i32,
113    /// Enter key
114    Enter = sys::ImGuiKey_Enter as i32,
115    /// Escape key
116    Escape = sys::ImGuiKey_Escape as i32,
117    /// Left Ctrl key
118    LeftCtrl = sys::ImGuiKey_LeftCtrl as i32,
119    /// Left Shift key
120    LeftShift = sys::ImGuiKey_LeftShift as i32,
121    /// Left Alt key
122    LeftAlt = sys::ImGuiKey_LeftAlt as i32,
123    /// Left Super key
124    LeftSuper = sys::ImGuiKey_LeftSuper as i32,
125    /// Right Ctrl key
126    RightCtrl = sys::ImGuiKey_RightCtrl as i32,
127    /// Right Shift key
128    RightShift = sys::ImGuiKey_RightShift as i32,
129    /// Right Alt key
130    RightAlt = sys::ImGuiKey_RightAlt as i32,
131    /// Right Super key
132    RightSuper = sys::ImGuiKey_RightSuper as i32,
133    /// Menu key
134    Menu = sys::ImGuiKey_Menu as i32,
135    /// 0 key
136    Key0 = sys::ImGuiKey_0 as i32,
137    /// 1 key
138    Key1 = sys::ImGuiKey_1 as i32,
139    /// 2 key
140    Key2 = sys::ImGuiKey_2 as i32,
141    /// 3 key
142    Key3 = sys::ImGuiKey_3 as i32,
143    /// 4 key
144    Key4 = sys::ImGuiKey_4 as i32,
145    /// 5 key
146    Key5 = sys::ImGuiKey_5 as i32,
147    /// 6 key
148    Key6 = sys::ImGuiKey_6 as i32,
149    /// 7 key
150    Key7 = sys::ImGuiKey_7 as i32,
151    /// 8 key
152    Key8 = sys::ImGuiKey_8 as i32,
153    /// 9 key
154    Key9 = sys::ImGuiKey_9 as i32,
155    /// A key
156    A = sys::ImGuiKey_A as i32,
157    /// B key
158    B = sys::ImGuiKey_B as i32,
159    /// C key
160    C = sys::ImGuiKey_C as i32,
161    /// D key
162    D = sys::ImGuiKey_D as i32,
163    /// E key
164    E = sys::ImGuiKey_E as i32,
165    /// F key
166    F = sys::ImGuiKey_F as i32,
167    /// G key
168    G = sys::ImGuiKey_G as i32,
169    /// H key
170    H = sys::ImGuiKey_H as i32,
171    /// I key
172    I = sys::ImGuiKey_I as i32,
173    /// J key
174    J = sys::ImGuiKey_J as i32,
175    /// K key
176    K = sys::ImGuiKey_K as i32,
177    /// L key
178    L = sys::ImGuiKey_L as i32,
179    /// M key
180    M = sys::ImGuiKey_M as i32,
181    /// N key
182    N = sys::ImGuiKey_N as i32,
183    /// O key
184    O = sys::ImGuiKey_O as i32,
185    /// P key
186    P = sys::ImGuiKey_P as i32,
187    /// Q key
188    Q = sys::ImGuiKey_Q as i32,
189    /// R key
190    R = sys::ImGuiKey_R as i32,
191    /// S key
192    S = sys::ImGuiKey_S as i32,
193    /// T key
194    T = sys::ImGuiKey_T as i32,
195    /// U key
196    U = sys::ImGuiKey_U as i32,
197    /// V key
198    V = sys::ImGuiKey_V as i32,
199    /// W key
200    W = sys::ImGuiKey_W as i32,
201    /// X key
202    X = sys::ImGuiKey_X as i32,
203    /// Y key
204    Y = sys::ImGuiKey_Y as i32,
205    /// Z key
206    Z = sys::ImGuiKey_Z as i32,
207    /// F1 key
208    F1 = sys::ImGuiKey_F1 as i32,
209    /// F2 key
210    F2 = sys::ImGuiKey_F2 as i32,
211    /// F3 key
212    F3 = sys::ImGuiKey_F3 as i32,
213    /// F4 key
214    F4 = sys::ImGuiKey_F4 as i32,
215    /// F5 key
216    F5 = sys::ImGuiKey_F5 as i32,
217    /// F6 key
218    F6 = sys::ImGuiKey_F6 as i32,
219    /// F7 key
220    F7 = sys::ImGuiKey_F7 as i32,
221    /// F8 key
222    F8 = sys::ImGuiKey_F8 as i32,
223    /// F9 key
224    F9 = sys::ImGuiKey_F9 as i32,
225    /// F10 key
226    F10 = sys::ImGuiKey_F10 as i32,
227    /// F11 key
228    F11 = sys::ImGuiKey_F11 as i32,
229    /// F12 key
230    F12 = sys::ImGuiKey_F12 as i32,
231
232    // --- Punctuation and extra named keys ---
233    /// Apostrophe (') key
234    Apostrophe = sys::ImGuiKey_Apostrophe as i32,
235    /// Comma (,) key
236    Comma = sys::ImGuiKey_Comma as i32,
237    /// Minus (-) key
238    Minus = sys::ImGuiKey_Minus as i32,
239    /// Period (.) key
240    Period = sys::ImGuiKey_Period as i32,
241    /// Slash (/) key
242    Slash = sys::ImGuiKey_Slash as i32,
243    /// Semicolon (;) key
244    Semicolon = sys::ImGuiKey_Semicolon as i32,
245    /// Equal (=) key
246    Equal = sys::ImGuiKey_Equal as i32,
247    /// Left bracket ([) key
248    LeftBracket = sys::ImGuiKey_LeftBracket as i32,
249    /// Backslash (\) key
250    Backslash = sys::ImGuiKey_Backslash as i32,
251    /// Right bracket (]) key
252    RightBracket = sys::ImGuiKey_RightBracket as i32,
253    /// Grave accent (`) key
254    GraveAccent = sys::ImGuiKey_GraveAccent as i32,
255    /// CapsLock key
256    CapsLock = sys::ImGuiKey_CapsLock as i32,
257    /// ScrollLock key
258    ScrollLock = sys::ImGuiKey_ScrollLock as i32,
259    /// NumLock key
260    NumLock = sys::ImGuiKey_NumLock as i32,
261    /// PrintScreen key
262    PrintScreen = sys::ImGuiKey_PrintScreen as i32,
263    /// Pause key
264    Pause = sys::ImGuiKey_Pause as i32,
265
266    // --- Keypad ---
267    /// Numpad 0
268    Keypad0 = sys::ImGuiKey_Keypad0 as i32,
269    /// Numpad 1
270    Keypad1 = sys::ImGuiKey_Keypad1 as i32,
271    /// Numpad 2
272    Keypad2 = sys::ImGuiKey_Keypad2 as i32,
273    /// Numpad 3
274    Keypad3 = sys::ImGuiKey_Keypad3 as i32,
275    /// Numpad 4
276    Keypad4 = sys::ImGuiKey_Keypad4 as i32,
277    /// Numpad 5
278    Keypad5 = sys::ImGuiKey_Keypad5 as i32,
279    /// Numpad 6
280    Keypad6 = sys::ImGuiKey_Keypad6 as i32,
281    /// Numpad 7
282    Keypad7 = sys::ImGuiKey_Keypad7 as i32,
283    /// Numpad 8
284    Keypad8 = sys::ImGuiKey_Keypad8 as i32,
285    /// Numpad 9
286    Keypad9 = sys::ImGuiKey_Keypad9 as i32,
287    /// Numpad decimal
288    KeypadDecimal = sys::ImGuiKey_KeypadDecimal as i32,
289    /// Numpad divide
290    KeypadDivide = sys::ImGuiKey_KeypadDivide as i32,
291    /// Numpad multiply
292    KeypadMultiply = sys::ImGuiKey_KeypadMultiply as i32,
293    /// Numpad subtract
294    KeypadSubtract = sys::ImGuiKey_KeypadSubtract as i32,
295    /// Numpad add
296    KeypadAdd = sys::ImGuiKey_KeypadAdd as i32,
297    /// Numpad enter
298    KeypadEnter = sys::ImGuiKey_KeypadEnter as i32,
299    /// Numpad equal
300    KeypadEqual = sys::ImGuiKey_KeypadEqual as i32,
301
302    /// OEM 102 key (ISO < > |)
303    Oem102 = sys::ImGuiKey_Oem102 as i32,
304}
305
306impl From<MouseButton> for sys::ImGuiMouseButton {
307    #[inline]
308    fn from(value: MouseButton) -> sys::ImGuiMouseButton {
309        value as sys::ImGuiMouseButton
310    }
311}
312
313impl From<MouseSource> for sys::ImGuiMouseSource {
314    #[inline]
315    fn from(value: MouseSource) -> sys::ImGuiMouseSource {
316        value as sys::ImGuiMouseSource
317    }
318}
319
320impl From<Key> for sys::ImGuiKey {
321    #[inline]
322    fn from(value: Key) -> sys::ImGuiKey {
323        value as sys::ImGuiKey
324    }
325}
326
327// Key modifier flags are available via io.KeyCtrl/KeyShift/KeyAlt/KeySuper.
328
329bitflags! {
330    /// Input text flags for text input widgets
331    #[repr(transparent)]
332    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
333    pub struct InputTextFlags: i32 {
334        /// No flags
335        const NONE = sys::ImGuiInputTextFlags_None as i32;
336        /// Allow 0123456789.+-*/
337        const CHARS_DECIMAL = sys::ImGuiInputTextFlags_CharsDecimal as i32;
338        /// Allow 0123456789ABCDEFabcdef
339        const CHARS_HEXADECIMAL = sys::ImGuiInputTextFlags_CharsHexadecimal as i32;
340        /// Turn a..z into A..Z
341        const CHARS_UPPERCASE = sys::ImGuiInputTextFlags_CharsUppercase as i32;
342        /// Filter out spaces, tabs
343        const CHARS_NO_BLANK = sys::ImGuiInputTextFlags_CharsNoBlank as i32;
344        /// Select entire text when first taking mouse focus
345        const AUTO_SELECT_ALL = sys::ImGuiInputTextFlags_AutoSelectAll as i32;
346        /// Return 'true' when Enter is pressed (as opposed to every time the value was modified)
347        const ENTER_RETURNS_TRUE = sys::ImGuiInputTextFlags_EnterReturnsTrue as i32;
348        /// Callback on pressing TAB (for completion handling)
349        const CALLBACK_COMPLETION = sys::ImGuiInputTextFlags_CallbackCompletion as i32;
350        /// Callback on pressing Up/Down arrows (for history handling)
351        const CALLBACK_HISTORY = sys::ImGuiInputTextFlags_CallbackHistory as i32;
352        /// Callback on each iteration (user can query cursor and modify text)
353        const CALLBACK_ALWAYS = sys::ImGuiInputTextFlags_CallbackAlways as i32;
354        /// Callback on character inputs to replace or discard them
355        const CALLBACK_CHAR_FILTER = sys::ImGuiInputTextFlags_CallbackCharFilter as i32;
356        /// Pressing TAB input a '\t' character into the text field
357        const ALLOW_TAB_INPUT = sys::ImGuiInputTextFlags_AllowTabInput as i32;
358        /// In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter
359        const CTRL_ENTER_FOR_NEW_LINE = sys::ImGuiInputTextFlags_CtrlEnterForNewLine as i32;
360        /// Disable following the cursor horizontally
361        const NO_HORIZONTAL_SCROLL = sys::ImGuiInputTextFlags_NoHorizontalScroll as i32;
362        /// Overwrite mode
363        const ALWAYS_OVERWRITE = sys::ImGuiInputTextFlags_AlwaysOverwrite as i32;
364        /// Read-only mode
365        const READ_ONLY = sys::ImGuiInputTextFlags_ReadOnly as i32;
366        /// Password mode, display all characters as '*'
367        const PASSWORD = sys::ImGuiInputTextFlags_Password as i32;
368        /// Disable undo/redo
369        const NO_UNDO_REDO = sys::ImGuiInputTextFlags_NoUndoRedo as i32;
370        /// Allow 0123456789.+-*/eE (Scientific notation input)
371        const CHARS_SCIENTIFIC = sys::ImGuiInputTextFlags_CharsScientific as i32;
372        /// Callback on buffer capacity changes request
373        const CALLBACK_RESIZE = sys::ImGuiInputTextFlags_CallbackResize as i32;
374        /// Callback on any edit (note that InputText() already returns true on edit)
375        const CALLBACK_EDIT = sys::ImGuiInputTextFlags_CallbackEdit as i32;
376    }
377}
378
379#[cfg(feature = "serde")]
380impl Serialize for InputTextFlags {
381    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
382    where
383        S: serde::Serializer,
384    {
385        serializer.serialize_i32(self.bits())
386    }
387}
388
389#[cfg(feature = "serde")]
390impl<'de> Deserialize<'de> for InputTextFlags {
391    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
392    where
393        D: serde::Deserializer<'de>,
394    {
395        let bits = i32::deserialize(deserializer)?;
396        Ok(InputTextFlags::from_bits_truncate(bits))
397    }
398}
399
400// TODO: Add NavInput enum once we have proper constants in sys crate
401
402impl crate::Ui {
403    /// Check if a key is being held down
404    #[doc(alias = "IsKeyDown")]
405    pub fn is_key_down(&self, key: Key) -> bool {
406        unsafe { sys::igIsKeyDown_Nil(key as sys::ImGuiKey) }
407    }
408
409    /// Check if a key was pressed (went from !Down to Down)
410    #[doc(alias = "IsKeyPressed")]
411    pub fn is_key_pressed(&self, key: Key) -> bool {
412        unsafe { sys::igIsKeyPressed_Bool(key as sys::ImGuiKey, true) }
413    }
414
415    /// Check if a key was pressed (went from !Down to Down), with repeat
416    #[doc(alias = "IsKeyPressed")]
417    pub fn is_key_pressed_with_repeat(&self, key: Key, repeat: bool) -> bool {
418        unsafe { sys::igIsKeyPressed_Bool(key as sys::ImGuiKey, repeat) }
419    }
420
421    /// Check if a key was released (went from Down to !Down)
422    #[doc(alias = "IsKeyReleased")]
423    pub fn is_key_released(&self, key: Key) -> bool {
424        unsafe { sys::igIsKeyReleased_Nil(key as sys::ImGuiKey) }
425    }
426
427    /// Check if a mouse button is being held down
428    #[doc(alias = "IsMouseDown")]
429    pub fn is_mouse_down(&self, button: MouseButton) -> bool {
430        unsafe { sys::igIsMouseDown_Nil(button.into()) }
431    }
432
433    /// Check if a mouse button was clicked (went from !Down to Down)
434    #[doc(alias = "IsMouseClicked")]
435    pub fn is_mouse_clicked(&self, button: MouseButton) -> bool {
436        unsafe { sys::igIsMouseClicked_Bool(button.into(), false) }
437    }
438
439    /// Check if a mouse button was clicked, with repeat
440    #[doc(alias = "IsMouseClicked")]
441    pub fn is_mouse_clicked_with_repeat(&self, button: MouseButton, repeat: bool) -> bool {
442        unsafe { sys::igIsMouseClicked_Bool(button.into(), repeat) }
443    }
444
445    /// Check if a mouse button was released (went from Down to !Down)
446    #[doc(alias = "IsMouseReleased")]
447    pub fn is_mouse_released(&self, button: MouseButton) -> bool {
448        unsafe { sys::igIsMouseReleased_Nil(button.into()) }
449    }
450
451    /// Check if a mouse button was double-clicked
452    #[doc(alias = "IsMouseDoubleClicked")]
453    pub fn is_mouse_double_clicked(&self, button: MouseButton) -> bool {
454        unsafe { sys::igIsMouseDoubleClicked_Nil(button.into()) }
455    }
456
457    /// Get mouse position in screen coordinates
458    #[doc(alias = "GetMousePos")]
459    pub fn mouse_pos(&self) -> [f32; 2] {
460        let pos = unsafe { sys::igGetMousePos() };
461        [pos.x, pos.y]
462    }
463
464    /// Get mouse position when a specific button was clicked
465    #[doc(alias = "GetMousePosOnOpeningCurrentPopup")]
466    pub fn mouse_pos_on_opening_current_popup(&self) -> [f32; 2] {
467        let pos = unsafe { sys::igGetMousePosOnOpeningCurrentPopup() };
468        [pos.x, pos.y]
469    }
470
471    /// Check if mouse is hovering given rectangle
472    #[doc(alias = "IsMouseHoveringRect")]
473    pub fn is_mouse_hovering_rect(&self, r_min: [f32; 2], r_max: [f32; 2]) -> bool {
474        unsafe {
475            sys::igIsMouseHoveringRect(
476                sys::ImVec2::new(r_min[0], r_min[1]),
477                sys::ImVec2::new(r_max[0], r_max[1]),
478                true,
479            )
480        }
481    }
482
483    /// Check if mouse is hovering given rectangle (with clipping test)
484    #[doc(alias = "IsMouseHoveringRect")]
485    pub fn is_mouse_hovering_rect_with_clip(
486        &self,
487        r_min: [f32; 2],
488        r_max: [f32; 2],
489        clip: bool,
490    ) -> bool {
491        unsafe {
492            sys::igIsMouseHoveringRect(
493                sys::ImVec2::new(r_min[0], r_min[1]),
494                sys::ImVec2::new(r_max[0], r_max[1]),
495                clip,
496            )
497        }
498    }
499
500    /// Check if mouse is dragging
501    #[doc(alias = "IsMouseDragging")]
502    pub fn is_mouse_dragging(&self, button: MouseButton) -> bool {
503        unsafe { sys::igIsMouseDragging(button as i32, -1.0) }
504    }
505
506    /// Check if mouse is dragging with threshold
507    #[doc(alias = "IsMouseDragging")]
508    pub fn is_mouse_dragging_with_threshold(
509        &self,
510        button: MouseButton,
511        lock_threshold: f32,
512    ) -> bool {
513        unsafe { sys::igIsMouseDragging(button as i32, lock_threshold) }
514    }
515
516    /// Get mouse drag delta
517    #[doc(alias = "GetMouseDragDelta")]
518    pub fn mouse_drag_delta(&self, button: MouseButton) -> [f32; 2] {
519        let delta = unsafe { sys::igGetMouseDragDelta(button as i32, -1.0) };
520        [delta.x, delta.y]
521    }
522
523    /// Get mouse drag delta with threshold
524    #[doc(alias = "GetMouseDragDelta")]
525    pub fn mouse_drag_delta_with_threshold(
526        &self,
527        button: MouseButton,
528        lock_threshold: f32,
529    ) -> [f32; 2] {
530        let delta = unsafe { sys::igGetMouseDragDelta(button as i32, lock_threshold) };
531        [delta.x, delta.y]
532    }
533
534    /// Reset mouse drag delta for a specific button
535    #[doc(alias = "ResetMouseDragDelta")]
536    pub fn reset_mouse_drag_delta(&self, button: MouseButton) {
537        unsafe { sys::igResetMouseDragDelta(button as i32) }
538    }
539
540    /// Returns true if the last item toggled its selection state in a multi-select scope.
541    ///
542    /// This only makes sense when used between `BeginMultiSelect()` /
543    /// `EndMultiSelect()` (or helpers built on top of them).
544    #[doc(alias = "IsItemToggledSelection")]
545    pub fn is_item_toggled_selection(&self) -> bool {
546        unsafe { sys::igIsItemToggledSelection() }
547    }
548}