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