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