1use std::ptr;
2
3use crate::sys;
4use crate::Ui;
5
6#[derive(Copy, Clone, Eq, PartialEq, Debug)]
8pub enum MouseButton {
9 Left = 0,
10 Right = 1,
11 Middle = 2,
12 Extra1 = 3,
13 Extra2 = 4,
14}
15
16impl MouseButton {
17 pub const VARIANTS: [MouseButton; MouseButton::COUNT] = [
19 MouseButton::Left,
20 MouseButton::Right,
21 MouseButton::Middle,
22 MouseButton::Extra1,
23 MouseButton::Extra2,
24 ];
25 pub const COUNT: usize = 5;
27}
28
29#[test]
30fn test_mouse_button_variants() {
31 for (idx, &value) in MouseButton::VARIANTS.iter().enumerate() {
32 assert_eq!(idx, value as usize);
33 }
34}
35
36#[repr(i32)]
38#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
39#[allow(warnings)]
44pub enum MouseCursor {
45 Arrow = sys::ImGuiMouseCursor_Arrow,
46 TextInput = sys::ImGuiMouseCursor_TextInput,
48 ResizeAll = sys::ImGuiMouseCursor_ResizeAll,
50 ResizeNS = sys::ImGuiMouseCursor_ResizeNS,
52 ResizeEW = sys::ImGuiMouseCursor_ResizeEW,
54 ResizeNESW = sys::ImGuiMouseCursor_ResizeNESW,
56 ResizeNWSE = sys::ImGuiMouseCursor_ResizeNWSE,
58 Hand = sys::ImGuiMouseCursor_Hand,
60 NotAllowed = sys::ImGuiMouseCursor_NotAllowed,
64}
65
66impl MouseCursor {
67 pub const VARIANTS: [MouseCursor; MouseCursor::COUNT] = [
69 MouseCursor::Arrow,
70 MouseCursor::TextInput,
71 MouseCursor::ResizeAll,
72 MouseCursor::ResizeNS,
73 MouseCursor::ResizeEW,
74 MouseCursor::ResizeNESW,
75 MouseCursor::ResizeNWSE,
76 MouseCursor::Hand,
77 MouseCursor::NotAllowed,
78 ];
79 pub const COUNT: usize = sys::ImGuiMouseCursor_COUNT as usize;
81}
82
83#[test]
84fn test_mouse_cursor_variants() {
85 for (idx, &value) in MouseCursor::VARIANTS.iter().enumerate() {
86 assert_eq!(idx, value as usize);
87 }
88}
89
90impl<'ui> Ui<'ui> {
92 #[doc(alias = "IsMouseDown")]
96 pub fn is_mouse_down(&self, button: MouseButton) -> bool {
97 unsafe { sys::igIsMouseDown(button as i32) }
98 }
99 #[doc(alias = "IsAnyMouseDown")]
101 pub fn is_any_mouse_down(&self) -> bool {
102 unsafe { sys::igIsAnyMouseDown() }
103 }
104 #[doc(alias = "IsMouseClicked")]
106 pub fn is_mouse_clicked(&self, button: MouseButton) -> bool {
107 unsafe { sys::igIsMouseClicked(button as i32, false) }
108 }
109 #[doc(alias = "IsMouseDoubleClicked")]
111 pub fn is_mouse_double_clicked(&self, button: MouseButton) -> bool {
112 unsafe { sys::igIsMouseDoubleClicked(button as i32) }
113 }
114 #[doc(alias = "IsMouseReleased")]
116 pub fn is_mouse_released(&self, button: MouseButton) -> bool {
117 unsafe { sys::igIsMouseReleased(button as i32) }
118 }
119 #[doc(alias = "IsMouseDragging")]
121 pub fn is_mouse_dragging(&self, button: MouseButton) -> bool {
122 unsafe { sys::igIsMouseDragging(button as i32, -1.0) }
123 }
124 #[doc(alias = "IsMouseDragging")]
129 pub fn is_mouse_dragging_with_threshold(&self, button: MouseButton, threshold: f32) -> bool {
130 unsafe { sys::igIsMouseDragging(button as i32, threshold) }
131 }
132 pub fn is_mouse_hovering_rect(&self, r_min: [f32; 2], r_max: [f32; 2]) -> bool {
137 unsafe { sys::igIsMouseHoveringRect(r_min.into(), r_max.into(), true) }
138 }
139 #[doc(alias = "GetMousePosOnOpeningCurrentPopup")]
141 pub fn mouse_pos_on_opening_current_popup(&self) -> [f32; 2] {
142 let mut out = sys::ImVec2::zero();
143 unsafe { sys::igGetMousePosOnOpeningCurrentPopup(&mut out) };
144 out.into()
145 }
146
147 #[doc(alias = "GetMouseDragDelta")]
155 pub fn mouse_drag_delta(&self) -> [f32; 2] {
156 self.mouse_drag_delta_with_button(MouseButton::Left)
157 }
158
159 #[doc(alias = "GetMouseDragDelta")]
167 pub fn mouse_drag_delta_with_button(&self, button: MouseButton) -> [f32; 2] {
168 self.mouse_drag_delta_with_threshold(button, -1.0)
169 }
170 #[doc(alias = "GetMouseDragDelta")]
176 pub fn mouse_drag_delta_with_threshold(&self, button: MouseButton, threshold: f32) -> [f32; 2] {
177 let mut out = sys::ImVec2::zero();
178 unsafe { sys::igGetMouseDragDelta(&mut out, button as i32, threshold) };
179 out.into()
180 }
181 #[doc(alias = "ResetMouseDragDelta")]
183 pub fn reset_mouse_drag_delta(&self, button: MouseButton) {
184 unsafe { sys::igResetMouseDragDelta(button as i32) }
187 }
188 #[doc(alias = "GetMouseCursor")]
192 pub fn mouse_cursor(&self) -> Option<MouseCursor> {
193 match unsafe { sys::igGetMouseCursor() } {
194 sys::ImGuiMouseCursor_Arrow => Some(MouseCursor::Arrow),
195 sys::ImGuiMouseCursor_TextInput => Some(MouseCursor::TextInput),
196 sys::ImGuiMouseCursor_ResizeAll => Some(MouseCursor::ResizeAll),
197 sys::ImGuiMouseCursor_ResizeNS => Some(MouseCursor::ResizeNS),
198 sys::ImGuiMouseCursor_ResizeEW => Some(MouseCursor::ResizeEW),
199 sys::ImGuiMouseCursor_ResizeNESW => Some(MouseCursor::ResizeNESW),
200 sys::ImGuiMouseCursor_ResizeNWSE => Some(MouseCursor::ResizeNWSE),
201 sys::ImGuiMouseCursor_Hand => Some(MouseCursor::Hand),
202 sys::ImGuiMouseCursor_NotAllowed => Some(MouseCursor::NotAllowed),
203 _ => None,
204 }
205 }
206 #[doc(alias = "SetMouseCursor")]
210 pub fn set_mouse_cursor(&self, cursor_type: Option<MouseCursor>) {
211 unsafe {
212 sys::igSetMouseCursor(
213 cursor_type
214 .map(|x| x as i32)
215 .unwrap_or(sys::ImGuiMouseCursor_None),
216 );
217 }
218 }
219 #[doc(alias = "IsMousePosValid")]
220 pub fn is_current_mouse_pos_valid(&self) -> bool {
221 unsafe { sys::igIsMousePosValid(ptr::null()) }
222 }
223 #[doc(alias = "IsMousePosValid")]
224 pub fn is_mouse_pos_valid(&self, mouse_pos: [f32; 2]) -> bool {
225 unsafe { sys::igIsMousePosValid(&mouse_pos.into()) }
226 }
227}
228
229#[test]
230fn test_mouse_down_clicked_released() {
231 for &button in MouseButton::VARIANTS.iter() {
232 let (_guard, mut ctx) = crate::test::test_ctx_initialized();
233 {
234 ctx.io_mut().mouse_down = [false; 5];
235 let ui = ctx.frame();
236 assert!(!ui.is_mouse_down(button));
237 assert!(!ui.is_any_mouse_down());
238 assert!(!ui.is_mouse_clicked(button));
239 assert!(!ui.is_mouse_released(button));
240 }
241 {
242 ctx.io_mut()[button] = true;
243 let ui = ctx.frame();
244 assert!(ui.is_mouse_down(button));
245 assert!(ui.is_any_mouse_down());
246 assert!(ui.is_mouse_clicked(button));
247 assert!(!ui.is_mouse_released(button));
248 }
249 {
250 let ui = ctx.frame();
251 assert!(ui.is_mouse_down(button));
252 assert!(ui.is_any_mouse_down());
253 assert!(!ui.is_mouse_clicked(button));
254 assert!(!ui.is_mouse_released(button));
255 }
256 {
257 ctx.io_mut()[button] = false;
258 let ui = ctx.frame();
259 assert!(!ui.is_mouse_down(button));
260 assert!(!ui.is_any_mouse_down());
261 assert!(!ui.is_mouse_clicked(button));
262 assert!(ui.is_mouse_released(button));
263 }
264 {
265 let ui = ctx.frame();
266 assert!(!ui.is_mouse_down(button));
267 assert!(!ui.is_any_mouse_down());
268 assert!(!ui.is_mouse_clicked(button));
269 assert!(!ui.is_mouse_released(button));
270 }
271 }
272}
273
274#[test]
275fn test_mouse_double_click() {
276 let (_guard, mut ctx) = crate::test::test_ctx_initialized();
277 {
283 ctx.io_mut().delta_time = 1.0;
285 let _ = ctx.frame();
286 }
287 ctx.io_mut().delta_time = 1.0 / 60.0;
289 for &button in MouseButton::VARIANTS.iter() {
290 {
291 ctx.io_mut().mouse_down = [false; 5];
292 let ui = ctx.frame();
293 assert!(!ui.is_mouse_clicked(button));
294 assert!(!ui.is_mouse_double_clicked(button));
295 }
296 {
297 ctx.io_mut()[button] = true;
298 let ui = ctx.frame();
299 assert!(ui.is_mouse_clicked(button));
300 assert!(!ui.is_mouse_double_clicked(button));
301 }
302 {
303 let ui = ctx.frame();
304 assert!(!ui.is_mouse_clicked(button));
305 assert!(!ui.is_mouse_double_clicked(button));
306 }
307 {
308 ctx.io_mut()[button] = false;
309 let ui = ctx.frame();
310 assert!(!ui.is_mouse_clicked(button));
311 assert!(!ui.is_mouse_double_clicked(button));
312 }
313 {
314 ctx.io_mut()[button] = true;
315 let ui = ctx.frame();
316 assert!(ui.is_mouse_clicked(button));
317 assert!(ui.is_mouse_double_clicked(button));
318 }
319 {
320 let ui = ctx.frame();
321 assert!(!ui.is_mouse_clicked(button));
322 assert!(!ui.is_mouse_double_clicked(button));
323 }
324 }
325 ctx.io_mut().delta_time = 1.0;
327 for &button in MouseButton::VARIANTS.iter() {
328 {
329 ctx.io_mut().mouse_down = [false; 5];
330 let ui = ctx.frame();
331 assert!(!ui.is_mouse_clicked(button));
332 assert!(!ui.is_mouse_double_clicked(button));
333 }
334 {
335 ctx.io_mut()[button] = true;
336 let ui = ctx.frame();
337 assert!(ui.is_mouse_clicked(button));
338 assert!(!ui.is_mouse_double_clicked(button));
339 }
340 {
341 let ui = ctx.frame();
342 assert!(!ui.is_mouse_clicked(button));
343 assert!(!ui.is_mouse_double_clicked(button));
344 }
345 {
346 ctx.io_mut()[button] = false;
347 let ui = ctx.frame();
348 assert!(!ui.is_mouse_clicked(button));
349 assert!(!ui.is_mouse_double_clicked(button));
350 }
351 {
352 ctx.io_mut()[button] = true;
353 let ui = ctx.frame();
354 assert!(ui.is_mouse_clicked(button));
355 assert!(!ui.is_mouse_double_clicked(button));
356 }
357 {
358 let ui = ctx.frame();
359 assert!(!ui.is_mouse_clicked(button));
360 assert!(!ui.is_mouse_double_clicked(button));
361 }
362 }
363}
364
365#[test]
366fn test_set_get_mouse_cursor() {
367 let (_guard, mut ctx) = crate::test::test_ctx_initialized();
368 let ui = ctx.frame();
369 ui.set_mouse_cursor(None);
370 assert_eq!(None, ui.mouse_cursor());
371 ui.set_mouse_cursor(Some(MouseCursor::Hand));
372 assert_eq!(Some(MouseCursor::Hand), ui.mouse_cursor());
373}
374
375#[test]
376fn test_mouse_drags() {
377 for &button in MouseButton::VARIANTS.iter() {
378 let (_guard, mut ctx) = crate::test::test_ctx_initialized();
379 {
380 ctx.io_mut().mouse_pos = [0.0, 0.0];
381 ctx.io_mut().mouse_down = [false; 5];
382 let ui = ctx.frame();
383 assert!(!ui.is_mouse_dragging(button));
384 assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
385 assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
386 assert_eq!(
387 ui.mouse_drag_delta_with_threshold(button, 200.0),
388 [0.0, 0.0]
389 );
390 }
391 {
392 ctx.io_mut()[button] = true;
393 let ui = ctx.frame();
394 assert!(!ui.is_mouse_dragging(button));
395 assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
396 assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
397 assert_eq!(
398 ui.mouse_drag_delta_with_threshold(button, 200.0),
399 [0.0, 0.0]
400 );
401 }
402 {
403 ctx.io_mut().mouse_pos = [0.0, 100.0];
404 let ui = ctx.frame();
405 assert!(ui.is_mouse_dragging(button));
406 assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
407 assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 100.0]);
408 assert_eq!(
409 ui.mouse_drag_delta_with_threshold(button, 200.0),
410 [0.0, 0.0]
411 );
412 }
413 {
414 ctx.io_mut().mouse_pos = [0.0, 200.0];
415 let ui = ctx.frame();
416 assert!(ui.is_mouse_dragging(button));
417 assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
418 assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 200.0]);
419 assert_eq!(
420 ui.mouse_drag_delta_with_threshold(button, 200.0),
421 [0.0, 200.0]
422 );
423 }
424 {
425 ctx.io_mut().mouse_pos = [10.0, 10.0];
426 ctx.io_mut()[button] = false;
427 let ui = ctx.frame();
428 assert!(!ui.is_mouse_dragging(button));
429 assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
430 assert_eq!(ui.mouse_drag_delta_with_button(button), [10.0, 10.0]);
431 assert_eq!(
432 ui.mouse_drag_delta_with_threshold(button, 200.0),
433 [10.0, 10.0]
434 );
435 }
436 {
437 ctx.io_mut()[button] = true;
438 let ui = ctx.frame();
439 assert!(!ui.is_mouse_dragging(button));
440 assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
441 assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
442 assert_eq!(
443 ui.mouse_drag_delta_with_threshold(button, 200.0),
444 [0.0, 0.0]
445 );
446 }
447 {
448 ctx.io_mut().mouse_pos = [180.0, 180.0];
449 let ui = ctx.frame();
450 assert!(ui.is_mouse_dragging(button));
451 assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
452 assert_eq!(ui.mouse_drag_delta_with_button(button), [170.0, 170.0]);
453 assert_eq!(
454 ui.mouse_drag_delta_with_threshold(button, 200.0),
455 [170.0, 170.0]
456 );
457 ui.reset_mouse_drag_delta(button);
458 assert!(ui.is_mouse_dragging(button));
459 assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
460 assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
461 assert_eq!(
462 ui.mouse_drag_delta_with_threshold(button, 200.0),
463 [0.0, 0.0]
464 );
465 }
466 {
467 ctx.io_mut().mouse_pos = [200.0, 200.0];
468 let ui = ctx.frame();
469 assert!(ui.is_mouse_dragging(button));
470 assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
471 assert_eq!(ui.mouse_drag_delta_with_button(button), [20.0, 20.0]);
472 assert_eq!(
473 ui.mouse_drag_delta_with_threshold(button, 200.0),
474 [20.0, 20.0]
475 );
476 }
477 }
478}