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 self.with_bound_context(|| {
12 unsafe { sys::ImPlot3D_PushColormap_Plot3DColormap(cmap.into().raw()) }
13 ColormapToken {
14 binding: self.binding.clone(),
15 was_popped: false,
16 _lifetime: PhantomData,
17 _not_send_or_sync: PhantomData,
18 }
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 self.with_bound_context(|| {
26 dear_imgui_rs::with_scratch_txt(name, |ptr| unsafe {
27 sys::ImPlot3D_PushColormap_Str(ptr)
28 });
29 ColormapToken {
30 binding: self.binding.clone(),
31 was_popped: false,
32 _lifetime: PhantomData,
33 _not_send_or_sync: PhantomData,
34 }
35 })
36 }
37}
38
39pub(super) fn colormap_count_from_i32(raw: i32, caller: &str) -> usize {
40 assert!(raw >= 0, "{caller} returned a negative colormap count");
41 usize::try_from(raw).expect("non-negative colormap count must fit usize")
42}
43
44impl Plot3DContext {
45 #[inline]
46 fn with_bound_colormap<R>(&self, _caller: &str, f: impl FnOnce() -> R) -> R {
47 self.binding().with_bound_context(|| 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 =
163 sys::ImPlot3D_GetColormapColor(index.raw(), (-1) as sys::ImPlot3DColormap);
164 [out.x, out.y, out.z, out.w]
165 },
166 )
167 }
168
169 pub fn next_colormap_color(&self) -> [f32; 4] {
171 self.with_bound_colormap(
172 "dear-implot3d: Plot3DContext::next_colormap_color()",
173 || unsafe {
174 let out = sys::ImPlot3D_NextColormapColor();
175 [out.x, out.y, out.z, out.w]
176 },
177 )
178 }
179}
180
181impl Plot3DUi<'_> {
182 pub fn colormap_color(&self, index: ColormapColorIndex) -> [f32; 4] {
184 self.with_bound_context(|| unsafe {
185 let out = sys::ImPlot3D_GetColormapColor(index.raw(), (-1) as sys::ImPlot3DColormap);
186 [out.x, out.y, out.z, out.w]
187 })
188 }
189
190 pub fn next_colormap_color(&self) -> [f32; 4] {
192 self.with_bound_context(|| unsafe {
193 let out = sys::ImPlot3D_NextColormapColor();
194 [out.x, out.y, out.z, out.w]
195 })
196 }
197}