1use crate::sys;
4use dear_imgui_rs::{with_scratch_txt, with_scratch_txt_two};
5use std::os::raw::c_char;
6
7#[repr(i32)]
9#[derive(Copy, Clone, Debug, PartialEq, Eq)]
10pub enum StyleVar {
11 PlotDefaultSize = sys::ImPlotStyleVar_PlotDefaultSize as i32,
12 PlotMinSize = sys::ImPlotStyleVar_PlotMinSize as i32,
13 PlotBorderSize = sys::ImPlotStyleVar_PlotBorderSize as i32,
14 MinorAlpha = sys::ImPlotStyleVar_MinorAlpha as i32,
15 MajorTickLen = sys::ImPlotStyleVar_MajorTickLen as i32,
16 MinorTickLen = sys::ImPlotStyleVar_MinorTickLen as i32,
17 MajorTickSize = sys::ImPlotStyleVar_MajorTickSize as i32,
18 MinorTickSize = sys::ImPlotStyleVar_MinorTickSize as i32,
19 MajorGridSize = sys::ImPlotStyleVar_MajorGridSize as i32,
20 MinorGridSize = sys::ImPlotStyleVar_MinorGridSize as i32,
21 PlotPadding = sys::ImPlotStyleVar_PlotPadding as i32,
22 LabelPadding = sys::ImPlotStyleVar_LabelPadding as i32,
23 LegendPadding = sys::ImPlotStyleVar_LegendPadding as i32,
24 LegendInnerPadding = sys::ImPlotStyleVar_LegendInnerPadding as i32,
25 LegendSpacing = sys::ImPlotStyleVar_LegendSpacing as i32,
26 MousePosPadding = sys::ImPlotStyleVar_MousePosPadding as i32,
27 AnnotationPadding = sys::ImPlotStyleVar_AnnotationPadding as i32,
28 FitPadding = sys::ImPlotStyleVar_FitPadding as i32,
29 DigitalPadding = sys::ImPlotStyleVar_DigitalPadding as i32,
30 DigitalSpacing = sys::ImPlotStyleVar_DigitalSpacing as i32,
31}
32
33pub struct StyleVarToken {
35 was_popped: bool,
36}
37
38impl StyleVarToken {
39 pub fn pop(mut self) {
41 if self.was_popped {
42 panic!("Attempted to pop a style var token twice.");
43 }
44 self.was_popped = true;
45 unsafe {
46 sys::ImPlot_PopStyleVar(1);
47 }
48 }
49}
50
51impl Drop for StyleVarToken {
52 fn drop(&mut self) {
53 if !self.was_popped {
54 unsafe {
55 sys::ImPlot_PopStyleVar(1);
56 }
57 }
58 }
59}
60
61pub struct StyleColorToken {
63 was_popped: bool,
64}
65
66impl StyleColorToken {
67 pub fn pop(mut self) {
69 if self.was_popped {
70 panic!("Attempted to pop a style color token twice.");
71 }
72 self.was_popped = true;
73 unsafe {
74 sys::ImPlot_PopStyleColor(1);
75 }
76 }
77}
78
79impl Drop for StyleColorToken {
80 fn drop(&mut self) {
81 if !self.was_popped {
82 unsafe {
83 sys::ImPlot_PopStyleColor(1);
84 }
85 }
86 }
87}
88
89pub fn push_style_var_f32(var: StyleVar, value: f32) -> StyleVarToken {
91 unsafe {
92 sys::ImPlot_PushStyleVar_Float(var as sys::ImPlotStyleVar, value);
93 }
94 StyleVarToken { was_popped: false }
95}
96
97pub fn push_style_var_i32(var: StyleVar, value: i32) -> StyleVarToken {
99 unsafe {
100 sys::ImPlot_PushStyleVar_Int(var as sys::ImPlotStyleVar, value);
101 }
102 StyleVarToken { was_popped: false }
103}
104
105pub fn push_style_var_vec2(var: StyleVar, value: [f32; 2]) -> StyleVarToken {
107 unsafe {
108 sys::ImPlot_PushStyleVar_Vec2(
109 var as sys::ImPlotStyleVar,
110 sys::ImVec2_c {
111 x: value[0],
112 y: value[1],
113 },
114 );
115 }
116 StyleVarToken { was_popped: false }
117}
118
119pub fn push_style_color(element: crate::PlotColorElement, color: [f32; 4]) -> StyleColorToken {
121 unsafe {
122 let r = (color[0] * 255.0) as u32;
124 let g = (color[1] * 255.0) as u32;
125 let b = (color[2] * 255.0) as u32;
126 let a = (color[3] * 255.0) as u32;
127 let color_u32 = (a << 24) | (b << 16) | (g << 8) | r;
128
129 sys::ImPlot_PushStyleColor_U32(element as sys::ImPlotCol, color_u32);
130 }
131 StyleColorToken { was_popped: false }
132}
133
134pub fn push_colormap(preset: crate::Colormap) {
136 unsafe {
137 sys::ImPlot_PushColormap_PlotColormap(preset as sys::ImPlotColormap);
138 }
139}
140
141pub fn pop_colormap(count: i32) {
143 unsafe {
144 sys::ImPlot_PopColormap(count);
145 }
146}
147
148pub fn add_colormap(name: &str, colors: &[sys::ImVec4], qualitative: bool) -> sys::ImPlotColormap {
150 assert!(!name.contains('\0'), "colormap name contained NUL");
151 let count = i32::try_from(colors.len()).expect("colormap contained too many colors");
152 with_scratch_txt(name, |ptr| unsafe {
153 sys::ImPlot_AddColormap_Vec4Ptr(ptr, colors.as_ptr(), count, qualitative)
154 as sys::ImPlotColormap
155 })
156}
157
158pub fn show_style_editor() {
162 unsafe { sys::ImPlot_ShowStyleEditor(std::ptr::null_mut()) }
163}
164
165pub fn show_style_selector(label: &str) -> bool {
167 let label = if label.contains('\0') { "" } else { label };
168 with_scratch_txt(label, |ptr| unsafe { sys::ImPlot_ShowStyleSelector(ptr) })
169}
170
171pub fn show_colormap_selector(label: &str) -> bool {
173 let label = if label.contains('\0') { "" } else { label };
174 with_scratch_txt(label, |ptr| unsafe {
175 sys::ImPlot_ShowColormapSelector(ptr)
176 })
177}
178
179pub fn show_input_map_selector(label: &str) -> bool {
181 let label = if label.contains('\0') { "" } else { label };
182 with_scratch_txt(label, |ptr| unsafe {
183 sys::ImPlot_ShowInputMapSelector(ptr)
184 })
185}
186
187pub fn map_input_default() {
189 unsafe { sys::ImPlot_MapInputDefault(sys::ImPlot_GetInputMap()) }
190}
191
192pub fn map_input_reverse() {
194 unsafe { sys::ImPlot_MapInputReverse(sys::ImPlot_GetInputMap()) }
195}
196
197pub fn colormap_scale(
201 label: &str,
202 scale_min: f64,
203 scale_max: f64,
204 height: f32,
205 cmap: Option<sys::ImPlotColormap>,
206) {
207 let label = if label.contains('\0') { "" } else { label };
208 let size = sys::ImVec2_c { x: 0.0, y: height };
209 let fmt_ptr: *const c_char = std::ptr::null();
210 let flags: i32 = 0; with_scratch_txt(label, |ptr| unsafe {
212 sys::ImPlot_ColormapScale(
213 ptr,
214 scale_min,
215 scale_max,
216 size,
217 fmt_ptr,
218 flags,
219 cmap.unwrap_or(0),
220 )
221 })
222}
223
224pub fn colormap_slider(
226 label: &str,
227 t: &mut f32,
228 out_color: &mut sys::ImVec4,
229 format: Option<&str>,
230 cmap: sys::ImPlotColormap,
231) -> bool {
232 let label = if label.contains('\0') { "" } else { label };
233 let format = format.filter(|s| !s.contains('\0'));
234
235 match format {
236 Some(fmt) => with_scratch_txt_two(label, fmt, |label_ptr, fmt_ptr| unsafe {
237 sys::ImPlot_ColormapSlider(
238 label_ptr,
239 t as *mut f32,
240 out_color as *mut sys::ImVec4,
241 fmt_ptr,
242 cmap,
243 )
244 }),
245 None => with_scratch_txt(label, |label_ptr| unsafe {
246 sys::ImPlot_ColormapSlider(
247 label_ptr,
248 t as *mut f32,
249 out_color as *mut sys::ImVec4,
250 std::ptr::null(),
251 cmap,
252 )
253 }),
254 }
255}
256
257pub fn colormap_button(label: &str, size: [f32; 2], cmap: sys::ImPlotColormap) -> bool {
259 let label = if label.contains('\0') { "" } else { label };
260 let sz = sys::ImVec2_c {
261 x: size[0],
262 y: size[1],
263 };
264 with_scratch_txt(label, |ptr| unsafe {
265 sys::ImPlot_ColormapButton(ptr, sz, cmap)
266 })
267}