dear_implot/plots/
dummy.rs1use super::{PlotData, PlotError, safe_cstring};
4use crate::DummyFlags;
5use crate::sys;
6
7pub struct DummyPlot<'a> {
12 label: &'a str,
13 flags: DummyFlags,
14}
15
16impl<'a> DummyPlot<'a> {
17 pub fn new(label: &'a str) -> Self {
19 Self {
20 label,
21 flags: DummyFlags::NONE,
22 }
23 }
24
25 pub fn with_flags(mut self, flags: DummyFlags) -> Self {
27 self.flags = flags;
28 self
29 }
30
31 pub fn validate(&self) -> Result<(), PlotError> {
33 if self.label.is_empty() {
34 return Err(PlotError::InvalidData("Label cannot be empty".to_string()));
35 }
36 Ok(())
37 }
38
39 pub fn plot(self) {
41 let label_cstring = safe_cstring(self.label);
42
43 unsafe {
44 sys::ImPlot_PlotDummy(label_cstring.as_ptr(), self.flags.bits() as i32);
45 }
46 }
47}
48
49impl<'a> PlotData for DummyPlot<'a> {
50 fn label(&self) -> &str {
51 self.label
52 }
53
54 fn data_len(&self) -> usize {
55 0 }
57}
58
59pub struct MultiDummyPlot<'a> {
61 labels: Vec<&'a str>,
62 flags: DummyFlags,
63}
64
65impl<'a> MultiDummyPlot<'a> {
66 pub fn new(labels: Vec<&'a str>) -> Self {
68 Self {
69 labels,
70 flags: DummyFlags::NONE,
71 }
72 }
73
74 pub fn with_flags(mut self, flags: DummyFlags) -> Self {
76 self.flags = flags;
77 self
78 }
79
80 pub fn validate(&self) -> Result<(), PlotError> {
82 if self.labels.is_empty() {
83 return Err(PlotError::EmptyData);
84 }
85
86 for (i, &label) in self.labels.iter().enumerate() {
87 if label.is_empty() {
88 return Err(PlotError::InvalidData(format!(
89 "Label at index {} cannot be empty",
90 i
91 )));
92 }
93 }
94
95 Ok(())
96 }
97
98 pub fn plot(self) {
100 for &label in &self.labels {
101 let dummy_plot = DummyPlot::new(label).with_flags(self.flags);
102 dummy_plot.plot();
103 }
104 }
105}
106
107impl<'a> PlotData for MultiDummyPlot<'a> {
108 fn label(&self) -> &str {
109 "MultiDummy"
110 }
111
112 fn data_len(&self) -> usize {
113 self.labels.len()
114 }
115}
116
117pub struct LegendSeparator<'a> {
119 label: &'a str,
120}
121
122impl<'a> LegendSeparator<'a> {
123 pub fn new(label: &'a str) -> Self {
125 Self { label }
126 }
127
128 pub fn empty() -> Self {
130 Self { label: "---" }
131 }
132
133 pub fn plot(self) {
135 let dummy_plot = DummyPlot::new(self.label);
136 dummy_plot.plot();
137 }
138}
139
140pub struct LegendHeader<'a> {
142 title: &'a str,
143}
144
145impl<'a> LegendHeader<'a> {
146 pub fn new(title: &'a str) -> Self {
148 Self { title }
149 }
150
151 pub fn plot(self) {
153 let dummy_plot = DummyPlot::new(self.title);
154 dummy_plot.plot();
155 }
156}
157
158pub struct CustomLegendEntry<'a> {
160 label: &'a str,
161 flags: DummyFlags,
162}
163
164impl<'a> CustomLegendEntry<'a> {
165 pub fn new(label: &'a str) -> Self {
167 Self {
168 label,
169 flags: DummyFlags::NONE,
170 }
171 }
172
173 pub fn with_flags(mut self, flags: DummyFlags) -> Self {
175 self.flags = flags;
176 self
177 }
178
179 pub fn plot(self) {
181 let dummy_plot = DummyPlot::new(self.label).with_flags(self.flags);
182 dummy_plot.plot();
183 }
184}
185
186pub struct LegendGroup<'a> {
188 title: &'a str,
189 entries: Vec<&'a str>,
190 add_separator: bool,
191}
192
193impl<'a> LegendGroup<'a> {
194 pub fn new(title: &'a str, entries: Vec<&'a str>) -> Self {
196 Self {
197 title,
198 entries,
199 add_separator: true,
200 }
201 }
202
203 pub fn no_separator(mut self) -> Self {
205 self.add_separator = false;
206 self
207 }
208
209 pub fn plot(self) {
211 LegendHeader::new(self.title).plot();
213
214 for &entry in &self.entries {
216 DummyPlot::new(entry).plot();
217 }
218
219 if self.add_separator && !self.entries.is_empty() {
221 LegendSeparator::empty().plot();
222 }
223 }
224}
225
226impl<'a> DummyPlot<'a> {
228 pub fn separator() -> DummyPlot<'static> {
230 DummyPlot::new("---")
231 }
232
233 pub fn spacer() -> DummyPlot<'static> {
235 DummyPlot::new(" ")
236 }
237
238 pub fn header(title: &'a str) -> DummyPlot<'a> {
240 DummyPlot::new(title)
241 }
242}
243
244#[macro_export]
246macro_rules! dummy_plots {
247 ($($label:expr),* $(,)?) => {
248 {
249 let labels = vec![$($label),*];
250 $crate::plots::dummy::MultiDummyPlot::new(labels)
251 }
252 };
253}
254
255#[macro_export]
257macro_rules! legend_group {
258 ($title:expr, $($entry:expr),* $(,)?) => {
259 {
260 let entries = vec![$($entry),*];
261 $crate::plots::dummy::LegendGroup::new($title, entries)
262 }
263 };
264}