1use bitflags::bitflags;
2use std::f32;
3use std::ops::{Index, IndexMut};
4use std::os::raw::{c_char, c_int, c_void};
5use std::time::Duration;
6
7use crate::fonts::atlas::FontAtlas;
8use crate::fonts::font::Font;
9use crate::input::keyboard::Key;
10use crate::input::mouse::MouseButton;
11use crate::internal::{ImVector, RawCast};
12use crate::sys;
13
14bitflags! {
15 #[repr(transparent)]
17 pub struct ConfigFlags: u32 {
18 const NAV_ENABLE_KEYBOARD = sys::ImGuiConfigFlags_NavEnableKeyboard;
22 const NAV_ENABLE_GAMEPAD = sys::ImGuiConfigFlags_NavEnableGamepad;
27 const NAV_ENABLE_SET_MOUSE_POS = sys::ImGuiConfigFlags_NavEnableSetMousePos;
34 const NAV_NO_CAPTURE_KEYBOARD = sys::ImGuiConfigFlags_NavNoCaptureKeyboard;
37 const NO_MOUSE = sys::ImGuiConfigFlags_NoMouse;
41 const NO_MOUSE_CURSOR_CHANGE = sys::ImGuiConfigFlags_NoMouseCursorChange;
47 const IS_SRGB = sys::ImGuiConfigFlags_IsSRGB;
51 const IS_TOUCH_SCREEN = sys::ImGuiConfigFlags_IsTouchScreen;
55 }
56}
57
58bitflags! {
59 #[repr(transparent)]
61 pub struct BackendFlags: u32 {
62 const HAS_GAMEPAD = sys::ImGuiBackendFlags_HasGamepad;
64 const HAS_MOUSE_CURSORS = sys::ImGuiBackendFlags_HasMouseCursors;
66 const HAS_SET_MOUSE_POS = sys::ImGuiBackendFlags_HasSetMousePos;
70 const RENDERER_HAS_VTX_OFFSET = sys::ImGuiBackendFlags_RendererHasVtxOffset;
74 }
75}
76
77#[repr(u32)]
79#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
80pub enum NavInput {
81 Activate = sys::ImGuiNavInput_Activate,
82 Cancel = sys::ImGuiNavInput_Cancel,
83 Input = sys::ImGuiNavInput_Input,
84 Menu = sys::ImGuiNavInput_Menu,
85 DpadLeft = sys::ImGuiNavInput_DpadLeft,
86 DpadRight = sys::ImGuiNavInput_DpadRight,
87 DpadUp = sys::ImGuiNavInput_DpadUp,
88 DpadDown = sys::ImGuiNavInput_DpadDown,
89 LStickLeft = sys::ImGuiNavInput_LStickLeft,
90 LStickRight = sys::ImGuiNavInput_LStickRight,
91 LStickUp = sys::ImGuiNavInput_LStickUp,
92 LStickDown = sys::ImGuiNavInput_LStickDown,
93 FocusPrev = sys::ImGuiNavInput_FocusPrev,
94 FocusNext = sys::ImGuiNavInput_FocusNext,
95 TweakSlow = sys::ImGuiNavInput_TweakSlow,
96 TweakFast = sys::ImGuiNavInput_TweakFast,
97}
98
99impl NavInput {
100 pub const VARIANTS: [NavInput; NavInput::COUNT] = [
102 NavInput::Activate,
103 NavInput::Cancel,
104 NavInput::Input,
105 NavInput::Menu,
106 NavInput::DpadLeft,
107 NavInput::DpadRight,
108 NavInput::DpadUp,
109 NavInput::DpadDown,
110 NavInput::LStickLeft,
111 NavInput::LStickRight,
112 NavInput::LStickUp,
113 NavInput::LStickDown,
114 NavInput::FocusPrev,
115 NavInput::FocusNext,
116 NavInput::TweakSlow,
117 NavInput::TweakFast,
118 ];
119 const INTERNAL_COUNT: usize = 5;
121 pub const COUNT: usize = sys::ImGuiNavInput_COUNT as usize - NavInput::INTERNAL_COUNT;
123}
124
125#[test]
126fn test_nav_input_variants() {
127 for (idx, &value) in NavInput::VARIANTS.iter().enumerate() {
128 assert_eq!(idx, value as usize);
129 }
130}
131
132#[repr(C)]
134pub struct Io {
135 pub config_flags: ConfigFlags,
137 pub backend_flags: BackendFlags,
139 pub display_size: [f32; 2],
141 pub delta_time: f32,
143 pub ini_saving_rate: f32,
145
146 pub(crate) ini_filename: *const c_char,
147 pub(crate) log_filename: *const c_char,
148
149 pub mouse_double_click_time: f32,
151 pub mouse_double_click_max_dist: f32,
153 pub mouse_drag_threshold: f32,
155 pub key_map: [u32; sys::ImGuiKey_COUNT as usize],
158 pub key_repeat_delay: f32,
160 pub key_repeat_rate: f32,
162
163 user_data: *mut c_void,
164 pub(crate) fonts: *mut FontAtlas,
165
166 pub font_global_scale: f32,
168 pub font_allow_user_scaling: bool,
170
171 pub(crate) font_default: *mut Font,
172
173 pub display_framebuffer_scale: [f32; 2],
176
177 pub mouse_draw_cursor: bool,
179 pub config_mac_os_behaviors: bool,
189 pub config_input_text_cursor_blink: bool,
191 pub config_drag_click_to_input_text: bool,
195 pub config_windows_resize_from_edges: bool,
199 pub config_windows_move_from_title_bar_only: bool,
203 pub config_memory_compact_timer: f32,
207
208 pub(crate) backend_platform_name: *const c_char,
209 pub(crate) backend_renderer_name: *const c_char,
210 backend_platform_user_data: *mut c_void,
211 backend_renderer_user_data: *mut c_void,
212 backend_language_user_data: *mut c_void,
213 pub(crate) get_clipboard_text_fn:
214 Option<unsafe extern "C" fn(user_data: *mut c_void) -> *const c_char>,
215 pub(crate) set_clipboard_text_fn:
216 Option<unsafe extern "C" fn(user_data: *mut c_void, text: *const c_char)>,
217 pub(crate) clipboard_user_data: *mut c_void,
218 ime_set_input_screen_pos_fn: Option<unsafe extern "C" fn(x: c_int, y: c_int)>,
219 ime_window_handle: *mut c_void,
220 pub mouse_pos: [f32; 2],
224 pub mouse_down: [bool; 5],
226 pub mouse_wheel: f32,
230 pub mouse_wheel_h: f32,
235 pub key_ctrl: bool,
237 pub key_shift: bool,
239 pub key_alt: bool,
241 pub key_super: bool,
243 pub keys_down: [bool; 512],
245 pub nav_inputs: [f32; NavInput::COUNT + NavInput::INTERNAL_COUNT],
250 pub want_capture_mouse: bool,
253 pub want_capture_keyboard: bool,
256 pub want_text_input: bool,
260 pub want_set_mouse_pos: bool,
265 pub want_save_ini_settings: bool,
270 pub nav_active: bool,
272 pub nav_visible: bool,
274 pub framerate: f32,
278 pub metrics_render_vertices: i32,
280 pub metrics_render_indices: i32,
282 pub metrics_render_windows: i32,
284 pub metrics_active_windows: i32,
286 pub metrics_active_allocations: i32,
288 pub mouse_delta: [f32; 2],
293
294 key_mods: sys::ImGuiKeyModFlags,
295 mouse_pos_prev: [f32; 2],
296 mouse_clicked_pos: [[f32; 2]; 5],
297 mouse_clicked_time: [f64; 5],
298 mouse_clicked: [bool; 5],
299 mouse_double_clicked: [bool; 5],
300 mouse_released: [bool; 5],
301 mouse_down_owned: [bool; 5],
302 mouse_down_was_double_click: [bool; 5],
303 mouse_down_duration: [f32; 5],
304 mouse_down_duration_prev: [f32; 5],
305 mouse_drag_max_distance_abs: [[f32; 2]; 5],
306 mouse_drag_max_distance_sqr: [f32; 5],
307 keys_down_duration: [f32; 512],
308 keys_down_duration_prev: [f32; 512],
309 nav_inputs_down_duration: [f32; NavInput::COUNT + NavInput::INTERNAL_COUNT],
310 nav_inputs_down_duration_prev: [f32; NavInput::COUNT + NavInput::INTERNAL_COUNT],
311 pen_pressure: f32,
312 input_queue_surrogate: sys::ImWchar16,
313 input_queue_characters: ImVector<sys::ImWchar>,
314}
315
316unsafe impl RawCast<sys::ImGuiIO> for Io {}
317
318impl Io {
319 #[doc(alias = "AddInputCharactersUTF8")]
321 pub fn add_input_character(&mut self, character: char) {
322 let mut buf = [0; 5];
323 character.encode_utf8(&mut buf);
324 unsafe {
325 sys::ImGuiIO_AddInputCharactersUTF8(self.raw_mut(), buf.as_ptr() as *const _);
326 }
327 }
328 #[doc(alias = "ClearCharacters")]
330 pub fn clear_input_characters(&mut self) {
331 unsafe {
332 sys::ImGuiIO_ClearInputCharacters(self.raw_mut());
333 }
334 }
335 pub fn peek_input_characters(&self) -> String {
337 let c16_slice = self.input_queue_characters.as_slice();
338 String::from_utf16(c16_slice).unwrap()
339 }
340 pub fn update_delta_time(&mut self, delta: Duration) {
341 let delta_s = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1_000_000_000.0;
342 if delta_s > 0.0 {
343 self.delta_time = delta_s;
344 } else {
345 self.delta_time = f32::MIN_POSITIVE;
346 }
347 self.delta_time = delta_s;
348 }
349}
350
351impl Index<Key> for Io {
352 type Output = u32;
353 fn index(&self, index: Key) -> &u32 {
354 &self.key_map[index as usize]
355 }
356}
357
358impl IndexMut<Key> for Io {
359 fn index_mut(&mut self, index: Key) -> &mut u32 {
360 &mut self.key_map[index as usize]
361 }
362}
363
364impl Index<NavInput> for Io {
365 type Output = f32;
366 fn index(&self, index: NavInput) -> &f32 {
367 &self.nav_inputs[index as usize]
368 }
369}
370
371impl IndexMut<NavInput> for Io {
372 fn index_mut(&mut self, index: NavInput) -> &mut f32 {
373 &mut self.nav_inputs[index as usize]
374 }
375}
376
377impl Index<MouseButton> for Io {
378 type Output = bool;
379 fn index(&self, index: MouseButton) -> &bool {
380 &self.mouse_down[index as usize]
381 }
382}
383
384impl IndexMut<MouseButton> for Io {
385 fn index_mut(&mut self, index: MouseButton) -> &mut bool {
386 &mut self.mouse_down[index as usize]
387 }
388}
389
390#[test]
391#[cfg(test)]
392fn test_io_memory_layout() {
393 use std::mem;
394 assert_eq!(mem::size_of::<Io>(), mem::size_of::<sys::ImGuiIO>());
395 assert_eq!(mem::align_of::<Io>(), mem::align_of::<sys::ImGuiIO>());
396 use sys::ImGuiIO;
397 macro_rules! assert_field_offset {
398 ($l:ident, $r:ident) => {
399 assert_eq!(
400 memoffset::offset_of!(Io, $l),
401 memoffset::offset_of!(ImGuiIO, $r)
402 );
403 };
404 }
405 assert_field_offset!(config_flags, ConfigFlags);
406 assert_field_offset!(backend_flags, BackendFlags);
407 assert_field_offset!(display_size, DisplaySize);
408 assert_field_offset!(delta_time, DeltaTime);
409 assert_field_offset!(ini_saving_rate, IniSavingRate);
410 assert_field_offset!(ini_filename, IniFilename);
411 assert_field_offset!(log_filename, LogFilename);
412 assert_field_offset!(mouse_double_click_time, MouseDoubleClickTime);
413 assert_field_offset!(mouse_double_click_max_dist, MouseDoubleClickMaxDist);
414 assert_field_offset!(mouse_drag_threshold, MouseDragThreshold);
415 assert_field_offset!(key_map, KeyMap);
416 assert_field_offset!(key_repeat_delay, KeyRepeatDelay);
417 assert_field_offset!(key_repeat_rate, KeyRepeatRate);
418 assert_field_offset!(user_data, UserData);
419 assert_field_offset!(fonts, Fonts);
420 assert_field_offset!(font_global_scale, FontGlobalScale);
421 assert_field_offset!(font_allow_user_scaling, FontAllowUserScaling);
422 assert_field_offset!(font_default, FontDefault);
423 assert_field_offset!(display_framebuffer_scale, DisplayFramebufferScale);
424 assert_field_offset!(mouse_draw_cursor, MouseDrawCursor);
425 assert_field_offset!(config_mac_os_behaviors, ConfigMacOSXBehaviors);
426 assert_field_offset!(config_input_text_cursor_blink, ConfigInputTextCursorBlink);
427 assert_field_offset!(
428 config_windows_resize_from_edges,
429 ConfigWindowsResizeFromEdges
430 );
431 assert_field_offset!(
432 config_windows_move_from_title_bar_only,
433 ConfigWindowsMoveFromTitleBarOnly
434 );
435 assert_field_offset!(backend_platform_name, BackendPlatformName);
436 assert_field_offset!(backend_renderer_name, BackendRendererName);
437 assert_field_offset!(backend_platform_user_data, BackendPlatformUserData);
438 assert_field_offset!(backend_renderer_user_data, BackendRendererUserData);
439 assert_field_offset!(backend_language_user_data, BackendLanguageUserData);
440 assert_field_offset!(get_clipboard_text_fn, GetClipboardTextFn);
441 assert_field_offset!(set_clipboard_text_fn, SetClipboardTextFn);
442 assert_field_offset!(clipboard_user_data, ClipboardUserData);
443 assert_field_offset!(ime_set_input_screen_pos_fn, ImeSetInputScreenPosFn);
444 assert_field_offset!(ime_window_handle, ImeWindowHandle);
445 assert_field_offset!(mouse_pos, MousePos);
446 assert_field_offset!(mouse_down, MouseDown);
447 assert_field_offset!(mouse_wheel, MouseWheel);
448 assert_field_offset!(mouse_wheel_h, MouseWheelH);
449 assert_field_offset!(key_ctrl, KeyCtrl);
450 assert_field_offset!(key_shift, KeyShift);
451 assert_field_offset!(key_alt, KeyAlt);
452 assert_field_offset!(key_super, KeySuper);
453 assert_field_offset!(keys_down, KeysDown);
454 assert_field_offset!(nav_inputs, NavInputs);
455 assert_field_offset!(want_capture_mouse, WantCaptureMouse);
456 assert_field_offset!(want_capture_keyboard, WantCaptureKeyboard);
457 assert_field_offset!(want_text_input, WantTextInput);
458 assert_field_offset!(want_set_mouse_pos, WantSetMousePos);
459 assert_field_offset!(want_save_ini_settings, WantSaveIniSettings);
460 assert_field_offset!(nav_active, NavActive);
461 assert_field_offset!(nav_visible, NavVisible);
462 assert_field_offset!(framerate, Framerate);
463 assert_field_offset!(metrics_render_vertices, MetricsRenderVertices);
464 assert_field_offset!(metrics_render_indices, MetricsRenderIndices);
465 assert_field_offset!(metrics_render_windows, MetricsRenderWindows);
466 assert_field_offset!(metrics_active_windows, MetricsActiveWindows);
467 assert_field_offset!(metrics_active_allocations, MetricsActiveAllocations);
468 assert_field_offset!(mouse_delta, MouseDelta);
469 assert_field_offset!(key_mods, KeyMods);
470 assert_field_offset!(mouse_pos_prev, MousePosPrev);
471 assert_field_offset!(mouse_clicked_pos, MouseClickedPos);
472 assert_field_offset!(mouse_clicked_time, MouseClickedTime);
473 assert_field_offset!(mouse_clicked, MouseClicked);
474 assert_field_offset!(mouse_double_clicked, MouseDoubleClicked);
475 assert_field_offset!(mouse_released, MouseReleased);
476 assert_field_offset!(mouse_down_owned, MouseDownOwned);
477 assert_field_offset!(mouse_down_was_double_click, MouseDownWasDoubleClick);
478 assert_field_offset!(mouse_down_duration, MouseDownDuration);
479 assert_field_offset!(mouse_down_duration_prev, MouseDownDurationPrev);
480 assert_field_offset!(mouse_drag_max_distance_abs, MouseDragMaxDistanceAbs);
481 assert_field_offset!(mouse_drag_max_distance_sqr, MouseDragMaxDistanceSqr);
482 assert_field_offset!(keys_down_duration, KeysDownDuration);
483 assert_field_offset!(keys_down_duration_prev, KeysDownDurationPrev);
484 assert_field_offset!(nav_inputs_down_duration, NavInputsDownDuration);
485 assert_field_offset!(nav_inputs_down_duration_prev, NavInputsDownDurationPrev);
486 assert_field_offset!(pen_pressure, PenPressure);
487 assert_field_offset!(input_queue_surrogate, InputQueueSurrogate);
488 assert_field_offset!(input_queue_characters, InputQueueCharacters);
489}