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