dear_implot/plots/
dummy.rs1use super::{PlotData, PlotError, with_plot_str_or_empty};
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 with_plot_str_or_empty(self.label, |label_ptr| unsafe {
42 sys::ImPlot_PlotDummy(label_ptr, self.flags.bits() as i32);
43 })
44 }
45}
46
47impl<'a> PlotData for DummyPlot<'a> {
48 fn label(&self) -> &str {
49 self.label
50 }
51
52 fn data_len(&self) -> usize {
53 0 }
55}
56
57pub struct MultiDummyPlot<'a> {
59 labels: Vec<&'a str>,
60 flags: DummyFlags,
61}
62
63impl<'a> MultiDummyPlot<'a> {
64 pub fn new(labels: Vec<&'a str>) -> Self {
66 Self {
67 labels,
68 flags: DummyFlags::NONE,
69 }
70 }
71
72 pub fn with_flags(mut self, flags: DummyFlags) -> Self {
74 self.flags = flags;
75 self
76 }
77
78 pub fn validate(&self) -> Result<(), PlotError> {
80 if self.labels.is_empty() {
81 return Err(PlotError::EmptyData);
82 }
83
84 for (i, &label) in self.labels.iter().enumerate() {
85 if label.is_empty() {
86 return Err(PlotError::InvalidData(format!(
87 "Label at index {} cannot be empty",
88 i
89 )));
90 }
91 }
92
93 Ok(())
94 }
95
96 pub fn plot(self) {
98 for &label in &self.labels {
99 let dummy_plot = DummyPlot::new(label).with_flags(self.flags);
100 dummy_plot.plot();
101 }
102 }
103}
104
105impl<'a> PlotData for MultiDummyPlot<'a> {
106 fn label(&self) -> &str {
107 "MultiDummy"
108 }
109
110 fn data_len(&self) -> usize {
111 self.labels.len()
112 }
113}
114
115pub struct LegendSeparator<'a> {
117 label: &'a str,
118}
119
120impl<'a> LegendSeparator<'a> {
121 pub fn new(label: &'a str) -> Self {
123 Self { label }
124 }
125
126 pub fn empty() -> Self {
128 Self { label: "---" }
129 }
130
131 pub fn plot(self) {
133 let dummy_plot = DummyPlot::new(self.label);
134 dummy_plot.plot();
135 }
136}
137
138pub struct LegendHeader<'a> {
140 title: &'a str,
141}
142
143impl<'a> LegendHeader<'a> {
144 pub fn new(title: &'a str) -> Self {
146 Self { title }
147 }
148
149 pub fn plot(self) {
151 let dummy_plot = DummyPlot::new(self.title);
152 dummy_plot.plot();
153 }
154}
155
156pub struct CustomLegendEntry<'a> {
158 label: &'a str,
159 flags: DummyFlags,
160}
161
162impl<'a> CustomLegendEntry<'a> {
163 pub fn new(label: &'a str) -> Self {
165 Self {
166 label,
167 flags: DummyFlags::NONE,
168 }
169 }
170
171 pub fn with_flags(mut self, flags: DummyFlags) -> Self {
173 self.flags = flags;
174 self
175 }
176
177 pub fn plot(self) {
179 let dummy_plot = DummyPlot::new(self.label).with_flags(self.flags);
180 dummy_plot.plot();
181 }
182}
183
184pub struct LegendGroup<'a> {
186 title: &'a str,
187 entries: Vec<&'a str>,
188 add_separator: bool,
189}
190
191impl<'a> LegendGroup<'a> {
192 pub fn new(title: &'a str, entries: Vec<&'a str>) -> Self {
194 Self {
195 title,
196 entries,
197 add_separator: true,
198 }
199 }
200
201 pub fn no_separator(mut self) -> Self {
203 self.add_separator = false;
204 self
205 }
206
207 pub fn plot(self) {
209 LegendHeader::new(self.title).plot();
211
212 for &entry in &self.entries {
214 DummyPlot::new(entry).plot();
215 }
216
217 if self.add_separator && !self.entries.is_empty() {
219 LegendSeparator::empty().plot();
220 }
221 }
222}
223
224impl<'a> DummyPlot<'a> {
226 pub fn separator() -> DummyPlot<'static> {
228 DummyPlot::new("---")
229 }
230
231 pub fn spacer() -> DummyPlot<'static> {
233 DummyPlot::new(" ")
234 }
235
236 pub fn header(title: &'a str) -> DummyPlot<'a> {
238 DummyPlot::new(title)
239 }
240}
241
242#[macro_export]
244macro_rules! dummy_plots {
245 ($($label:expr),* $(,)?) => {
246 {
247 let labels = vec![$($label),*];
248 $crate::plots::dummy::MultiDummyPlot::new(labels)
249 }
250 };
251}
252
253#[macro_export]
255macro_rules! legend_group {
256 ($title:expr, $($entry:expr),* $(,)?) => {
257 {
258 let entries = vec![$($entry),*];
259 $crate::plots::dummy::LegendGroup::new($title, entries)
260 }
261 };
262}