Skip to main content

dear_imgui_rs/
ui.rs

1//! Per-frame UI entry point
2//!
3//! The `Ui` type exposes most user-facing Dear ImGui APIs for a single frame:
4//! creating windows, drawing widgets, accessing draw lists, showing built-in
5//! tools and more. Obtain it from [`Context::frame`].
6//!
7//! Example:
8//! ```no_run
9//! # use dear_imgui_rs::*;
10//! let mut ctx = Context::create();
11//! let ui = ctx.frame();
12//! ui.text("Hello, world!");
13//! ```
14//!
15use crate::Id;
16use crate::draw::DrawListMut;
17use crate::input::MouseCursor;
18use crate::internal::RawWrapper;
19use crate::string::UiBuffer;
20use crate::sys;
21use crate::texture::TextureRef;
22use std::cell::UnsafeCell;
23
24/// Represents the Dear ImGui user interface for one frame
25#[derive(Debug)]
26pub struct Ui {
27    /// Internal buffer for string operations
28    buffer: UnsafeCell<UiBuffer>,
29}
30
31impl Ui {
32    /// Returns a reference to the main Dear ImGui viewport (safe wrapper)
33    ///
34    /// Same viewport used by `dockspace_over_main_viewport()`.
35    ///
36    /// The returned reference is owned by the currently active ImGui context and
37    /// must not be used after the context is destroyed.
38    #[doc(alias = "GetMainViewport")]
39    pub fn main_viewport(&self) -> &crate::platform_io::Viewport {
40        unsafe {
41            let ptr = sys::igGetMainViewport();
42            if ptr.is_null() {
43                panic!("Ui::main_viewport() requires an active ImGui context");
44            }
45            crate::platform_io::Viewport::from_raw(ptr as *const sys::ImGuiViewport)
46        }
47    }
48    /// Creates a new Ui instance
49    ///
50    /// This should only be called by Context::create()
51    pub(crate) fn new() -> Self {
52        Ui {
53            buffer: UnsafeCell::new(UiBuffer::new(1024)),
54        }
55    }
56
57    /// Returns an immutable reference to the inputs/outputs object
58    #[doc(alias = "GetIO")]
59    pub fn io(&self) -> &crate::io::Io {
60        unsafe {
61            let io = sys::igGetIO_Nil();
62            if io.is_null() {
63                panic!("Ui::io() requires an active ImGui context");
64            }
65            &*(io as *const crate::io::Io)
66        }
67    }
68
69    /// Internal method to push a single text to our scratch buffer.
70    pub(crate) fn scratch_txt(&self, txt: impl AsRef<str>) -> *const std::os::raw::c_char {
71        unsafe {
72            let handle = &mut *self.buffer.get();
73            handle.scratch_txt(txt)
74        }
75    }
76
77    /// Helper method for two strings
78    pub(crate) fn scratch_txt_two(
79        &self,
80        txt_0: impl AsRef<str>,
81        txt_1: impl AsRef<str>,
82    ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
83        unsafe {
84            let handle = &mut *self.buffer.get();
85            handle.scratch_txt_two(txt_0, txt_1)
86        }
87    }
88
89    /// Helper method with one optional value
90    pub(crate) fn scratch_txt_with_opt(
91        &self,
92        txt_0: impl AsRef<str>,
93        txt_1: Option<impl AsRef<str>>,
94    ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
95        unsafe {
96            let handle = &mut *self.buffer.get();
97            handle.scratch_txt_with_opt(txt_0, txt_1)
98        }
99    }
100
101    /// Get access to the scratch buffer for complex string operations
102    pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
103        &self.buffer
104    }
105
106    /// Display text
107    #[doc(alias = "TextUnformatted")]
108    pub fn text<T: AsRef<str>>(&self, text: T) {
109        let s = text.as_ref();
110        unsafe {
111            let start = s.as_ptr();
112            let end = start.add(s.len());
113            crate::sys::igTextUnformatted(
114                start as *const std::os::raw::c_char,
115                end as *const std::os::raw::c_char,
116            );
117        }
118    }
119
120    /// Set the viewport for the next window.
121    ///
122    /// This is a convenience wrapper over `ImGui::SetNextWindowViewport`.
123    /// Useful when hosting a fullscreen DockSpace window inside the main viewport.
124    #[doc(alias = "SetNextWindowViewport")]
125    pub fn set_next_window_viewport(&self, viewport_id: Id) {
126        unsafe { sys::igSetNextWindowViewport(viewport_id.into()) }
127    }
128
129    /// Returns the viewport of the current window.
130    ///
131    /// This requires a current window (i.e. must be called between `Begin`/`End`).
132    #[doc(alias = "GetWindowViewport")]
133    pub fn window_viewport(&self) -> &crate::platform_io::Viewport {
134        unsafe {
135            let ptr = sys::igGetWindowViewport();
136            if ptr.is_null() {
137                panic!("Ui::window_viewport() requires a current window");
138            }
139            crate::platform_io::Viewport::from_raw(ptr as *const sys::ImGuiViewport)
140        }
141    }
142
143    /// Find a viewport by ID.
144    #[doc(alias = "FindViewportByID")]
145    pub fn find_viewport_by_id(&self, viewport_id: Id) -> Option<&crate::platform_io::Viewport> {
146        unsafe {
147            let ptr = sys::igFindViewportByID(viewport_id.raw());
148            if ptr.is_null() {
149                None
150            } else {
151                Some(crate::platform_io::Viewport::from_raw(
152                    ptr as *const sys::ImGuiViewport,
153                ))
154            }
155        }
156    }
157
158    /// Find a viewport by its platform handle.
159    ///
160    /// The platform handle type depends on the backend (e.g. `HWND` on Windows).
161    #[doc(alias = "FindViewportByPlatformHandle")]
162    #[allow(clippy::not_unsafe_ptr_arg_deref)]
163    pub fn find_viewport_by_platform_handle(
164        &self,
165        platform_handle: *mut std::ffi::c_void,
166    ) -> Option<&crate::platform_io::Viewport> {
167        unsafe {
168            let ptr = sys::igFindViewportByPlatformHandle(platform_handle);
169            if ptr.is_null() {
170                None
171            } else {
172                Some(crate::platform_io::Viewport::from_raw(
173                    ptr as *const sys::ImGuiViewport,
174                ))
175            }
176        }
177    }
178
179    /// Returns an ID from a string label in the current ID scope.
180    ///
181    /// This mirrors `ImGui::GetID(label)`. Useful for building stable IDs
182    /// for widgets or dockspaces inside the current window/scope.
183    #[doc(alias = "GetID")]
184    pub fn get_id(&self, label: &str) -> Id {
185        unsafe { Id::from(sys::igGetID_Str(self.scratch_txt(label))) }
186    }
187
188    /// Access to the current window's draw list
189    #[doc(alias = "GetWindowDrawList")]
190    pub fn get_window_draw_list(&self) -> DrawListMut<'_> {
191        DrawListMut::window(self)
192    }
193
194    /// Access to the background draw list
195    #[doc(alias = "GetBackgroundDrawList")]
196    pub fn get_background_draw_list(&self) -> DrawListMut<'_> {
197        DrawListMut::background(self)
198    }
199
200    /// Access to the foreground draw list
201    #[doc(alias = "GetForegroundDrawList")]
202    pub fn get_foreground_draw_list(&self) -> DrawListMut<'_> {
203        DrawListMut::foreground(self)
204    }
205
206    /// Creates a window builder
207    pub fn window<'ui>(
208        &'ui self,
209        name: impl Into<std::borrow::Cow<'ui, str>>,
210    ) -> crate::window::Window<'ui> {
211        crate::window::Window::new(self, name)
212    }
213
214    /// Renders a demo window (previously called a test window), which demonstrates most
215    /// Dear ImGui features.
216    #[doc(alias = "ShowDemoWindow")]
217    pub fn show_demo_window(&self, opened: &mut bool) {
218        unsafe {
219            crate::sys::igShowDemoWindow(opened);
220        }
221    }
222
223    /// Convenience: draw an image with background and tint (ImGui 1.92+)
224    ///
225    /// Equivalent to using `image_config(...).build_with_bg(bg, tint)` but in one call.
226    #[doc(alias = "ImageWithBg")]
227    pub fn image_with_bg(
228        &self,
229        texture: impl Into<TextureRef>,
230        size: [f32; 2],
231        bg_color: [f32; 4],
232        tint_color: [f32; 4],
233    ) {
234        crate::widget::image::Image::new(self, texture, size).build_with_bg(bg_color, tint_color)
235    }
236
237    /// Renders an about window.
238    ///
239    /// Displays the Dear ImGui version/credits, and build/system information.
240    #[doc(alias = "ShowAboutWindow")]
241    pub fn show_about_window(&self, opened: &mut bool) {
242        unsafe {
243            crate::sys::igShowAboutWindow(opened);
244        }
245    }
246
247    /// Renders a metrics/debug window.
248    ///
249    /// Displays Dear ImGui internals: draw commands (with individual draw calls and vertices),
250    /// window list, basic internal state, etc.
251    #[doc(alias = "ShowMetricsWindow")]
252    pub fn show_metrics_window(&self, opened: &mut bool) {
253        unsafe {
254            crate::sys::igShowMetricsWindow(opened);
255        }
256    }
257
258    /// Renders a style editor block (not a window) for the given `Style` structure
259    #[doc(alias = "ShowStyleEditor")]
260    pub fn show_style_editor(&self, style: &mut crate::style::Style) {
261        unsafe {
262            crate::sys::igShowStyleEditor(style.raw_mut());
263        }
264    }
265
266    /// Renders a style editor block (not a window) for the currently active style
267    #[doc(alias = "ShowStyleEditor")]
268    pub fn show_default_style_editor(&self) {
269        unsafe {
270            crate::sys::igShowStyleEditor(std::ptr::null_mut());
271        }
272    }
273
274    /// Renders a basic help/info block (not a window)
275    #[doc(alias = "ShowUserGuide")]
276    pub fn show_user_guide(&self) {
277        unsafe {
278            crate::sys::igShowUserGuide();
279        }
280    }
281
282    // Drag widgets
283
284    /// Creates a drag float slider
285    #[doc(alias = "DragFloat")]
286    pub fn drag_float(&self, label: impl AsRef<str>, value: &mut f32) -> bool {
287        crate::widget::drag::Drag::new(label).build(self, value)
288    }
289
290    /// Creates a drag float slider with configuration
291    #[doc(alias = "DragFloat")]
292    pub fn drag_float_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<f32, L> {
293        crate::widget::drag::Drag::new(label)
294    }
295
296    /// Creates a drag int slider
297    #[doc(alias = "DragInt")]
298    pub fn drag_int(&self, label: impl AsRef<str>, value: &mut i32) -> bool {
299        crate::widget::drag::Drag::new(label).build(self, value)
300    }
301
302    /// Creates a drag int slider with configuration
303    #[doc(alias = "DragInt")]
304    pub fn drag_int_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<i32, L> {
305        crate::widget::drag::Drag::new(label)
306    }
307
308    /// Creates a drag float range slider
309    #[doc(alias = "DragFloatRange2")]
310    pub fn drag_float_range2(&self, label: impl AsRef<str>, min: &mut f32, max: &mut f32) -> bool {
311        crate::widget::drag::DragRange::<f32, _>::new(label).build(self, min, max)
312    }
313
314    /// Creates a drag float range slider with configuration
315    #[doc(alias = "DragFloatRange2")]
316    pub fn drag_float_range2_config<L: AsRef<str>>(
317        &self,
318        label: L,
319    ) -> crate::widget::drag::DragRange<f32, L> {
320        crate::widget::drag::DragRange::new(label)
321    }
322
323    /// Creates a drag int range slider
324    #[doc(alias = "DragIntRange2")]
325    pub fn drag_int_range2(&self, label: impl AsRef<str>, min: &mut i32, max: &mut i32) -> bool {
326        crate::widget::drag::DragRange::<i32, _>::new(label).build(self, min, max)
327    }
328
329    /// Creates a drag int range slider with configuration
330    #[doc(alias = "DragIntRange2")]
331    pub fn drag_int_range2_config<L: AsRef<str>>(
332        &self,
333        label: L,
334    ) -> crate::widget::drag::DragRange<i32, L> {
335        crate::widget::drag::DragRange::new(label)
336    }
337
338    /// Returns the currently desired mouse cursor type
339    ///
340    /// Returns `None` if no cursor should be displayed
341    #[doc(alias = "GetMouseCursor")]
342    pub fn mouse_cursor(&self) -> Option<MouseCursor> {
343        unsafe {
344            match sys::igGetMouseCursor() {
345                sys::ImGuiMouseCursor_Arrow => Some(MouseCursor::Arrow),
346                sys::ImGuiMouseCursor_TextInput => Some(MouseCursor::TextInput),
347                sys::ImGuiMouseCursor_ResizeAll => Some(MouseCursor::ResizeAll),
348                sys::ImGuiMouseCursor_ResizeNS => Some(MouseCursor::ResizeNS),
349                sys::ImGuiMouseCursor_ResizeEW => Some(MouseCursor::ResizeEW),
350                sys::ImGuiMouseCursor_ResizeNESW => Some(MouseCursor::ResizeNESW),
351                sys::ImGuiMouseCursor_ResizeNWSE => Some(MouseCursor::ResizeNWSE),
352                sys::ImGuiMouseCursor_Hand => Some(MouseCursor::Hand),
353                sys::ImGuiMouseCursor_NotAllowed => Some(MouseCursor::NotAllowed),
354                _ => None,
355            }
356        }
357    }
358
359    /// Sets the desired mouse cursor type
360    ///
361    /// Passing `None` hides the mouse cursor
362    #[doc(alias = "SetMouseCursor")]
363    pub fn set_mouse_cursor(&self, cursor_type: Option<MouseCursor>) {
364        unsafe {
365            let val: sys::ImGuiMouseCursor = cursor_type
366                .map(|x| x as sys::ImGuiMouseCursor)
367                .unwrap_or(sys::ImGuiMouseCursor_None);
368            sys::igSetMouseCursor(val);
369        }
370    }
371
372    // ============================================================================
373    // Focus and Navigation
374    // ============================================================================
375
376    /// Focuses keyboard on the next widget.
377    ///
378    /// This is the equivalent to [set_keyboard_focus_here_with_offset](Self::set_keyboard_focus_here_with_offset)
379    /// with `offset` set to 0.
380    #[doc(alias = "SetKeyboardFocusHere")]
381    pub fn set_keyboard_focus_here(&self) {
382        self.set_keyboard_focus_here_with_offset(0);
383    }
384
385    /// Focuses keyboard on a widget relative to current position.
386    ///
387    /// Use positive offset to focus on next widgets, negative offset to focus on previous widgets.
388    #[doc(alias = "SetKeyboardFocusHere")]
389    pub fn set_keyboard_focus_here_with_offset(&self, offset: i32) {
390        unsafe {
391            sys::igSetKeyboardFocusHere(offset);
392        }
393    }
394
395    /// Shows or hides the navigation cursor (a small marker indicating nav focus).
396    #[doc(alias = "SetNavCursorVisible")]
397    pub fn set_nav_cursor_visible(&self, visible: bool) {
398        unsafe { sys::igSetNavCursorVisible(visible) }
399    }
400
401    /// Focus a window by name, or clear focus from all windows.
402    ///
403    /// Passing `None` is equivalent to `ImGui::SetWindowFocus(NULL)` in the C++ API.
404    /// This can be used to "unfocus" the entire UI (e.g. on Escape, to behave like
405    /// clicking outside of the UI).
406    #[doc(alias = "SetWindowFocus")]
407    pub fn set_window_focus(&self, name: Option<&str>) {
408        unsafe {
409            match name {
410                Some(name) => sys::igSetWindowFocus_Str(self.scratch_txt(name)),
411                None => sys::igSetWindowFocus_Nil(),
412            }
413        }
414    }
415
416    /// Sets the position of the current window.
417    #[doc(alias = "SetWindowPos")]
418    pub fn set_window_pos(&self, pos: [f32; 2]) {
419        self.set_window_pos_with_cond(pos, crate::Condition::Always);
420    }
421
422    /// Sets the position of the current window with a condition.
423    #[doc(alias = "SetWindowPos")]
424    pub fn set_window_pos_with_cond(&self, pos: [f32; 2], cond: crate::Condition) {
425        let pos_vec = sys::ImVec2_c {
426            x: pos[0],
427            y: pos[1],
428        };
429        unsafe { sys::igSetWindowPos_Vec2(pos_vec, cond as sys::ImGuiCond) }
430    }
431
432    /// Sets the position of a named window.
433    #[doc(alias = "SetWindowPos")]
434    pub fn set_window_pos_by_name(&self, name: impl AsRef<str>, pos: [f32; 2]) {
435        self.set_window_pos_by_name_with_cond(name, pos, crate::Condition::Always);
436    }
437
438    /// Sets the position of a named window with a condition.
439    #[doc(alias = "SetWindowPos")]
440    pub fn set_window_pos_by_name_with_cond(
441        &self,
442        name: impl AsRef<str>,
443        pos: [f32; 2],
444        cond: crate::Condition,
445    ) {
446        let pos_vec = sys::ImVec2_c {
447            x: pos[0],
448            y: pos[1],
449        };
450        unsafe { sys::igSetWindowPos_Str(self.scratch_txt(name), pos_vec, cond as sys::ImGuiCond) }
451    }
452
453    /// Sets the size of the current window.
454    #[doc(alias = "SetWindowSize")]
455    pub fn set_window_size(&self, size: [f32; 2]) {
456        self.set_window_size_with_cond(size, crate::Condition::Always);
457    }
458
459    /// Sets the size of the current window with a condition.
460    #[doc(alias = "SetWindowSize")]
461    pub fn set_window_size_with_cond(&self, size: [f32; 2], cond: crate::Condition) {
462        let size_vec = sys::ImVec2_c {
463            x: size[0],
464            y: size[1],
465        };
466        unsafe { sys::igSetWindowSize_Vec2(size_vec, cond as sys::ImGuiCond) }
467    }
468
469    /// Sets the size of a named window.
470    #[doc(alias = "SetWindowSize")]
471    pub fn set_window_size_by_name(&self, name: impl AsRef<str>, size: [f32; 2]) {
472        self.set_window_size_by_name_with_cond(name, size, crate::Condition::Always);
473    }
474
475    /// Sets the size of a named window with a condition.
476    #[doc(alias = "SetWindowSize")]
477    pub fn set_window_size_by_name_with_cond(
478        &self,
479        name: impl AsRef<str>,
480        size: [f32; 2],
481        cond: crate::Condition,
482    ) {
483        let size_vec = sys::ImVec2_c {
484            x: size[0],
485            y: size[1],
486        };
487        unsafe {
488            sys::igSetWindowSize_Str(self.scratch_txt(name), size_vec, cond as sys::ImGuiCond);
489        }
490    }
491
492    /// Collapses or expands the current window.
493    #[doc(alias = "SetWindowCollapsed")]
494    pub fn set_window_collapsed(&self, collapsed: bool) {
495        self.set_window_collapsed_with_cond(collapsed, crate::Condition::Always);
496    }
497
498    /// Collapses or expands the current window with a condition.
499    #[doc(alias = "SetWindowCollapsed")]
500    pub fn set_window_collapsed_with_cond(&self, collapsed: bool, cond: crate::Condition) {
501        unsafe { sys::igSetWindowCollapsed_Bool(collapsed, cond as sys::ImGuiCond) }
502    }
503
504    /// Collapses or expands a named window.
505    #[doc(alias = "SetWindowCollapsed")]
506    pub fn set_window_collapsed_by_name(&self, name: impl AsRef<str>, collapsed: bool) {
507        self.set_window_collapsed_by_name_with_cond(name, collapsed, crate::Condition::Always);
508    }
509
510    /// Collapses or expands a named window with a condition.
511    #[doc(alias = "SetWindowCollapsed")]
512    pub fn set_window_collapsed_by_name_with_cond(
513        &self,
514        name: impl AsRef<str>,
515        collapsed: bool,
516        cond: crate::Condition,
517    ) {
518        unsafe {
519            sys::igSetWindowCollapsed_Str(
520                self.scratch_txt(name),
521                collapsed,
522                cond as sys::ImGuiCond,
523            );
524        }
525    }
526
527    /// Set next item to be open by default.
528    ///
529    /// This is useful for tree nodes, collapsing headers, etc.
530    #[doc(alias = "SetNextItemOpen")]
531    pub fn set_next_item_open(&self, is_open: bool) {
532        unsafe {
533            sys::igSetNextItemOpen(is_open, 0); // 0 = ImGuiCond_Always
534        }
535    }
536
537    /// Set next item to be open by default with condition.
538    #[doc(alias = "SetNextItemOpen")]
539    pub fn set_next_item_open_with_cond(&self, is_open: bool, cond: crate::Condition) {
540        unsafe { sys::igSetNextItemOpen(is_open, cond as sys::ImGuiCond) }
541    }
542
543    /// Set next item width.
544    ///
545    /// Set to 0.0 for default width, >0.0 for explicit width, <0.0 for relative width.
546    #[doc(alias = "SetNextItemWidth")]
547    pub fn set_next_item_width(&self, item_width: f32) {
548        unsafe {
549            sys::igSetNextItemWidth(item_width);
550        }
551    }
552
553    // ============================================================================
554    // Style Access
555    // ============================================================================
556
557    /// Returns a shared reference to the current [`Style`].
558    ///
559    /// ## Safety
560    ///
561    /// This function is tagged as `unsafe` because pushing via
562    /// [`push_style_color`](crate::Ui::push_style_color) or
563    /// [`push_style_var`](crate::Ui::push_style_var) or popping via
564    /// [`ColorStackToken::pop`](crate::ColorStackToken::pop) or
565    /// [`StyleStackToken::pop`](crate::StyleStackToken::pop) will modify the values in the returned
566    /// shared reference. Therefore, you should not retain this reference across calls to push and
567    /// pop. The [`clone_style`](Ui::clone_style) version may instead be used to avoid `unsafe`.
568    #[doc(alias = "GetStyle")]
569    pub unsafe fn style(&self) -> &crate::Style {
570        unsafe {
571            // safe because Style is a transparent wrapper around sys::ImGuiStyle
572            &*(sys::igGetStyle() as *const crate::Style)
573        }
574    }
575
576    /// Returns a copy of the current style.
577    ///
578    /// This is a safe alternative to [`style`](Self::style) that avoids the lifetime issues.
579    #[doc(alias = "GetStyle")]
580    pub fn clone_style(&self) -> crate::Style {
581        unsafe { self.style().clone() }
582    }
583
584    /// Apply the built-in Dark style to the current style.
585    #[doc(alias = "StyleColorsDark")]
586    pub fn style_colors_dark(&self) {
587        unsafe { sys::igStyleColorsDark(std::ptr::null_mut()) }
588    }
589
590    /// Apply the built-in Light style to the current style.
591    #[doc(alias = "StyleColorsLight")]
592    pub fn style_colors_light(&self) {
593        unsafe { sys::igStyleColorsLight(std::ptr::null_mut()) }
594    }
595
596    /// Apply the built-in Classic style to the current style.
597    #[doc(alias = "StyleColorsClassic")]
598    pub fn style_colors_classic(&self) {
599        unsafe { sys::igStyleColorsClassic(std::ptr::null_mut()) }
600    }
601
602    /// Write the Dark style values into the provided [`Style`] object.
603    #[doc(alias = "StyleColorsDark")]
604    pub fn style_colors_dark_into(&self, dst: &mut crate::Style) {
605        unsafe { sys::igStyleColorsDark(dst.raw_mut() as *mut sys::ImGuiStyle) }
606    }
607
608    /// Write the Light style values into the provided [`Style`] object.
609    #[doc(alias = "StyleColorsLight")]
610    pub fn style_colors_light_into(&self, dst: &mut crate::Style) {
611        unsafe { sys::igStyleColorsLight(dst.raw_mut() as *mut sys::ImGuiStyle) }
612    }
613
614    /// Write the Classic style values into the provided [`Style`] object.
615    #[doc(alias = "StyleColorsClassic")]
616    pub fn style_colors_classic_into(&self, dst: &mut crate::Style) {
617        unsafe { sys::igStyleColorsClassic(dst.raw_mut() as *mut sys::ImGuiStyle) }
618    }
619
620    /// Returns DPI scale currently associated to the current window's viewport.
621    #[doc(alias = "GetWindowDpiScale")]
622    pub fn window_dpi_scale(&self) -> f32 {
623        unsafe { sys::igGetWindowDpiScale() }
624    }
625
626    /// Display a text label with a boolean value (for quick debug UIs).
627    #[doc(alias = "Value")]
628    pub fn value_bool(&self, prefix: impl AsRef<str>, v: bool) {
629        unsafe { sys::igValue_Bool(self.scratch_txt(prefix), v) }
630    }
631
632    /// Get current window width (shortcut for `GetWindowSize().x`).
633    #[doc(alias = "GetWindowWidth")]
634    pub fn window_width(&self) -> f32 {
635        unsafe { sys::igGetWindowWidth() }
636    }
637
638    /// Get current window height (shortcut for `GetWindowSize().y`).
639    #[doc(alias = "GetWindowHeight")]
640    pub fn window_height(&self) -> f32 {
641        unsafe { sys::igGetWindowHeight() }
642    }
643
644    /// Get current window position in screen space.
645    #[doc(alias = "GetWindowPos")]
646    pub fn window_pos(&self) -> [f32; 2] {
647        let v = unsafe { sys::igGetWindowPos() };
648        [v.x, v.y]
649    }
650
651    /// Get current window size.
652    #[doc(alias = "GetWindowSize")]
653    pub fn window_size(&self) -> [f32; 2] {
654        let v = unsafe { sys::igGetWindowSize() };
655        [v.x, v.y]
656    }
657
658    // ============================================================================
659    // Additional Demo, Debug, Information (non-duplicate methods)
660    // ============================================================================
661
662    /// Renders a debug log window.
663    ///
664    /// Displays a simplified log of important dear imgui events.
665    #[doc(alias = "ShowDebugLogWindow")]
666    pub fn show_debug_log_window(&self, opened: &mut bool) {
667        unsafe {
668            sys::igShowDebugLogWindow(opened);
669        }
670    }
671
672    /// Renders an ID stack tool window.
673    ///
674    /// Hover items with mouse to query information about the source of their unique ID.
675    #[doc(alias = "ShowIDStackToolWindow")]
676    pub fn show_id_stack_tool_window(&self, opened: &mut bool) {
677        unsafe {
678            sys::igShowIDStackToolWindow(opened);
679        }
680    }
681
682    /// Renders a style selector combo box.
683    ///
684    /// Returns true when a different style was selected.
685    #[doc(alias = "ShowStyleSelector")]
686    pub fn show_style_selector(&self, label: impl AsRef<str>) -> bool {
687        unsafe { sys::igShowStyleSelector(self.scratch_txt(label)) }
688    }
689
690    /// Renders a font selector combo box.
691    #[doc(alias = "ShowFontSelector")]
692    pub fn show_font_selector(&self, label: impl AsRef<str>) {
693        unsafe {
694            sys::igShowFontSelector(self.scratch_txt(label));
695        }
696    }
697
698    /// Returns the Dear ImGui version string
699    #[doc(alias = "GetVersion")]
700    pub fn get_version(&self) -> &str {
701        unsafe {
702            let version_ptr = sys::igGetVersion();
703            if version_ptr.is_null() {
704                return "Unknown";
705            }
706            let c_str = std::ffi::CStr::from_ptr(version_ptr);
707            c_str.to_str().unwrap_or("Unknown")
708        }
709    }
710}