Skip to main content

dear_imgui_rs/input/
ui.rs

1use super::{Key, KeyChord, MouseButton, NextItemShortcutOptions, ShortcutOptions};
2use crate::sys;
3
4// TODO: Add NavInput enum once we have proper constants in sys crate
5
6impl crate::Ui {
7    /// Check if a key is being held down
8    #[doc(alias = "IsKeyDown")]
9    pub fn is_key_down(&self, key: Key) -> bool {
10        self.run_with_bound_context(|| unsafe { sys::igIsKeyDown_Nil(key as sys::ImGuiKey) })
11    }
12
13    /// Check if a key was pressed (went from !Down to Down)
14    #[doc(alias = "IsKeyPressed")]
15    pub fn is_key_pressed(&self, key: Key) -> bool {
16        self.run_with_bound_context(|| unsafe {
17            sys::igIsKeyPressed_Bool(key as sys::ImGuiKey, true)
18        })
19    }
20
21    /// Check if a key was pressed (went from !Down to Down), with repeat
22    #[doc(alias = "IsKeyPressed")]
23    pub fn is_key_pressed_with_repeat(&self, key: Key, repeat: bool) -> bool {
24        self.run_with_bound_context(|| unsafe {
25            sys::igIsKeyPressed_Bool(key as sys::ImGuiKey, repeat)
26        })
27    }
28
29    /// Check if a key was released (went from Down to !Down)
30    #[doc(alias = "IsKeyReleased")]
31    pub fn is_key_released(&self, key: Key) -> bool {
32        self.run_with_bound_context(|| unsafe { sys::igIsKeyReleased_Nil(key as sys::ImGuiKey) })
33    }
34
35    /// Check if a key chord was pressed (e.g. `Ctrl+S`).
36    #[doc(alias = "IsKeyChordPressed")]
37    pub fn is_key_chord_pressed(&self, key_chord: KeyChord) -> bool {
38        self.run_with_bound_context(|| unsafe { sys::igIsKeyChordPressed_Nil(key_chord.raw()) })
39    }
40
41    /// Call ImGui shortcut routing with default flags.
42    #[doc(alias = "Shortcut")]
43    pub fn shortcut(&self, key_chord: KeyChord) -> bool {
44        self.shortcut_with_flags(key_chord, ShortcutOptions::new())
45    }
46
47    /// Call ImGui shortcut routing with explicit input options.
48    #[doc(alias = "Shortcut")]
49    pub fn shortcut_with_flags(
50        &self,
51        key_chord: KeyChord,
52        flags: impl Into<ShortcutOptions>,
53    ) -> bool {
54        let flags = flags.into();
55        self.run_with_bound_context(|| unsafe { sys::igShortcut_Nil(key_chord.raw(), flags.raw()) })
56    }
57
58    /// Set the next item's shortcut with default flags.
59    #[doc(alias = "SetNextItemShortcut")]
60    pub fn set_next_item_shortcut(&self, key_chord: KeyChord) {
61        self.set_next_item_shortcut_with_flags(key_chord, NextItemShortcutOptions::new());
62    }
63
64    /// Set the next item's shortcut with explicit options.
65    #[doc(alias = "SetNextItemShortcut")]
66    pub fn set_next_item_shortcut_with_flags(
67        &self,
68        key_chord: KeyChord,
69        flags: impl Into<NextItemShortcutOptions>,
70    ) {
71        let flags = flags.into();
72        self.run_with_bound_context(|| unsafe {
73            sys::igSetNextItemShortcut(key_chord.raw(), flags.raw())
74        });
75    }
76
77    /// Overrides `io.WantCaptureKeyboard` for the next frame.
78    #[doc(alias = "SetNextFrameWantCaptureKeyboard")]
79    pub fn set_next_frame_want_capture_keyboard(&self, want_capture_keyboard: bool) {
80        self.run_with_bound_context(|| unsafe {
81            sys::igSetNextFrameWantCaptureKeyboard(want_capture_keyboard)
82        });
83    }
84
85    /// Overrides `io.WantCaptureMouse` for the next frame.
86    #[doc(alias = "SetNextFrameWantCaptureMouse")]
87    pub fn set_next_frame_want_capture_mouse(&self, want_capture_mouse: bool) {
88        self.run_with_bound_context(|| unsafe {
89            sys::igSetNextFrameWantCaptureMouse(want_capture_mouse)
90        });
91    }
92
93    /// Check if a mouse button is being held down
94    #[doc(alias = "IsMouseDown")]
95    pub fn is_mouse_down(&self, button: MouseButton) -> bool {
96        self.run_with_bound_context(|| unsafe { sys::igIsMouseDown_Nil(button.into()) })
97    }
98
99    /// Check if a mouse button was clicked (went from !Down to Down)
100    #[doc(alias = "IsMouseClicked")]
101    pub fn is_mouse_clicked(&self, button: MouseButton) -> bool {
102        self.run_with_bound_context(|| unsafe { sys::igIsMouseClicked_Bool(button.into(), false) })
103    }
104
105    /// Check if a mouse button was clicked, with repeat
106    #[doc(alias = "IsMouseClicked")]
107    pub fn is_mouse_clicked_with_repeat(&self, button: MouseButton, repeat: bool) -> bool {
108        self.run_with_bound_context(|| unsafe { sys::igIsMouseClicked_Bool(button.into(), repeat) })
109    }
110
111    /// Check if a mouse button was released (went from Down to !Down)
112    #[doc(alias = "IsMouseReleased")]
113    pub fn is_mouse_released(&self, button: MouseButton) -> bool {
114        self.run_with_bound_context(|| unsafe { sys::igIsMouseReleased_Nil(button.into()) })
115    }
116
117    /// Check if a mouse button was double-clicked
118    #[doc(alias = "IsMouseDoubleClicked")]
119    pub fn is_mouse_double_clicked(&self, button: MouseButton) -> bool {
120        self.run_with_bound_context(|| unsafe { sys::igIsMouseDoubleClicked_Nil(button.into()) })
121    }
122
123    /// Returns `true` if the mouse position is valid (not NaN).
124    ///
125    /// This checks the current mouse position as known by Dear ImGui.
126    #[doc(alias = "IsMousePosValid")]
127    pub fn is_mouse_pos_valid(&self) -> bool {
128        self.run_with_bound_context(|| unsafe { sys::igIsMousePosValid(std::ptr::null()) })
129    }
130
131    /// Returns `true` if the provided mouse position is valid (not NaN).
132    #[doc(alias = "IsMousePosValid")]
133    pub fn is_mouse_pos_valid_at(&self, pos: [f32; 2]) -> bool {
134        let v = sys::ImVec2_c {
135            x: pos[0],
136            y: pos[1],
137        };
138        self.run_with_bound_context(|| unsafe {
139            sys::igIsMousePosValid(&v as *const sys::ImVec2_c)
140        })
141    }
142
143    /// Returns `true` if the mouse button was released and the given delay has passed.
144    #[doc(alias = "IsMouseReleasedWithDelay")]
145    pub fn is_mouse_released_with_delay(&self, button: MouseButton, delay: f32) -> bool {
146        self.run_with_bound_context(|| unsafe {
147            sys::igIsMouseReleasedWithDelay(button.into(), delay)
148        })
149    }
150
151    /// Get mouse position in screen coordinates
152    #[doc(alias = "GetMousePos")]
153    pub fn mouse_pos(&self) -> [f32; 2] {
154        let pos = self.run_with_bound_context(|| unsafe { sys::igGetMousePos() });
155        [pos.x, pos.y]
156    }
157
158    /// Get mouse position when a specific button was clicked
159    #[doc(alias = "GetMousePosOnOpeningCurrentPopup")]
160    pub fn mouse_pos_on_opening_current_popup(&self) -> [f32; 2] {
161        let pos =
162            self.run_with_bound_context(|| unsafe { sys::igGetMousePosOnOpeningCurrentPopup() });
163        [pos.x, pos.y]
164    }
165
166    /// Check if mouse is hovering given rectangle
167    #[doc(alias = "IsMouseHoveringRect")]
168    pub fn is_mouse_hovering_rect(&self, r_min: [f32; 2], r_max: [f32; 2]) -> bool {
169        self.run_with_bound_context(|| unsafe {
170            sys::igIsMouseHoveringRect(
171                sys::ImVec2::new(r_min[0], r_min[1]),
172                sys::ImVec2::new(r_max[0], r_max[1]),
173                true,
174            )
175        })
176    }
177
178    /// Check if mouse is hovering given rectangle (with clipping test)
179    #[doc(alias = "IsMouseHoveringRect")]
180    pub fn is_mouse_hovering_rect_with_clip(
181        &self,
182        r_min: [f32; 2],
183        r_max: [f32; 2],
184        clip: bool,
185    ) -> bool {
186        self.run_with_bound_context(|| unsafe {
187            sys::igIsMouseHoveringRect(
188                sys::ImVec2::new(r_min[0], r_min[1]),
189                sys::ImVec2::new(r_max[0], r_max[1]),
190                clip,
191            )
192        })
193    }
194
195    /// Check if mouse is dragging
196    #[doc(alias = "IsMouseDragging")]
197    pub fn is_mouse_dragging(&self, button: MouseButton) -> bool {
198        self.run_with_bound_context(|| unsafe { sys::igIsMouseDragging(button as i32, -1.0) })
199    }
200
201    /// Check if mouse is dragging with threshold
202    #[doc(alias = "IsMouseDragging")]
203    pub fn is_mouse_dragging_with_threshold(
204        &self,
205        button: MouseButton,
206        lock_threshold: f32,
207    ) -> bool {
208        self.run_with_bound_context(|| unsafe {
209            sys::igIsMouseDragging(button as i32, lock_threshold)
210        })
211    }
212
213    /// Get mouse drag delta
214    #[doc(alias = "GetMouseDragDelta")]
215    pub fn mouse_drag_delta(&self, button: MouseButton) -> [f32; 2] {
216        let delta = self
217            .run_with_bound_context(|| unsafe { sys::igGetMouseDragDelta(button as i32, -1.0) });
218        [delta.x, delta.y]
219    }
220
221    /// Get mouse drag delta with threshold
222    #[doc(alias = "GetMouseDragDelta")]
223    pub fn mouse_drag_delta_with_threshold(
224        &self,
225        button: MouseButton,
226        lock_threshold: f32,
227    ) -> [f32; 2] {
228        let delta = self.run_with_bound_context(|| unsafe {
229            sys::igGetMouseDragDelta(button as i32, lock_threshold)
230        });
231        [delta.x, delta.y]
232    }
233
234    /// Reset mouse drag delta for a specific button
235    #[doc(alias = "ResetMouseDragDelta")]
236    pub fn reset_mouse_drag_delta(&self, button: MouseButton) {
237        self.run_with_bound_context(|| unsafe { sys::igResetMouseDragDelta(button as i32) });
238    }
239
240    /// Returns true if the last item toggled its selection state in a multi-select scope.
241    ///
242    /// This only makes sense when used between `BeginMultiSelect()` /
243    /// `EndMultiSelect()` (or helpers built on top of them).
244    #[doc(alias = "IsItemToggledSelection")]
245    pub fn is_item_toggled_selection(&self) -> bool {
246        self.run_with_bound_context(|| unsafe { sys::igIsItemToggledSelection() })
247    }
248}