Skip to main content

dear_imgui_rs/ui/
style.rs

1use super::*;
2
3impl Ui {
4    /// Renders a style editor block (not a window) for the given `Style` structure.
5    ///
6    /// The safe editor retains all upstream style controls except its destructive Fonts tab.
7    /// Font selection and font-scale controls remain available because they do not mutate the
8    /// atlas topology.
9    #[doc(alias = "ShowStyleEditor")]
10    pub fn show_style_editor(&self, style: &mut crate::style::Style) {
11        self.run_with_bound_context(|| unsafe {
12            crate::sys::dear_imgui_rs_show_style_editor_without_font_atlas(style.raw_mut());
13        });
14    }
15
16    /// Renders a style editor block (not a window) for the currently active style.
17    ///
18    /// The safe editor retains all upstream style controls except its destructive Fonts tab.
19    #[doc(alias = "ShowStyleEditor")]
20    pub fn show_default_style_editor(&self) {
21        self.run_with_bound_context(|| unsafe {
22            crate::sys::dear_imgui_rs_show_style_editor_without_font_atlas(std::ptr::null_mut());
23        });
24    }
25
26    /// Renders the exact upstream style editor for the given `Style` structure.
27    ///
28    /// Prefer [`show_style_editor`](Self::show_style_editor) unless the application deliberately
29    /// owns the full font-atlas mutation contract.
30    ///
31    /// # Safety
32    ///
33    /// The upstream Fonts tab exposes destructive font-atlas operations that bypass Rust's atlas
34    /// generation tracking. The caller must uphold the native font-atlas contract.
35    pub unsafe fn show_upstream_style_editor(&self, style: &mut crate::style::Style) {
36        self.run_with_bound_context(|| unsafe {
37            crate::sys::igShowStyleEditor(style.raw_mut());
38        });
39    }
40
41    /// Renders the exact upstream style editor for the active style.
42    ///
43    /// # Safety
44    ///
45    /// The upstream Fonts tab exposes destructive font-atlas operations that bypass Rust's atlas
46    /// generation tracking. The caller must uphold the native font-atlas contract.
47    pub unsafe fn show_upstream_default_style_editor(&self) {
48        self.run_with_bound_context(|| unsafe {
49            crate::sys::igShowStyleEditor(std::ptr::null_mut());
50        });
51    }
52
53    // ============================================================================
54    // Style Access
55    // ============================================================================
56
57    /// Returns a shared reference to the current [`crate::Style`].
58    ///
59    /// ## Safety
60    ///
61    /// This function is tagged as `unsafe` because pushing via
62    /// [`push_style_color`](crate::Ui::push_style_color) or
63    /// [`push_style_var`](crate::Ui::push_style_var) or popping via
64    /// [`ColorStackToken::pop`](crate::ColorStackToken::pop) or
65    /// [`StyleStackToken::pop`](crate::StyleStackToken::pop) will modify the values in the returned
66    /// shared reference. Therefore, you should not retain this reference across calls to push and
67    /// pop. The [`clone_style`](Ui::clone_style) version may instead be used to avoid `unsafe`.
68    #[doc(alias = "GetStyle")]
69    pub unsafe fn style(&self) -> &crate::Style {
70        self.run_with_bound_context(|| unsafe {
71            // safe because Style is a transparent wrapper around sys::ImGuiStyle
72            &*(sys::igGetStyle() as *const crate::Style)
73        })
74    }
75
76    /// Returns a copy of the current style.
77    ///
78    /// This is a safe alternative to [`style`](Self::style) that avoids the lifetime issues.
79    #[doc(alias = "GetStyle")]
80    pub fn clone_style(&self) -> crate::Style {
81        unsafe { self.style().clone() }
82    }
83
84    /// Apply the built-in Dark style to the current style.
85    #[doc(alias = "StyleColorsDark")]
86    pub fn style_colors_dark(&self) {
87        self.run_with_bound_context(|| unsafe { sys::igStyleColorsDark(std::ptr::null_mut()) });
88    }
89
90    /// Apply the built-in Light style to the current style.
91    #[doc(alias = "StyleColorsLight")]
92    pub fn style_colors_light(&self) {
93        self.run_with_bound_context(|| unsafe { sys::igStyleColorsLight(std::ptr::null_mut()) });
94    }
95
96    /// Apply the built-in Classic style to the current style.
97    #[doc(alias = "StyleColorsClassic")]
98    pub fn style_colors_classic(&self) {
99        self.run_with_bound_context(|| unsafe { sys::igStyleColorsClassic(std::ptr::null_mut()) });
100    }
101
102    /// Write the Dark style values into the provided [`crate::Style`] object.
103    #[doc(alias = "StyleColorsDark")]
104    pub fn style_colors_dark_into(&self, dst: &mut crate::Style) {
105        self.run_with_bound_context(|| unsafe {
106            sys::igStyleColorsDark(dst.raw_mut() as *mut sys::ImGuiStyle)
107        });
108    }
109
110    /// Write the Light style values into the provided [`crate::Style`] object.
111    #[doc(alias = "StyleColorsLight")]
112    pub fn style_colors_light_into(&self, dst: &mut crate::Style) {
113        self.run_with_bound_context(|| unsafe {
114            sys::igStyleColorsLight(dst.raw_mut() as *mut sys::ImGuiStyle)
115        });
116    }
117
118    /// Write the Classic style values into the provided [`crate::Style`] object.
119    #[doc(alias = "StyleColorsClassic")]
120    pub fn style_colors_classic_into(&self, dst: &mut crate::Style) {
121        self.run_with_bound_context(|| unsafe {
122            sys::igStyleColorsClassic(dst.raw_mut() as *mut sys::ImGuiStyle)
123        });
124    }
125
126    /// Renders a style selector combo box.
127    ///
128    /// Returns true when a different style was selected.
129    #[doc(alias = "ShowStyleSelector")]
130    pub fn show_style_selector(&self, label: impl AsRef<str>) -> bool {
131        self.run_with_bound_context(|| unsafe { sys::igShowStyleSelector(self.scratch_txt(label)) })
132    }
133
134    /// Renders a font selector combo box.
135    #[doc(alias = "ShowFontSelector")]
136    pub fn show_font_selector(&self, label: impl AsRef<str>) {
137        self.run_with_bound_context(|| unsafe {
138            sys::igShowFontSelector(self.scratch_txt(label));
139        });
140    }
141}
142
143#[cfg(test)]
144mod tests {
145    #[test]
146    fn safe_style_editors_keep_font_atlas_controls_explicit() {
147        let _: fn(&crate::Ui, &mut crate::Style) = crate::Ui::show_style_editor;
148        let _: fn(&crate::Ui) = crate::Ui::show_default_style_editor;
149        let _: unsafe fn(&crate::Ui, &mut crate::Style) = crate::Ui::show_upstream_style_editor;
150        let _: unsafe fn(&crate::Ui) = crate::Ui::show_upstream_default_style_editor;
151    }
152}