dear_implot3d/style/
colormap.rs1use crate::sys;
2use crate::{Plot3DContext, Plot3DUi};
3
4use super::tokens::ColormapToken;
5use super::types::{ColormapColorIndex, ColormapIndex};
6use std::marker::PhantomData;
7
8impl<'ui> Plot3DUi<'ui> {
9 #[inline]
10 pub fn push_colormap(&self, cmap: impl Into<ColormapIndex>) -> ColormapToken<'_> {
11 let _guard = self.bind();
12 unsafe { sys::ImPlot3D_PushColormap_Plot3DColormap(cmap.into().raw()) }
13 ColormapToken {
14 binding: self.binding,
15 imgui_alive: self.imgui_alive.clone(),
16 was_popped: false,
17 _lifetime: PhantomData,
18 _not_send_or_sync: PhantomData,
19 }
20 }
21
22 #[inline]
23 pub fn push_colormap_name(&self, name: &str) -> ColormapToken<'_> {
24 assert!(!name.contains('\0'), "colormap name contained NUL");
25 let _guard = self.bind();
26 dear_imgui_rs::with_scratch_txt(name, |ptr| unsafe { sys::ImPlot3D_PushColormap_Str(ptr) });
27 ColormapToken {
28 binding: self.binding,
29 imgui_alive: self.imgui_alive.clone(),
30 was_popped: false,
31 _lifetime: PhantomData,
32 _not_send_or_sync: PhantomData,
33 }
34 }
35}
36
37pub(super) fn colormap_count_from_i32(raw: i32, caller: &str) -> usize {
38 assert!(raw >= 0, "{caller} returned a negative colormap count");
39 usize::try_from(raw).expect("non-negative colormap count must fit usize")
40}
41
42impl Plot3DContext {
43 #[inline]
44 fn with_bound_colormap<R>(&self, caller: &str, f: impl FnOnce() -> R) -> R {
45 self.assert_imgui_alive(caller);
46 let _guard = self.binding().bind();
47 f()
48 }
49
50 #[inline]
52 pub fn colormap_count(&self) -> usize {
53 self.with_bound_colormap("dear-implot3d: Plot3DContext::colormap_count()", || {
54 colormap_count_from_i32(
55 unsafe { sys::ImPlot3D_GetColormapCount() },
56 "Plot3DContext::colormap_count()",
57 )
58 })
59 }
60
61 #[inline]
63 pub fn colormap_name(&self, index: impl Into<ColormapIndex>) -> String {
64 self.with_bound_colormap("dear-implot3d: Plot3DContext::colormap_name()", || unsafe {
65 let p = sys::ImPlot3D_GetColormapName(index.into().raw());
66 if p.is_null() {
67 return String::new();
68 }
69 std::ffi::CStr::from_ptr(p).to_string_lossy().into_owned()
70 })
71 }
72
73 #[inline]
75 pub fn colormap_size(&self, index: impl Into<ColormapIndex>) -> usize {
76 self.with_bound_colormap("dear-implot3d: Plot3DContext::colormap_size()", || {
77 colormap_count_from_i32(
78 unsafe { sys::ImPlot3D_GetColormapSize(index.into().raw()) },
79 "Plot3DContext::colormap_size()",
80 )
81 })
82 }
83
84 #[inline]
86 pub fn style_colormap_index(&self) -> Option<ColormapIndex> {
87 self.with_bound_colormap(
88 "dear-implot3d: Plot3DContext::style_colormap_index()",
89 || unsafe {
90 let style = sys::ImPlot3D_GetStyle();
91 if style.is_null() {
92 return None;
93 }
94 ColormapIndex::from_raw((*style).Colormap)
95 },
96 )
97 }
98
99 #[inline]
101 pub fn style_colormap_name(&self) -> Option<String> {
102 let idx = self.style_colormap_index()?;
103 let count = self.colormap_count();
104 if idx.get() >= count {
105 return None;
106 }
107 Some(self.colormap_name(idx))
108 }
109
110 #[inline]
112 pub fn set_style_colormap(&self, index: impl Into<ColormapIndex>) {
113 self.with_bound_colormap(
114 "dear-implot3d: Plot3DContext::set_style_colormap()",
115 || unsafe {
116 let style = sys::ImPlot3D_GetStyle();
117 if !style.is_null() {
118 let count = colormap_count_from_i32(
119 sys::ImPlot3D_GetColormapCount(),
120 "Plot3DContext::set_style_colormap()",
121 );
122 if count > 0 {
123 let index = index.into().get();
124 let idx = index.min(count - 1);
125 (*style).Colormap = ColormapIndex::from(idx).raw();
126 }
127 }
128 },
129 )
130 }
131
132 #[inline]
134 pub fn colormap_index_by_name(&self, name: &str) -> Option<ColormapIndex> {
135 if name.contains('\0') {
136 return None;
137 }
138 let index = self.with_bound_colormap(
139 "dear-implot3d: Plot3DContext::colormap_index_by_name()",
140 || {
141 dear_imgui_rs::with_scratch_txt(name, |ptr| unsafe {
142 sys::ImPlot3D_GetColormapIndex(ptr)
143 })
144 },
145 );
146 ColormapIndex::from_raw(index)
147 }
148
149 #[inline]
151 pub fn set_style_colormap_by_name(&self, name: &str) {
152 if let Some(idx) = self.colormap_index_by_name(name) {
153 self.set_style_colormap(idx);
154 }
155 }
156
157 pub fn colormap_color(&self, index: ColormapColorIndex) -> [f32; 4] {
159 self.with_bound_colormap(
160 "dear-implot3d: Plot3DContext::colormap_color()",
161 || unsafe {
162 let out = crate::compat_ffi::ImPlot3D_GetColormapColor(
163 index.raw(),
164 (-1) as sys::ImPlot3DColormap,
165 );
166 [out.x, out.y, out.z, out.w]
167 },
168 )
169 }
170
171 pub fn next_colormap_color(&self) -> [f32; 4] {
173 self.with_bound_colormap(
174 "dear-implot3d: Plot3DContext::next_colormap_color()",
175 || unsafe {
176 let out = crate::compat_ffi::ImPlot3D_NextColormapColor();
177 [out.x, out.y, out.z, out.w]
178 },
179 )
180 }
181}
182
183impl Plot3DUi<'_> {
184 pub fn colormap_color(&self, index: ColormapColorIndex) -> [f32; 4] {
186 let _guard = self.bind();
187 unsafe {
188 let out = crate::compat_ffi::ImPlot3D_GetColormapColor(
189 index.raw(),
190 (-1) as sys::ImPlot3DColormap,
191 );
192 [out.x, out.y, out.z, out.w]
193 }
194 }
195
196 pub fn next_colormap_color(&self) -> [f32; 4] {
198 let _guard = self.bind();
199 unsafe {
200 let out = crate::compat_ffi::ImPlot3D_NextColormapColor();
201 [out.x, out.y, out.z, out.w]
202 }
203 }
204}