1use crate::{XAxis, YAxis, compat_ffi, sys};
4use dear_imgui_rs::with_scratch_txt;
5
6pub fn is_plot_hovered() -> bool {
8 unsafe { sys::ImPlot_IsPlotHovered() }
9}
10
11pub fn is_subplots_hovered() -> bool {
13 unsafe { sys::ImPlot_IsSubplotsHovered() }
14}
15
16pub fn is_legend_entry_hovered(label: &str) -> bool {
18 let label = if label.contains('\0') { "" } else { label };
19 with_scratch_txt(label, |ptr| unsafe {
20 sys::ImPlot_IsLegendEntryHovered(ptr)
21 })
22}
23
24pub fn get_plot_mouse_position(y_axis_choice: Option<crate::YAxisChoice>) -> sys::ImPlotPoint {
26 let x_axis = 0; let y_axis = match y_axis_choice {
28 Some(crate::YAxisChoice::First) => 3, Some(crate::YAxisChoice::Second) => 4, Some(crate::YAxisChoice::Third) => 5, None => 3, };
33 unsafe { sys::ImPlot_GetPlotMousePos(x_axis as sys::ImAxis, y_axis as sys::ImAxis) }
34}
35
36pub fn get_plot_mouse_position_axes(x_axis: XAxis, y_axis: YAxis) -> sys::ImPlotPoint {
38 unsafe { sys::ImPlot_GetPlotMousePos(x_axis as sys::ImAxis, y_axis as sys::ImAxis) }
39}
40
41pub fn pixels_to_plot(
43 pixel_position: [f32; 2],
44 y_axis_choice: Option<crate::YAxisChoice>,
45) -> sys::ImPlotPoint {
46 let y_index = match y_axis_choice {
48 Some(crate::YAxisChoice::First) => 0,
49 Some(crate::YAxisChoice::Second) => 1,
50 Some(crate::YAxisChoice::Third) => 2,
51 None => 0,
52 };
53 unsafe {
54 let plot = sys::ImPlot_GetCurrentPlot();
55 if plot.is_null() {
56 return sys::ImPlotPoint { x: 0.0, y: 0.0 };
57 }
58 let x_axis_ptr = sys::ImPlotPlot_XAxis_Nil(plot, 0);
59 let y_axis_ptr = sys::ImPlotPlot_YAxis_Nil(plot, y_index);
60 let x = sys::ImPlotAxis_PixelsToPlot(x_axis_ptr, pixel_position[0]);
61 let y = sys::ImPlotAxis_PixelsToPlot(y_axis_ptr, pixel_position[1]);
62 sys::ImPlotPoint { x, y }
63 }
64}
65
66pub fn pixels_to_plot_axes(
68 pixel_position: [f32; 2],
69 x_axis: XAxis,
70 y_axis: YAxis,
71) -> sys::ImPlotPoint {
72 unsafe {
73 let plot = sys::ImPlot_GetCurrentPlot();
74 if plot.is_null() {
75 return sys::ImPlotPoint { x: 0.0, y: 0.0 };
76 }
77 let x_axis_ptr = sys::ImPlotPlot_XAxis_Nil(plot, x_axis as i32);
78 let y_axis_ptr = sys::ImPlotPlot_YAxis_Nil(plot, y_axis.to_index());
79 let x = sys::ImPlotAxis_PixelsToPlot(x_axis_ptr, pixel_position[0]);
80 let y = sys::ImPlotAxis_PixelsToPlot(y_axis_ptr, pixel_position[1]);
81 sys::ImPlotPoint { x, y }
82 }
83}
84
85pub fn plot_to_pixels(
87 plot_position: sys::ImPlotPoint,
88 y_axis_choice: Option<crate::YAxisChoice>,
89) -> [f32; 2] {
90 let y_index = match y_axis_choice {
91 Some(crate::YAxisChoice::First) => 0,
92 Some(crate::YAxisChoice::Second) => 1,
93 Some(crate::YAxisChoice::Third) => 2,
94 None => 0,
95 };
96 unsafe {
97 let plot = sys::ImPlot_GetCurrentPlot();
98 if plot.is_null() {
99 return [0.0, 0.0];
100 }
101 let x_axis_ptr = sys::ImPlotPlot_XAxis_Nil(plot, 0);
102 let y_axis_ptr = sys::ImPlotPlot_YAxis_Nil(plot, y_index);
103 let px = sys::ImPlotAxis_PlotToPixels(x_axis_ptr, plot_position.x);
104 let py = sys::ImPlotAxis_PlotToPixels(y_axis_ptr, plot_position.y);
105 [px, py]
106 }
107}
108
109pub fn plot_to_pixels_axes(
111 plot_position: sys::ImPlotPoint,
112 x_axis: XAxis,
113 y_axis: YAxis,
114) -> [f32; 2] {
115 unsafe {
116 let plot = sys::ImPlot_GetCurrentPlot();
117 if plot.is_null() {
118 return [0.0, 0.0];
119 }
120 let x_axis_ptr = sys::ImPlotPlot_XAxis_Nil(plot, x_axis as i32);
121 let y_axis_ptr = sys::ImPlotPlot_YAxis_Nil(plot, y_axis.to_index());
122 let px = sys::ImPlotAxis_PlotToPixels(x_axis_ptr, plot_position.x);
123 let py = sys::ImPlotAxis_PlotToPixels(y_axis_ptr, plot_position.y);
124 [px, py]
125 }
126}
127
128pub fn get_plot_limits(
130 _x_axis_choice: Option<crate::YAxisChoice>,
131 y_axis_choice: Option<crate::YAxisChoice>,
132) -> sys::ImPlotRect {
133 let x_axis = 0; let y_axis = match y_axis_choice {
135 Some(crate::YAxisChoice::First) => 3, Some(crate::YAxisChoice::Second) => 4, Some(crate::YAxisChoice::Third) => 5, None => 3, };
140 unsafe { sys::ImPlot_GetPlotLimits(x_axis, y_axis) }
141}
142
143pub fn is_plot_selected() -> bool {
145 unsafe { sys::ImPlot_IsPlotSelected() }
146}
147
148pub fn get_plot_selection_axes(x_axis: XAxis, y_axis: YAxis) -> Option<sys::ImPlotRect> {
150 if !is_plot_selected() {
151 return None;
152 }
153 let rect = unsafe { sys::ImPlot_GetPlotSelection(x_axis as i32, y_axis as i32) };
154 Some(rect)
155}
156
157pub fn annotation_point(
159 x: f64,
160 y: f64,
161 color: [f32; 4],
162 pixel_offset: [f32; 2],
163 clamp: bool,
164 round: bool,
165) {
166 let col = sys::ImVec4_c {
167 x: color[0],
168 y: color[1],
169 z: color[2],
170 w: color[3],
171 };
172 let off = sys::ImVec2_c {
173 x: pixel_offset[0],
174 y: pixel_offset[1],
175 };
176 unsafe { sys::ImPlot_Annotation_Bool(x, y, col, off, clamp, round) }
177}
178
179pub fn annotation_text(
184 x: f64,
185 y: f64,
186 color: [f32; 4],
187 pixel_offset: [f32; 2],
188 clamp: bool,
189 text: &str,
190) {
191 let col = sys::ImVec4_c {
192 x: color[0],
193 y: color[1],
194 z: color[2],
195 w: color[3],
196 };
197 let off = sys::ImVec2_c {
198 x: pixel_offset[0],
199 y: pixel_offset[1],
200 };
201 assert!(!text.contains('\0'), "text contained NUL");
202 with_scratch_txt(text, |ptr| unsafe {
203 compat_ffi::ImPlot_Annotation_Str0(x, y, col, off, clamp, ptr)
204 })
205}
206
207pub fn tag_x(x: f64, color: [f32; 4], round: bool) {
209 let col = sys::ImVec4_c {
210 x: color[0],
211 y: color[1],
212 z: color[2],
213 w: color[3],
214 };
215 unsafe { sys::ImPlot_TagX_Bool(x, col, round) }
216}
217
218pub fn tag_x_text(x: f64, color: [f32; 4], text: &str) {
220 let col = sys::ImVec4_c {
221 x: color[0],
222 y: color[1],
223 z: color[2],
224 w: color[3],
225 };
226 assert!(!text.contains('\0'), "text contained NUL");
227 with_scratch_txt(text, |ptr| unsafe {
228 compat_ffi::ImPlot_TagX_Str0(x, col, ptr)
229 })
230}
231
232pub fn tag_y(y: f64, color: [f32; 4], round: bool) {
234 let col = sys::ImVec4_c {
235 x: color[0],
236 y: color[1],
237 z: color[2],
238 w: color[3],
239 };
240 unsafe { sys::ImPlot_TagY_Bool(y, col, round) }
241}
242
243pub fn tag_y_text(y: f64, color: [f32; 4], text: &str) {
245 let col = sys::ImVec4_c {
246 x: color[0],
247 y: color[1],
248 z: color[2],
249 w: color[3],
250 };
251 assert!(!text.contains('\0'), "text contained NUL");
252 with_scratch_txt(text, |ptr| unsafe {
253 compat_ffi::ImPlot_TagY_Str0(y, col, ptr)
254 })
255}
256
257pub fn get_plot_limits_axes(x_axis: XAxis, y_axis: YAxis) -> sys::ImPlotRect {
259 unsafe { sys::ImPlot_GetPlotLimits(x_axis as i32, y_axis as i32) }
260}
261
262pub fn is_axis_hovered(axis: i32) -> bool {
264 unsafe { sys::ImPlot_IsAxisHovered(axis) }
265}
266
267pub fn is_plot_x_axis_hovered() -> bool {
269 is_axis_hovered(XAxis::X1 as i32)
270}
271
272pub fn is_plot_x_axis_hovered_axis(x_axis: XAxis) -> bool {
274 is_axis_hovered(x_axis as i32)
275}
276
277pub fn is_plot_y_axis_hovered(y_axis_choice: Option<crate::YAxisChoice>) -> bool {
279 let y_axis = match y_axis_choice {
280 Some(crate::YAxisChoice::First) => 3, Some(crate::YAxisChoice::Second) => 4, Some(crate::YAxisChoice::Third) => 5, None => 3, };
285 is_axis_hovered(y_axis)
286}
287
288pub fn is_plot_y_axis_hovered_axis(y_axis: YAxis) -> bool {
290 is_axis_hovered(y_axis as i32)
291}
292
293#[cfg(feature = "demo")]
295pub fn show_demo_window(show: &mut bool) {
296 unsafe { sys::ImPlot_ShowDemoWindow(show) }
297}
298
299#[cfg(not(feature = "demo"))]
301pub fn show_demo_window(_show: &mut bool) {}
302
303pub fn show_user_guide() {
305 unsafe { sys::ImPlot_ShowUserGuide() }
306}
307
308pub fn show_metrics_window(open: &mut bool) {
310 unsafe { sys::ImPlot_ShowMetricsWindow(open as *mut bool) }
311}
312
313pub fn get_plot_pos() -> [f32; 2] {
315 let out = unsafe { crate::compat_ffi::ImPlot_GetPlotPos() };
316 [out.x, out.y]
317}
318
319pub fn get_plot_size() -> [f32; 2] {
321 let out = unsafe { crate::compat_ffi::ImPlot_GetPlotSize() };
322 [out.x, out.y]
323}
324
325pub fn get_plot_draw_list() -> *mut sys::ImDrawList {
327 unsafe { sys::ImPlot_GetPlotDrawList() }
328}
329
330pub fn push_plot_clip_rect(expand: f32) {
332 unsafe { sys::ImPlot_PushPlotClipRect(expand) }
333}
334
335pub fn pop_plot_clip_rect() {
337 unsafe { sys::ImPlot_PopPlotClipRect() }
338}
339
340#[derive(Debug, Clone, Copy, Default)]
342pub struct DragResult {
343 pub changed: bool,
345 pub clicked: bool,
347 pub hovered: bool,
349 pub held: bool,
351}
352
353fn color4(rgba: [f32; 4]) -> sys::ImVec4_c {
354 sys::ImVec4_c {
355 x: rgba[0],
356 y: rgba[1],
357 z: rgba[2],
358 w: rgba[3],
359 }
360}
361
362pub fn drag_point(
364 id: i32,
365 x: &mut f64,
366 y: &mut f64,
367 color: [f32; 4],
368 size: f32,
369 flags: crate::DragToolFlags,
370) -> DragResult {
371 let mut clicked = false;
372 let mut hovered = false;
373 let mut held = false;
374 let changed = unsafe {
375 sys::ImPlot_DragPoint(
376 id,
377 x as *mut f64,
378 y as *mut f64,
379 color4(color),
380 size,
381 flags.bits() as i32,
382 &mut clicked as *mut bool,
383 &mut hovered as *mut bool,
384 &mut held as *mut bool,
385 )
386 };
387 DragResult {
388 changed,
389 clicked,
390 hovered,
391 held,
392 }
393}
394
395pub fn drag_line_x(
397 id: i32,
398 x: &mut f64,
399 color: [f32; 4],
400 thickness: f32,
401 flags: crate::DragToolFlags,
402) -> DragResult {
403 let mut clicked = false;
404 let mut hovered = false;
405 let mut held = false;
406 let changed = unsafe {
407 sys::ImPlot_DragLineX(
408 id,
409 x as *mut f64,
410 color4(color),
411 thickness,
412 flags.bits() as i32,
413 &mut clicked as *mut bool,
414 &mut hovered as *mut bool,
415 &mut held as *mut bool,
416 )
417 };
418 DragResult {
419 changed,
420 clicked,
421 hovered,
422 held,
423 }
424}
425
426pub fn drag_line_y(
428 id: i32,
429 y: &mut f64,
430 color: [f32; 4],
431 thickness: f32,
432 flags: crate::DragToolFlags,
433) -> DragResult {
434 let mut clicked = false;
435 let mut hovered = false;
436 let mut held = false;
437 let changed = unsafe {
438 sys::ImPlot_DragLineY(
439 id,
440 y as *mut f64,
441 color4(color),
442 thickness,
443 flags.bits() as i32,
444 &mut clicked as *mut bool,
445 &mut hovered as *mut bool,
446 &mut held as *mut bool,
447 )
448 };
449 DragResult {
450 changed,
451 clicked,
452 hovered,
453 held,
454 }
455}