dear_imgui_rs/
io.rs

1//! IO: inputs, configuration and backend capabilities
2//!
3//! This module wraps Dear ImGui's `ImGuiIO` and related flag types. Access the
4//! per-frame IO object via [`Ui::io`], then read inputs or tweak configuration
5//! and backend capability flags.
6//!
7//! Example: enable docking and multi-viewports, and set renderer flags.
8//! ```no_run
9//! # use dear_imgui_rs::*;
10//! # let mut ctx = Context::create();
11//! // Configure IO before starting a frame
12//! let io = ctx.io_mut();
13//! io.set_config_flags(io.config_flags() | ConfigFlags::DOCKING_ENABLE | ConfigFlags::VIEWPORTS_ENABLE);
14//! io.set_backend_flags(io.backend_flags() | BackendFlags::RENDERER_HAS_TEXTURES);
15//! # let _ = ctx.frame();
16//! ```
17//!
18#![allow(
19    clippy::cast_possible_truncation,
20    clippy::cast_sign_loss,
21    clippy::as_conversions
22)]
23use bitflags::bitflags;
24
25use crate::sys;
26
27bitflags! {
28    /// Configuration flags
29    #[repr(transparent)]
30    pub struct ConfigFlags: i32 {
31        /// Master keyboard navigation enable flag.
32        const NAV_ENABLE_KEYBOARD = sys::ImGuiConfigFlags_NavEnableKeyboard as i32;
33        /// Master gamepad navigation enable flag.
34        const NAV_ENABLE_GAMEPAD = sys::ImGuiConfigFlags_NavEnableGamepad as i32;
35        /// Instruction imgui-rs to clear mouse position/buttons in `frame()`.
36        const NO_MOUSE = sys::ImGuiConfigFlags_NoMouse as i32;
37        /// Instruction backend to not alter mouse cursor shape and visibility.
38        const NO_MOUSE_CURSOR_CHANGE = sys::ImGuiConfigFlags_NoMouseCursorChange as i32;
39        /// Application is SRGB-aware.
40        const IS_SRGB = sys::ImGuiConfigFlags_IsSRGB as i32;
41        /// Application is using a touch screen instead of a mouse.
42        const IS_TOUCH_SCREEN = sys::ImGuiConfigFlags_IsTouchScreen as i32;
43
44        const DOCKING_ENABLE = sys::ImGuiConfigFlags_DockingEnable as i32;
45
46        const VIEWPORTS_ENABLE = sys::ImGuiConfigFlags_ViewportsEnable as i32;
47    }
48}
49
50bitflags! {
51    /// Backend capabilities
52    #[repr(transparent)]
53    pub struct BackendFlags: i32 {
54        /// Backend supports gamepad and currently has one connected
55        const HAS_GAMEPAD = sys::ImGuiBackendFlags_HasGamepad as i32;
56        /// Backend supports honoring `get_mouse_cursor` value to change the OS cursor shape
57        const HAS_MOUSE_CURSORS = sys::ImGuiBackendFlags_HasMouseCursors as i32;
58        /// Backend supports `io.want_set_mouse_pos` requests to reposition the OS mouse position.
59        const HAS_SET_MOUSE_POS = sys::ImGuiBackendFlags_HasSetMousePos as i32;
60        /// Backend renderer supports DrawCmd::vtx_offset.
61        const RENDERER_HAS_VTX_OFFSET = sys::ImGuiBackendFlags_RendererHasVtxOffset as i32;
62        /// Backend renderer supports ImTextureData requests to create/update/destroy textures.
63        const RENDERER_HAS_TEXTURES = sys::ImGuiBackendFlags_RendererHasTextures as i32;
64
65        #[cfg(feature = "multi-viewport")]
66        /// Set if the platform backend supports viewports.
67        const PLATFORM_HAS_VIEWPORTS = sys::ImGuiBackendFlags_PlatformHasViewports as i32;
68        #[cfg(feature = "multi-viewport")]
69        /// Set if the renderer backend supports viewports.
70        const RENDERER_HAS_VIEWPORTS = sys::ImGuiBackendFlags_RendererHasViewports as i32;
71    }
72}
73
74#[cfg(feature = "multi-viewport")]
75bitflags! {
76    /// Viewport flags for multi-viewport support
77    #[repr(transparent)]
78    pub struct ViewportFlags: i32 {
79        /// No flags
80        const NONE = 0;
81        /// Represent a Platform Window
82        const IS_PLATFORM_WINDOW = sys::ImGuiViewportFlags_IsPlatformWindow as i32;
83        /// Represent a Platform Monitor (unused in our implementation)
84        const IS_PLATFORM_MONITOR = sys::ImGuiViewportFlags_IsPlatformMonitor as i32;
85        /// Platform Window: is created/managed by the application (rather than a dear imgui backend)
86        const OWNED_BY_APP = sys::ImGuiViewportFlags_OwnedByApp as i32;
87        /// Platform Window: Disable platform decorations: title bar, borders, etc.
88        const NO_DECORATION = sys::ImGuiViewportFlags_NoDecoration as i32;
89        /// Platform Window: Disable platform task bar icon (generally set on popups/tooltips, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcon is set)
90        const NO_TASK_BAR_ICON = sys::ImGuiViewportFlags_NoTaskBarIcon as i32;
91        /// Platform Window: Don't take focus when created.
92        const NO_FOCUS_ON_APPEARING = sys::ImGuiViewportFlags_NoFocusOnAppearing as i32;
93        /// Platform Window: Don't take focus when clicked on.
94        const NO_FOCUS_ON_CLICK = sys::ImGuiViewportFlags_NoFocusOnClick as i32;
95        /// Platform Window: Make mouse pass through so we can drag this window while peaking behind it.
96        const NO_INPUTS = sys::ImGuiViewportFlags_NoInputs as i32;
97        /// Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely).
98        const NO_RENDERER_CLEAR = sys::ImGuiViewportFlags_NoRendererClear as i32;
99        /// Platform Window: Avoid merging this window into another host window. This can only be set via ImGuiWindowClass viewport flags override (because we need to now ahead if we are going to create a viewport in the first place!).
100        const NO_AUTO_MERGE = sys::ImGuiViewportFlags_NoAutoMerge as i32;
101        /// Platform Window: Display on top (for tooltips only).
102        const TOP_MOST = sys::ImGuiViewportFlags_TopMost as i32;
103        /// Viewport can host multiple imgui windows (secondary viewports are associated to a single window).
104        const CAN_HOST_OTHER_WINDOWS = sys::ImGuiViewportFlags_CanHostOtherWindows as i32;
105        /// Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping rectangle computation.
106        const IS_MINIMIZED = sys::ImGuiViewportFlags_IsMinimized as i32;
107        /// Platform Window: Window is focused (last call to Platform_GetWindowFocus() returned true)
108        const IS_FOCUSED = sys::ImGuiViewportFlags_IsFocused as i32;
109    }
110}
111
112/// Settings and inputs/outputs for imgui-rs
113/// This is a transparent wrapper around ImGuiIO
114#[repr(transparent)]
115pub struct Io(sys::ImGuiIO);
116
117impl Io {
118    /// Creates a new Io instance from the current context
119    pub(crate) fn from_raw() -> &'static mut Self {
120        unsafe {
121            // Note: our bindings expose igGetIO_Nil which resolves against the
122            // current context. Keep using _Nil variant until regular symbol is exported.
123            let io_ptr = sys::igGetIO_Nil();
124            &mut *(io_ptr as *mut Self)
125        }
126    }
127
128    /// Main display size in pixels
129    pub fn display_size(&self) -> [f32; 2] {
130        [self.0.DisplaySize.x, self.0.DisplaySize.y]
131    }
132
133    /// Set main display size in pixels
134    pub fn set_display_size(&mut self, size: [f32; 2]) {
135        self.0.DisplaySize.x = size[0];
136        self.0.DisplaySize.y = size[1];
137    }
138
139    /// Time elapsed since last frame, in seconds
140    pub fn delta_time(&self) -> f32 {
141        self.0.DeltaTime
142    }
143
144    /// Set time elapsed since last frame, in seconds
145    pub fn set_delta_time(&mut self, delta_time: f32) {
146        self.0.DeltaTime = delta_time;
147    }
148
149    /// Mouse position, in pixels
150    pub fn mouse_pos(&self) -> [f32; 2] {
151        [self.0.MousePos.x, self.0.MousePos.y]
152    }
153
154    /// Set mouse position, in pixels
155    pub fn set_mouse_pos(&mut self, pos: [f32; 2]) {
156        self.0.MousePos.x = pos[0];
157        self.0.MousePos.y = pos[1];
158    }
159
160    /// Mouse wheel vertical scrolling
161    pub fn mouse_wheel(&self) -> f32 {
162        self.0.MouseWheel
163    }
164
165    /// Set mouse wheel vertical scrolling
166    pub fn set_mouse_wheel(&mut self, wheel: f32) {
167        self.0.MouseWheel = wheel;
168    }
169
170    /// Mouse wheel horizontal scrolling
171    pub fn mouse_wheel_h(&self) -> f32 {
172        self.0.MouseWheelH
173    }
174
175    /// Set mouse wheel horizontal scrolling
176    pub fn set_mouse_wheel_h(&mut self, wheel_h: f32) {
177        self.0.MouseWheelH = wheel_h;
178    }
179
180    /// Check if a mouse button is down
181    pub fn mouse_down(&self, button: usize) -> bool {
182        if button < 5 {
183            self.0.MouseDown[button]
184        } else {
185            false
186        }
187    }
188
189    /// Set mouse button state
190    pub fn set_mouse_down(&mut self, button: usize, down: bool) {
191        if button < 5 {
192            self.0.MouseDown[button] = down;
193        }
194    }
195
196    /// Check if imgui wants to capture mouse input
197    pub fn want_capture_mouse(&self) -> bool {
198        self.0.WantCaptureMouse
199    }
200
201    /// Check if imgui wants to capture keyboard input
202    pub fn want_capture_keyboard(&self) -> bool {
203        self.0.WantCaptureKeyboard
204    }
205
206    /// Check if imgui wants to use text input
207    pub fn want_text_input(&self) -> bool {
208        self.0.WantTextInput
209    }
210
211    /// Check if imgui wants to set mouse position
212    pub fn want_set_mouse_pos(&self) -> bool {
213        self.0.WantSetMousePos
214    }
215    /// Whether ImGui requests software-drawn mouse cursor
216    pub fn mouse_draw_cursor(&self) -> bool {
217        self.0.MouseDrawCursor
218    }
219    /// Enable or disable software-drawn mouse cursor
220    pub fn set_mouse_draw_cursor(&mut self, draw: bool) {
221        self.0.MouseDrawCursor = draw;
222    }
223
224    /// Check if imgui wants to save ini settings
225    pub fn want_save_ini_settings(&self) -> bool {
226        self.0.WantSaveIniSettings
227    }
228
229    /// Framerate estimation, in frames per second
230    pub fn framerate(&self) -> f32 {
231        self.0.Framerate
232    }
233
234    /// Vertices output during last call to render
235    pub fn metrics_render_vertices(&self) -> i32 {
236        self.0.MetricsRenderVertices
237    }
238
239    /// Indices output during last call to render
240    pub fn metrics_render_indices(&self) -> i32 {
241        self.0.MetricsRenderIndices
242    }
243
244    /// Number of visible windows
245    pub fn metrics_render_windows(&self) -> i32 {
246        self.0.MetricsRenderWindows
247    }
248
249    /// Number of active windows
250    pub fn metrics_active_windows(&self) -> i32 {
251        self.0.MetricsActiveWindows
252    }
253
254    /// Configuration flags
255    pub fn config_flags(&self) -> ConfigFlags {
256        ConfigFlags::from_bits_truncate(self.0.ConfigFlags)
257    }
258
259    /// Set configuration flags
260    pub fn set_config_flags(&mut self, flags: ConfigFlags) {
261        self.0.ConfigFlags = flags.bits();
262    }
263
264    /// Backend flags
265    pub fn backend_flags(&self) -> BackendFlags {
266        BackendFlags::from_bits_truncate(self.0.BackendFlags)
267    }
268
269    /// Set backend flags
270    pub fn set_backend_flags(&mut self, flags: BackendFlags) {
271        self.0.BackendFlags = flags.bits();
272    }
273
274    /// Add a key event to the input queue
275    pub fn add_key_event(&mut self, key: crate::Key, down: bool) {
276        unsafe {
277            sys::ImGuiIO_AddKeyEvent(&mut self.0 as *mut _, key.into(), down);
278        }
279    }
280
281    /// Add a character input event to the input queue
282    pub fn add_input_character(&mut self, character: char) {
283        unsafe {
284            sys::ImGuiIO_AddInputCharacter(&mut self.0 as *mut _, character as u32);
285        }
286    }
287
288    /// Add a mouse position event to the input queue
289    pub fn add_mouse_pos_event(&mut self, pos: [f32; 2]) {
290        unsafe {
291            sys::ImGuiIO_AddMousePosEvent(&mut self.0 as *mut _, pos[0], pos[1]);
292        }
293    }
294
295    /// Add a mouse button event to the input queue
296    pub fn add_mouse_button_event(&mut self, button: crate::input::MouseButton, down: bool) {
297        unsafe {
298            sys::ImGuiIO_AddMouseButtonEvent(&mut self.0 as *mut _, button.into(), down);
299        }
300    }
301
302    /// Add a mouse wheel event to the input queue
303    pub fn add_mouse_wheel_event(&mut self, wheel: [f32; 2]) {
304        unsafe {
305            sys::ImGuiIO_AddMouseWheelEvent(&mut self.0 as *mut _, wheel[0], wheel[1]);
306        }
307    }
308
309    /// Notify Dear ImGui that the application window gained or lost focus
310    /// This mirrors `io.AddFocusEvent()` in Dear ImGui and is used by platform backends.
311    pub fn add_focus_event(&mut self, focused: bool) {
312        unsafe {
313            sys::ImGuiIO_AddFocusEvent(&mut self.0 as *mut _, focused);
314        }
315    }
316
317    /// Get the global font scale (not available in current Dear ImGui version)
318    /// Compatibility shim: maps to style.FontScaleMain (Dear ImGui 1.92+)
319    pub fn font_global_scale(&self) -> f32 {
320        unsafe { (*sys::igGetStyle()).FontScaleMain }
321    }
322
323    /// Set the global font scale (not available in current Dear ImGui version)
324    /// Compatibility shim: maps to style.FontScaleMain (Dear ImGui 1.92+)
325    pub fn set_font_global_scale(&mut self, _scale: f32) {
326        unsafe {
327            (*sys::igGetStyle()).FontScaleMain = _scale;
328        }
329    }
330
331    /// Get the display framebuffer scale
332    pub fn display_framebuffer_scale(&self) -> [f32; 2] {
333        let scale = self.0.DisplayFramebufferScale;
334        [scale.x, scale.y]
335    }
336
337    /// Set the display framebuffer scale
338    /// This is important for HiDPI displays to ensure proper rendering
339    pub fn set_display_framebuffer_scale(&mut self, scale: [f32; 2]) {
340        self.0.DisplayFramebufferScale.x = scale[0];
341        self.0.DisplayFramebufferScale.y = scale[1];
342    }
343}