Skip to main content

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    clippy::unnecessary_cast
14)]
15use crate::sys;
16use bitflags::bitflags;
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20/// Mouse button identifier
21#[repr(i32)]
22#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24pub enum MouseButton {
25    /// Left mouse button
26    Left = sys::ImGuiMouseButton_Left as i32,
27    /// Right mouse button
28    Right = sys::ImGuiMouseButton_Right as i32,
29    /// Middle mouse button
30    Middle = sys::ImGuiMouseButton_Middle as i32,
31    /// Extra mouse button 1 (typically Back)
32    Extra1 = 3,
33    /// Extra mouse button 2 (typically Forward)
34    Extra2 = 4,
35}
36
37/// Mouse cursor types
38#[repr(i32)]
39#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
40#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
41pub enum MouseCursor {
42    /// No cursor
43    None = sys::ImGuiMouseCursor_None as i32,
44    /// Arrow cursor
45    Arrow = sys::ImGuiMouseCursor_Arrow as i32,
46    /// Text input I-beam cursor
47    TextInput = sys::ImGuiMouseCursor_TextInput as i32,
48    /// Resize all directions cursor
49    ResizeAll = sys::ImGuiMouseCursor_ResizeAll as i32,
50    /// Resize north-south cursor
51    ResizeNS = sys::ImGuiMouseCursor_ResizeNS as i32,
52    /// Resize east-west cursor
53    ResizeEW = sys::ImGuiMouseCursor_ResizeEW as i32,
54    /// Resize northeast-southwest cursor
55    ResizeNESW = sys::ImGuiMouseCursor_ResizeNESW as i32,
56    /// Resize northwest-southeast cursor
57    ResizeNWSE = sys::ImGuiMouseCursor_ResizeNWSE as i32,
58    /// Hand cursor
59    Hand = sys::ImGuiMouseCursor_Hand as i32,
60    /// Not allowed cursor
61    NotAllowed = sys::ImGuiMouseCursor_NotAllowed as i32,
62}
63
64/// Source of mouse-like input events.
65///
66/// Backends can use this to mark whether a mouse event originates from a
67/// physical mouse, a touch screen, or a pen/stylus so Dear ImGui can
68/// correctly handle multiple input sources.
69#[repr(i32)]
70#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
71#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
72pub enum MouseSource {
73    /// Events coming from a physical mouse
74    Mouse = sys::ImGuiMouseSource_Mouse as i32,
75    /// Events coming from a touch screen
76    TouchScreen = sys::ImGuiMouseSource_TouchScreen as i32,
77    /// Events coming from a pen or stylus
78    Pen = sys::ImGuiMouseSource_Pen as i32,
79}
80
81/// Key identifier for keyboard input
82#[repr(i32)]
83#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
84#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
85pub enum Key {
86    /// No key
87    None = sys::ImGuiKey_None as i32,
88    /// Tab key
89    Tab = sys::ImGuiKey_Tab as i32,
90    /// Left arrow key
91    LeftArrow = sys::ImGuiKey_LeftArrow as i32,
92    /// Right arrow key
93    RightArrow = sys::ImGuiKey_RightArrow as i32,
94    /// Up arrow key
95    UpArrow = sys::ImGuiKey_UpArrow as i32,
96    /// Down arrow key
97    DownArrow = sys::ImGuiKey_DownArrow as i32,
98    /// Page up key
99    PageUp = sys::ImGuiKey_PageUp as i32,
100    /// Page down key
101    PageDown = sys::ImGuiKey_PageDown as i32,
102    /// Home key
103    Home = sys::ImGuiKey_Home as i32,
104    /// End key
105    End = sys::ImGuiKey_End as i32,
106    /// Insert key
107    Insert = sys::ImGuiKey_Insert as i32,
108    /// Delete key
109    Delete = sys::ImGuiKey_Delete as i32,
110    /// Backspace key
111    Backspace = sys::ImGuiKey_Backspace as i32,
112    /// Space key
113    Space = sys::ImGuiKey_Space as i32,
114    /// Enter key
115    Enter = sys::ImGuiKey_Enter as i32,
116    /// Escape key
117    Escape = sys::ImGuiKey_Escape as i32,
118    /// Left Ctrl key
119    LeftCtrl = sys::ImGuiKey_LeftCtrl as i32,
120    /// Left Shift key
121    LeftShift = sys::ImGuiKey_LeftShift as i32,
122    /// Left Alt key
123    LeftAlt = sys::ImGuiKey_LeftAlt as i32,
124    /// Left Super key
125    LeftSuper = sys::ImGuiKey_LeftSuper as i32,
126    /// Right Ctrl key
127    RightCtrl = sys::ImGuiKey_RightCtrl as i32,
128    /// Right Shift key
129    RightShift = sys::ImGuiKey_RightShift as i32,
130    /// Right Alt key
131    RightAlt = sys::ImGuiKey_RightAlt as i32,
132    /// Right Super key
133    RightSuper = sys::ImGuiKey_RightSuper as i32,
134    /// Ctrl modifier (for `io.KeyMods` / `io.KeyCtrl`)
135    ModCtrl = sys::ImGuiMod_Ctrl as i32,
136    /// Shift modifier (for `io.KeyMods` / `io.KeyShift`)
137    ModShift = sys::ImGuiMod_Shift as i32,
138    /// Alt modifier (for `io.KeyMods` / `io.KeyAlt`)
139    ModAlt = sys::ImGuiMod_Alt as i32,
140    /// Super/Cmd modifier (for `io.KeyMods` / `io.KeySuper`)
141    ModSuper = sys::ImGuiMod_Super as i32,
142    /// Menu key
143    Menu = sys::ImGuiKey_Menu as i32,
144    /// 0 key
145    Key0 = sys::ImGuiKey_0 as i32,
146    /// 1 key
147    Key1 = sys::ImGuiKey_1 as i32,
148    /// 2 key
149    Key2 = sys::ImGuiKey_2 as i32,
150    /// 3 key
151    Key3 = sys::ImGuiKey_3 as i32,
152    /// 4 key
153    Key4 = sys::ImGuiKey_4 as i32,
154    /// 5 key
155    Key5 = sys::ImGuiKey_5 as i32,
156    /// 6 key
157    Key6 = sys::ImGuiKey_6 as i32,
158    /// 7 key
159    Key7 = sys::ImGuiKey_7 as i32,
160    /// 8 key
161    Key8 = sys::ImGuiKey_8 as i32,
162    /// 9 key
163    Key9 = sys::ImGuiKey_9 as i32,
164    /// A key
165    A = sys::ImGuiKey_A as i32,
166    /// B key
167    B = sys::ImGuiKey_B as i32,
168    /// C key
169    C = sys::ImGuiKey_C as i32,
170    /// D key
171    D = sys::ImGuiKey_D as i32,
172    /// E key
173    E = sys::ImGuiKey_E as i32,
174    /// F key
175    F = sys::ImGuiKey_F as i32,
176    /// G key
177    G = sys::ImGuiKey_G as i32,
178    /// H key
179    H = sys::ImGuiKey_H as i32,
180    /// I key
181    I = sys::ImGuiKey_I as i32,
182    /// J key
183    J = sys::ImGuiKey_J as i32,
184    /// K key
185    K = sys::ImGuiKey_K as i32,
186    /// L key
187    L = sys::ImGuiKey_L as i32,
188    /// M key
189    M = sys::ImGuiKey_M as i32,
190    /// N key
191    N = sys::ImGuiKey_N as i32,
192    /// O key
193    O = sys::ImGuiKey_O as i32,
194    /// P key
195    P = sys::ImGuiKey_P as i32,
196    /// Q key
197    Q = sys::ImGuiKey_Q as i32,
198    /// R key
199    R = sys::ImGuiKey_R as i32,
200    /// S key
201    S = sys::ImGuiKey_S as i32,
202    /// T key
203    T = sys::ImGuiKey_T as i32,
204    /// U key
205    U = sys::ImGuiKey_U as i32,
206    /// V key
207    V = sys::ImGuiKey_V as i32,
208    /// W key
209    W = sys::ImGuiKey_W as i32,
210    /// X key
211    X = sys::ImGuiKey_X as i32,
212    /// Y key
213    Y = sys::ImGuiKey_Y as i32,
214    /// Z key
215    Z = sys::ImGuiKey_Z as i32,
216    /// F1 key
217    F1 = sys::ImGuiKey_F1 as i32,
218    /// F2 key
219    F2 = sys::ImGuiKey_F2 as i32,
220    /// F3 key
221    F3 = sys::ImGuiKey_F3 as i32,
222    /// F4 key
223    F4 = sys::ImGuiKey_F4 as i32,
224    /// F5 key
225    F5 = sys::ImGuiKey_F5 as i32,
226    /// F6 key
227    F6 = sys::ImGuiKey_F6 as i32,
228    /// F7 key
229    F7 = sys::ImGuiKey_F7 as i32,
230    /// F8 key
231    F8 = sys::ImGuiKey_F8 as i32,
232    /// F9 key
233    F9 = sys::ImGuiKey_F9 as i32,
234    /// F10 key
235    F10 = sys::ImGuiKey_F10 as i32,
236    /// F11 key
237    F11 = sys::ImGuiKey_F11 as i32,
238    /// F12 key
239    F12 = sys::ImGuiKey_F12 as i32,
240
241    // --- Punctuation and extra named keys ---
242    /// Apostrophe (') key
243    Apostrophe = sys::ImGuiKey_Apostrophe as i32,
244    /// Comma (,) key
245    Comma = sys::ImGuiKey_Comma as i32,
246    /// Minus (-) key
247    Minus = sys::ImGuiKey_Minus as i32,
248    /// Period (.) key
249    Period = sys::ImGuiKey_Period as i32,
250    /// Slash (/) key
251    Slash = sys::ImGuiKey_Slash as i32,
252    /// Semicolon (;) key
253    Semicolon = sys::ImGuiKey_Semicolon as i32,
254    /// Equal (=) key
255    Equal = sys::ImGuiKey_Equal as i32,
256    /// Left bracket ([) key
257    LeftBracket = sys::ImGuiKey_LeftBracket as i32,
258    /// Backslash (\) key
259    Backslash = sys::ImGuiKey_Backslash as i32,
260    /// Right bracket (]) key
261    RightBracket = sys::ImGuiKey_RightBracket as i32,
262    /// Grave accent (`) key
263    GraveAccent = sys::ImGuiKey_GraveAccent as i32,
264    /// CapsLock key
265    CapsLock = sys::ImGuiKey_CapsLock as i32,
266    /// ScrollLock key
267    ScrollLock = sys::ImGuiKey_ScrollLock as i32,
268    /// NumLock key
269    NumLock = sys::ImGuiKey_NumLock as i32,
270    /// PrintScreen key
271    PrintScreen = sys::ImGuiKey_PrintScreen as i32,
272    /// Pause key
273    Pause = sys::ImGuiKey_Pause as i32,
274
275    // --- Keypad ---
276    /// Numpad 0
277    Keypad0 = sys::ImGuiKey_Keypad0 as i32,
278    /// Numpad 1
279    Keypad1 = sys::ImGuiKey_Keypad1 as i32,
280    /// Numpad 2
281    Keypad2 = sys::ImGuiKey_Keypad2 as i32,
282    /// Numpad 3
283    Keypad3 = sys::ImGuiKey_Keypad3 as i32,
284    /// Numpad 4
285    Keypad4 = sys::ImGuiKey_Keypad4 as i32,
286    /// Numpad 5
287    Keypad5 = sys::ImGuiKey_Keypad5 as i32,
288    /// Numpad 6
289    Keypad6 = sys::ImGuiKey_Keypad6 as i32,
290    /// Numpad 7
291    Keypad7 = sys::ImGuiKey_Keypad7 as i32,
292    /// Numpad 8
293    Keypad8 = sys::ImGuiKey_Keypad8 as i32,
294    /// Numpad 9
295    Keypad9 = sys::ImGuiKey_Keypad9 as i32,
296    /// Numpad decimal
297    KeypadDecimal = sys::ImGuiKey_KeypadDecimal as i32,
298    /// Numpad divide
299    KeypadDivide = sys::ImGuiKey_KeypadDivide as i32,
300    /// Numpad multiply
301    KeypadMultiply = sys::ImGuiKey_KeypadMultiply as i32,
302    /// Numpad subtract
303    KeypadSubtract = sys::ImGuiKey_KeypadSubtract as i32,
304    /// Numpad add
305    KeypadAdd = sys::ImGuiKey_KeypadAdd as i32,
306    /// Numpad enter
307    KeypadEnter = sys::ImGuiKey_KeypadEnter as i32,
308    /// Numpad equal
309    KeypadEqual = sys::ImGuiKey_KeypadEqual as i32,
310
311    /// OEM 102 key (ISO < > |)
312    Oem102 = sys::ImGuiKey_Oem102 as i32,
313}
314
315impl From<MouseButton> for sys::ImGuiMouseButton {
316    #[inline]
317    fn from(value: MouseButton) -> sys::ImGuiMouseButton {
318        value as sys::ImGuiMouseButton
319    }
320}
321
322impl From<MouseSource> for sys::ImGuiMouseSource {
323    #[inline]
324    fn from(value: MouseSource) -> sys::ImGuiMouseSource {
325        value as sys::ImGuiMouseSource
326    }
327}
328
329impl From<Key> for sys::ImGuiKey {
330    #[inline]
331    fn from(value: Key) -> sys::ImGuiKey {
332        value as sys::ImGuiKey
333    }
334}
335
336// Key modifier flags are available via io.KeyCtrl/KeyShift/KeyAlt/KeySuper.
337// Backends should submit modifier state via `Key::ModCtrl`/`ModShift`/`ModAlt`/`ModSuper` using `Io::add_key_event`.
338
339bitflags! {
340    /// Modifier flags for building an ImGui key chord.
341    #[repr(transparent)]
342    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
343    pub struct KeyMods: i32 {
344        /// Ctrl modifier
345        const CTRL = sys::ImGuiMod_Ctrl as i32;
346        /// Shift modifier
347        const SHIFT = sys::ImGuiMod_Shift as i32;
348        /// Alt modifier
349        const ALT = sys::ImGuiMod_Alt as i32;
350        /// Super/Cmd modifier
351        const SUPER = sys::ImGuiMod_Super as i32;
352    }
353}
354
355impl Default for KeyMods {
356    fn default() -> Self {
357        KeyMods::empty()
358    }
359}
360
361impl KeyMods {
362    #[inline]
363    pub(crate) fn raw(self) -> sys::ImGuiKeyChord {
364        self.bits() as sys::ImGuiKeyChord
365    }
366}
367
368/// A key chord (key + optional modifier flags), used by ImGui shortcut routing APIs.
369///
370/// This is a thin wrapper over `sys::ImGuiKeyChord` (an `int`).
371#[repr(transparent)]
372#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
373pub struct KeyChord(sys::ImGuiKeyChord);
374
375impl KeyChord {
376    /// Create a chord from a key (no modifiers).
377    pub fn new(key: Key) -> Self {
378        Self(key as sys::ImGuiKeyChord)
379    }
380
381    /// Add modifier flags to the chord.
382    pub fn with_mods(self, mods: KeyMods) -> Self {
383        Self(self.0 | mods.raw())
384    }
385
386    /// Returns the raw `ImGuiKeyChord` value.
387    pub fn raw(self) -> sys::ImGuiKeyChord {
388        self.0
389    }
390}
391
392impl From<Key> for KeyChord {
393    fn from(value: Key) -> Self {
394        Self::new(value)
395    }
396}
397
398bitflags! {
399    /// Independent input flags accepted by `Shortcut()`.
400    ///
401    /// The route policy is a single-choice setting represented by
402    /// [`ShortcutRoute`].
403    #[repr(transparent)]
404    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
405    pub struct ShortcutFlags: i32 {
406        const NONE = sys::ImGuiInputFlags_None as i32;
407        const REPEAT = sys::ImGuiInputFlags_Repeat as i32;
408        const ROUTE_FROM_ROOT_WINDOW = sys::ImGuiInputFlags_RouteFromRootWindow as i32;
409    }
410}
411
412impl Default for ShortcutFlags {
413    fn default() -> Self {
414        ShortcutFlags::NONE
415    }
416}
417
418bitflags! {
419    /// Options accepted only by the global shortcut route.
420    #[repr(transparent)]
421    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
422    pub struct ShortcutGlobalRouteFlags: i32 {
423        const NONE = sys::ImGuiInputFlags_None as i32;
424        const OVER_FOCUSED = sys::ImGuiInputFlags_RouteOverFocused as i32;
425        const OVER_ACTIVE = sys::ImGuiInputFlags_RouteOverActive as i32;
426        const UNLESS_BG_FOCUSED = sys::ImGuiInputFlags_RouteUnlessBgFocused as i32;
427    }
428}
429
430/// Single route policy for `Shortcut()` and `SetNextItemShortcut()`.
431#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
432pub enum ShortcutRoute {
433    /// Route to the active item only.
434    Active,
435    /// Route to windows in the focus stack. This is Dear ImGui's `Shortcut()`
436    /// default when no explicit route is provided.
437    Focused,
438    /// Focused route with higher priority than the active item.
439    FocusedOverActive,
440    /// Global route with optional global-only priority modifiers.
441    Global(ShortcutGlobalRouteFlags),
442    /// Poll keys directly without route registration.
443    Always,
444}
445
446impl ShortcutRoute {
447    #[inline]
448    const fn raw(self) -> sys::ImGuiInputFlags {
449        match self {
450            Self::Active => sys::ImGuiInputFlags_RouteActive as sys::ImGuiInputFlags,
451            Self::Focused => sys::ImGuiInputFlags_RouteFocused as sys::ImGuiInputFlags,
452            Self::FocusedOverActive => {
453                sys::ImGuiInputFlags_RouteFocused as sys::ImGuiInputFlags
454                    | sys::ImGuiInputFlags_RouteOverActive as sys::ImGuiInputFlags
455            }
456            Self::Global(flags) => {
457                sys::ImGuiInputFlags_RouteGlobal as sys::ImGuiInputFlags | flags.bits()
458            }
459            Self::Always => sys::ImGuiInputFlags_RouteAlways as sys::ImGuiInputFlags,
460        }
461    }
462
463    /// Returns the underlying Dear ImGui bits for this route policy.
464    pub const fn bits(self) -> i32 {
465        self.raw()
466    }
467}
468
469/// Complete shortcut options assembled from independent flags and an optional
470/// single route policy.
471#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
472pub struct ShortcutOptions {
473    pub flags: ShortcutFlags,
474    pub route: Option<ShortcutRoute>,
475}
476
477impl ShortcutOptions {
478    pub const fn new() -> Self {
479        Self {
480            flags: ShortcutFlags::NONE,
481            route: None,
482        }
483    }
484
485    pub fn flags(mut self, flags: ShortcutFlags) -> Self {
486        self.flags = flags;
487        self
488    }
489
490    pub fn route(mut self, route: ShortcutRoute) -> Self {
491        self.route = Some(route);
492        self
493    }
494
495    /// Returns the underlying Dear ImGui bits for these options.
496    pub fn bits(self) -> i32 {
497        self.raw()
498    }
499
500    #[inline]
501    pub(crate) fn raw(self) -> sys::ImGuiInputFlags {
502        self.flags.bits() | self.route.map_or(0, ShortcutRoute::raw)
503    }
504}
505
506impl Default for ShortcutOptions {
507    fn default() -> Self {
508        Self::new()
509    }
510}
511
512impl From<ShortcutFlags> for ShortcutOptions {
513    fn from(flags: ShortcutFlags) -> Self {
514        Self::new().flags(flags)
515    }
516}
517
518impl From<ShortcutRoute> for ShortcutOptions {
519    fn from(route: ShortcutRoute) -> Self {
520        Self::new().route(route)
521    }
522}
523
524/// Backwards-compatible name for shortcut options.
525pub type InputFlags = ShortcutOptions;
526
527bitflags! {
528    /// Flags specific to `SetNextItemShortcut()`.
529    #[repr(transparent)]
530    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
531    pub struct NextItemShortcutFlags: i32 {
532        const NONE = sys::ImGuiInputFlags_None as i32;
533        const TOOLTIP = sys::ImGuiInputFlags_Tooltip as i32;
534    }
535}
536
537/// Complete options accepted by `SetNextItemShortcut()`.
538#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
539pub struct NextItemShortcutOptions {
540    pub shortcut: ShortcutOptions,
541    pub flags: NextItemShortcutFlags,
542}
543
544impl NextItemShortcutOptions {
545    pub const fn new() -> Self {
546        Self {
547            shortcut: ShortcutOptions::new(),
548            flags: NextItemShortcutFlags::NONE,
549        }
550    }
551
552    pub fn shortcut(mut self, options: impl Into<ShortcutOptions>) -> Self {
553        self.shortcut = options.into();
554        self
555    }
556
557    pub fn flags(mut self, flags: ShortcutFlags) -> Self {
558        self.shortcut.flags = flags;
559        self
560    }
561
562    pub fn route(mut self, route: ShortcutRoute) -> Self {
563        self.shortcut.route = Some(route);
564        self
565    }
566
567    pub fn next_item_flags(mut self, flags: NextItemShortcutFlags) -> Self {
568        self.flags = flags;
569        self
570    }
571
572    pub fn tooltip(mut self, value: bool) -> Self {
573        self.flags.set(NextItemShortcutFlags::TOOLTIP, value);
574        self
575    }
576
577    /// Returns the underlying Dear ImGui bits for these options.
578    pub fn bits(self) -> i32 {
579        self.raw()
580    }
581
582    #[inline]
583    pub(crate) fn raw(self) -> sys::ImGuiInputFlags {
584        self.shortcut.raw() | self.flags.bits()
585    }
586}
587
588impl Default for NextItemShortcutOptions {
589    fn default() -> Self {
590        Self::new()
591    }
592}
593
594impl From<ShortcutOptions> for NextItemShortcutOptions {
595    fn from(shortcut: ShortcutOptions) -> Self {
596        Self::new().shortcut(shortcut)
597    }
598}
599
600impl From<ShortcutFlags> for NextItemShortcutOptions {
601    fn from(flags: ShortcutFlags) -> Self {
602        Self::new().flags(flags)
603    }
604}
605
606impl From<ShortcutRoute> for NextItemShortcutOptions {
607    fn from(route: ShortcutRoute) -> Self {
608        Self::new().route(route)
609    }
610}
611
612impl From<NextItemShortcutFlags> for NextItemShortcutOptions {
613    fn from(flags: NextItemShortcutFlags) -> Self {
614        Self::new().next_item_flags(flags)
615    }
616}
617
618bitflags! {
619    /// Input flags accepted by `SetItemKeyOwner()`.
620    #[repr(transparent)]
621    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
622    pub struct ItemKeyOwnerFlags: i32 {
623        const NONE = sys::ImGuiInputFlags_None as i32;
624
625        const LOCK_THIS_FRAME = sys::ImGuiInputFlags_LockThisFrame as i32;
626        const LOCK_UNTIL_RELEASE = sys::ImGuiInputFlags_LockUntilRelease as i32;
627
628        const COND_HOVERED = sys::ImGuiInputFlags_CondHovered as i32;
629        const COND_ACTIVE = sys::ImGuiInputFlags_CondActive as i32;
630    }
631}
632
633impl Default for ItemKeyOwnerFlags {
634    fn default() -> Self {
635        ItemKeyOwnerFlags::NONE
636    }
637}
638
639impl ItemKeyOwnerFlags {
640    #[inline]
641    pub(crate) fn raw(self) -> sys::ImGuiInputFlags {
642        self.bits() as sys::ImGuiInputFlags
643    }
644}
645
646impl Default for NextItemShortcutFlags {
647    fn default() -> Self {
648        NextItemShortcutFlags::NONE
649    }
650}
651
652bitflags! {
653    /// Input text flags for text input widgets
654    #[repr(transparent)]
655    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
656    pub struct InputTextFlags: i32 {
657        /// No flags
658        const NONE = sys::ImGuiInputTextFlags_None as i32;
659        /// Allow 0123456789.+-*/
660        const CHARS_DECIMAL = sys::ImGuiInputTextFlags_CharsDecimal as i32;
661        /// Allow 0123456789ABCDEFabcdef
662        const CHARS_HEXADECIMAL = sys::ImGuiInputTextFlags_CharsHexadecimal as i32;
663        /// Turn a..z into A..Z
664        const CHARS_UPPERCASE = sys::ImGuiInputTextFlags_CharsUppercase as i32;
665        /// Filter out spaces, tabs
666        const CHARS_NO_BLANK = sys::ImGuiInputTextFlags_CharsNoBlank as i32;
667        /// Select entire text when first taking mouse focus
668        const AUTO_SELECT_ALL = sys::ImGuiInputTextFlags_AutoSelectAll as i32;
669        /// Return 'true' when Enter is pressed (as opposed to every time the value was modified)
670        const ENTER_RETURNS_TRUE = sys::ImGuiInputTextFlags_EnterReturnsTrue as i32;
671        /// Callback on pressing TAB (for completion handling)
672        const CALLBACK_COMPLETION = sys::ImGuiInputTextFlags_CallbackCompletion as i32;
673        /// Callback on pressing Up/Down arrows (for history handling)
674        const CALLBACK_HISTORY = sys::ImGuiInputTextFlags_CallbackHistory as i32;
675        /// Callback on each iteration (user can query cursor and modify text)
676        const CALLBACK_ALWAYS = sys::ImGuiInputTextFlags_CallbackAlways as i32;
677        /// Callback on character inputs to replace or discard them
678        const CALLBACK_CHAR_FILTER = sys::ImGuiInputTextFlags_CallbackCharFilter as i32;
679        /// Pressing TAB input a '\t' character into the text field
680        const ALLOW_TAB_INPUT = sys::ImGuiInputTextFlags_AllowTabInput as i32;
681        /// In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter
682        const CTRL_ENTER_FOR_NEW_LINE = sys::ImGuiInputTextFlags_CtrlEnterForNewLine as i32;
683        /// Disable following the cursor horizontally
684        const NO_HORIZONTAL_SCROLL = sys::ImGuiInputTextFlags_NoHorizontalScroll as i32;
685        /// Overwrite mode
686        const ALWAYS_OVERWRITE = sys::ImGuiInputTextFlags_AlwaysOverwrite as i32;
687        /// Read-only mode
688        const READ_ONLY = sys::ImGuiInputTextFlags_ReadOnly as i32;
689        /// Password mode, display all characters as '*'
690        const PASSWORD = sys::ImGuiInputTextFlags_Password as i32;
691        /// Disable undo/redo
692        const NO_UNDO_REDO = sys::ImGuiInputTextFlags_NoUndoRedo as i32;
693        /// Allow 0123456789.+-*/eE (Scientific notation input)
694        const CHARS_SCIENTIFIC = sys::ImGuiInputTextFlags_CharsScientific as i32;
695        /// Callback on buffer capacity changes request
696        const CALLBACK_RESIZE = sys::ImGuiInputTextFlags_CallbackResize as i32;
697        /// Callback on any edit (note that InputText() already returns true on edit)
698        const CALLBACK_EDIT = sys::ImGuiInputTextFlags_CallbackEdit as i32;
699    }
700}
701
702impl InputTextFlags {
703    #[inline]
704    pub(crate) fn raw(self) -> sys::ImGuiInputTextFlags {
705        self.bits() as sys::ImGuiInputTextFlags
706    }
707}
708
709#[cfg(feature = "serde")]
710impl Serialize for InputTextFlags {
711    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
712    where
713        S: serde::Serializer,
714    {
715        serializer.serialize_i32(self.bits())
716    }
717}
718
719#[cfg(feature = "serde")]
720impl<'de> Deserialize<'de> for InputTextFlags {
721    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
722    where
723        D: serde::Deserializer<'de>,
724    {
725        let bits = i32::deserialize(deserializer)?;
726        Ok(InputTextFlags::from_bits_truncate(bits))
727    }
728}
729
730// TODO: Add NavInput enum once we have proper constants in sys crate
731
732impl crate::Ui {
733    /// Check if a key is being held down
734    #[doc(alias = "IsKeyDown")]
735    pub fn is_key_down(&self, key: Key) -> bool {
736        unsafe { sys::igIsKeyDown_Nil(key as sys::ImGuiKey) }
737    }
738
739    /// Check if a key was pressed (went from !Down to Down)
740    #[doc(alias = "IsKeyPressed")]
741    pub fn is_key_pressed(&self, key: Key) -> bool {
742        unsafe { sys::igIsKeyPressed_Bool(key as sys::ImGuiKey, true) }
743    }
744
745    /// Check if a key was pressed (went from !Down to Down), with repeat
746    #[doc(alias = "IsKeyPressed")]
747    pub fn is_key_pressed_with_repeat(&self, key: Key, repeat: bool) -> bool {
748        unsafe { sys::igIsKeyPressed_Bool(key as sys::ImGuiKey, repeat) }
749    }
750
751    /// Check if a key was released (went from Down to !Down)
752    #[doc(alias = "IsKeyReleased")]
753    pub fn is_key_released(&self, key: Key) -> bool {
754        unsafe { sys::igIsKeyReleased_Nil(key as sys::ImGuiKey) }
755    }
756
757    /// Check if a key chord was pressed (e.g. `Ctrl+S`).
758    #[doc(alias = "IsKeyChordPressed")]
759    pub fn is_key_chord_pressed(&self, key_chord: KeyChord) -> bool {
760        unsafe { sys::igIsKeyChordPressed_Nil(key_chord.raw()) }
761    }
762
763    /// Call ImGui shortcut routing with default flags.
764    #[doc(alias = "Shortcut")]
765    pub fn shortcut(&self, key_chord: KeyChord) -> bool {
766        self.shortcut_with_flags(key_chord, ShortcutOptions::new())
767    }
768
769    /// Call ImGui shortcut routing with explicit input options.
770    #[doc(alias = "Shortcut")]
771    pub fn shortcut_with_flags(
772        &self,
773        key_chord: KeyChord,
774        flags: impl Into<ShortcutOptions>,
775    ) -> bool {
776        unsafe { sys::igShortcut_Nil(key_chord.raw(), flags.into().raw()) }
777    }
778
779    /// Set the next item's shortcut with default flags.
780    #[doc(alias = "SetNextItemShortcut")]
781    pub fn set_next_item_shortcut(&self, key_chord: KeyChord) {
782        self.set_next_item_shortcut_with_flags(key_chord, NextItemShortcutOptions::new());
783    }
784
785    /// Set the next item's shortcut with explicit options.
786    #[doc(alias = "SetNextItemShortcut")]
787    pub fn set_next_item_shortcut_with_flags(
788        &self,
789        key_chord: KeyChord,
790        flags: impl Into<NextItemShortcutOptions>,
791    ) {
792        let flags = flags.into();
793        unsafe { sys::igSetNextItemShortcut(key_chord.raw(), flags.raw()) }
794    }
795
796    /// Overrides `io.WantCaptureKeyboard` for the next frame.
797    #[doc(alias = "SetNextFrameWantCaptureKeyboard")]
798    pub fn set_next_frame_want_capture_keyboard(&self, want_capture_keyboard: bool) {
799        unsafe { sys::igSetNextFrameWantCaptureKeyboard(want_capture_keyboard) }
800    }
801
802    /// Overrides `io.WantCaptureMouse` for the next frame.
803    #[doc(alias = "SetNextFrameWantCaptureMouse")]
804    pub fn set_next_frame_want_capture_mouse(&self, want_capture_mouse: bool) {
805        unsafe { sys::igSetNextFrameWantCaptureMouse(want_capture_mouse) }
806    }
807
808    /// Check if a mouse button is being held down
809    #[doc(alias = "IsMouseDown")]
810    pub fn is_mouse_down(&self, button: MouseButton) -> bool {
811        unsafe { sys::igIsMouseDown_Nil(button.into()) }
812    }
813
814    /// Check if a mouse button was clicked (went from !Down to Down)
815    #[doc(alias = "IsMouseClicked")]
816    pub fn is_mouse_clicked(&self, button: MouseButton) -> bool {
817        unsafe { sys::igIsMouseClicked_Bool(button.into(), false) }
818    }
819
820    /// Check if a mouse button was clicked, with repeat
821    #[doc(alias = "IsMouseClicked")]
822    pub fn is_mouse_clicked_with_repeat(&self, button: MouseButton, repeat: bool) -> bool {
823        unsafe { sys::igIsMouseClicked_Bool(button.into(), repeat) }
824    }
825
826    /// Check if a mouse button was released (went from Down to !Down)
827    #[doc(alias = "IsMouseReleased")]
828    pub fn is_mouse_released(&self, button: MouseButton) -> bool {
829        unsafe { sys::igIsMouseReleased_Nil(button.into()) }
830    }
831
832    /// Check if a mouse button was double-clicked
833    #[doc(alias = "IsMouseDoubleClicked")]
834    pub fn is_mouse_double_clicked(&self, button: MouseButton) -> bool {
835        unsafe { sys::igIsMouseDoubleClicked_Nil(button.into()) }
836    }
837
838    /// Returns `true` if the mouse position is valid (not NaN).
839    ///
840    /// This checks the current mouse position as known by Dear ImGui.
841    #[doc(alias = "IsMousePosValid")]
842    pub fn is_mouse_pos_valid(&self) -> bool {
843        unsafe { sys::igIsMousePosValid(std::ptr::null()) }
844    }
845
846    /// Returns `true` if the provided mouse position is valid (not NaN).
847    #[doc(alias = "IsMousePosValid")]
848    pub fn is_mouse_pos_valid_at(&self, pos: [f32; 2]) -> bool {
849        let v = sys::ImVec2_c {
850            x: pos[0],
851            y: pos[1],
852        };
853        unsafe { sys::igIsMousePosValid(&v as *const sys::ImVec2_c) }
854    }
855
856    /// Returns `true` if the mouse button was released and the given delay has passed.
857    #[doc(alias = "IsMouseReleasedWithDelay")]
858    pub fn is_mouse_released_with_delay(&self, button: MouseButton, delay: f32) -> bool {
859        unsafe { sys::igIsMouseReleasedWithDelay(button.into(), delay) }
860    }
861
862    /// Get mouse position in screen coordinates
863    #[doc(alias = "GetMousePos")]
864    pub fn mouse_pos(&self) -> [f32; 2] {
865        let pos = unsafe { sys::igGetMousePos() };
866        [pos.x, pos.y]
867    }
868
869    /// Get mouse position when a specific button was clicked
870    #[doc(alias = "GetMousePosOnOpeningCurrentPopup")]
871    pub fn mouse_pos_on_opening_current_popup(&self) -> [f32; 2] {
872        let pos = unsafe { sys::igGetMousePosOnOpeningCurrentPopup() };
873        [pos.x, pos.y]
874    }
875
876    /// Check if mouse is hovering given rectangle
877    #[doc(alias = "IsMouseHoveringRect")]
878    pub fn is_mouse_hovering_rect(&self, r_min: [f32; 2], r_max: [f32; 2]) -> bool {
879        unsafe {
880            sys::igIsMouseHoveringRect(
881                sys::ImVec2::new(r_min[0], r_min[1]),
882                sys::ImVec2::new(r_max[0], r_max[1]),
883                true,
884            )
885        }
886    }
887
888    /// Check if mouse is hovering given rectangle (with clipping test)
889    #[doc(alias = "IsMouseHoveringRect")]
890    pub fn is_mouse_hovering_rect_with_clip(
891        &self,
892        r_min: [f32; 2],
893        r_max: [f32; 2],
894        clip: bool,
895    ) -> bool {
896        unsafe {
897            sys::igIsMouseHoveringRect(
898                sys::ImVec2::new(r_min[0], r_min[1]),
899                sys::ImVec2::new(r_max[0], r_max[1]),
900                clip,
901            )
902        }
903    }
904
905    /// Check if mouse is dragging
906    #[doc(alias = "IsMouseDragging")]
907    pub fn is_mouse_dragging(&self, button: MouseButton) -> bool {
908        unsafe { sys::igIsMouseDragging(button as i32, -1.0) }
909    }
910
911    /// Check if mouse is dragging with threshold
912    #[doc(alias = "IsMouseDragging")]
913    pub fn is_mouse_dragging_with_threshold(
914        &self,
915        button: MouseButton,
916        lock_threshold: f32,
917    ) -> bool {
918        unsafe { sys::igIsMouseDragging(button as i32, lock_threshold) }
919    }
920
921    /// Get mouse drag delta
922    #[doc(alias = "GetMouseDragDelta")]
923    pub fn mouse_drag_delta(&self, button: MouseButton) -> [f32; 2] {
924        let delta = unsafe { sys::igGetMouseDragDelta(button as i32, -1.0) };
925        [delta.x, delta.y]
926    }
927
928    /// Get mouse drag delta with threshold
929    #[doc(alias = "GetMouseDragDelta")]
930    pub fn mouse_drag_delta_with_threshold(
931        &self,
932        button: MouseButton,
933        lock_threshold: f32,
934    ) -> [f32; 2] {
935        let delta = unsafe { sys::igGetMouseDragDelta(button as i32, lock_threshold) };
936        [delta.x, delta.y]
937    }
938
939    /// Reset mouse drag delta for a specific button
940    #[doc(alias = "ResetMouseDragDelta")]
941    pub fn reset_mouse_drag_delta(&self, button: MouseButton) {
942        unsafe { sys::igResetMouseDragDelta(button as i32) }
943    }
944
945    /// Returns true if the last item toggled its selection state in a multi-select scope.
946    ///
947    /// This only makes sense when used between `BeginMultiSelect()` /
948    /// `EndMultiSelect()` (or helpers built on top of them).
949    #[doc(alias = "IsItemToggledSelection")]
950    pub fn is_item_toggled_selection(&self) -> bool {
951        unsafe { sys::igIsItemToggledSelection() }
952    }
953}