dear_implot/plots/
image.rs

1//! Image plot implementation
2
3use super::{Plot, PlotError, with_plot_str_or_empty};
4use crate::{ImageFlags, sys};
5
6/// Plot an image in plot coordinates using an ImTextureID
7pub struct ImagePlot<'a> {
8    label: &'a str,
9    tex_id: sys::ImTextureID,
10    bounds_min: sys::ImPlotPoint,
11    bounds_max: sys::ImPlotPoint,
12    uv0: [f32; 2],
13    uv1: [f32; 2],
14    tint: [f32; 4],
15    flags: ImageFlags,
16}
17
18impl<'a> ImagePlot<'a> {
19    pub fn new(
20        label: &'a str,
21        tex_id: sys::ImTextureID,
22        bounds_min: sys::ImPlotPoint,
23        bounds_max: sys::ImPlotPoint,
24    ) -> Self {
25        Self {
26            label,
27            tex_id,
28            bounds_min,
29            bounds_max,
30            uv0: [0.0, 0.0],
31            uv1: [1.0, 1.0],
32            tint: [1.0, 1.0, 1.0, 1.0],
33            flags: ImageFlags::NONE,
34        }
35    }
36
37    pub fn with_uv(mut self, uv0: [f32; 2], uv1: [f32; 2]) -> Self {
38        self.uv0 = uv0;
39        self.uv1 = uv1;
40        self
41    }
42    pub fn with_tint(mut self, tint: [f32; 4]) -> Self {
43        self.tint = tint;
44        self
45    }
46    pub fn with_flags(mut self, flags: ImageFlags) -> Self {
47        self.flags = flags;
48        self
49    }
50
51    pub fn validate(&self) -> Result<(), PlotError> {
52        Ok(())
53    }
54}
55
56impl<'a> Plot for ImagePlot<'a> {
57    fn plot(&self) {
58        if self.validate().is_err() {
59            return;
60        }
61        let uv0 = sys::ImVec2_c {
62            x: self.uv0[0],
63            y: self.uv0[1],
64        };
65        let uv1 = sys::ImVec2_c {
66            x: self.uv1[0],
67            y: self.uv1[1],
68        };
69        let tint = sys::ImVec4_c {
70            x: self.tint[0],
71            y: self.tint[1],
72            z: self.tint[2],
73            w: self.tint[3],
74        };
75        // Construct ImTextureRef from ImTextureID
76        let tex_ref = sys::ImTextureRef_c {
77            _TexData: std::ptr::null_mut(),
78            _TexID: self.tex_id,
79        };
80        with_plot_str_or_empty(self.label, |label_ptr| unsafe {
81            sys::ImPlot_PlotImage(
82                label_ptr,
83                tex_ref,
84                self.bounds_min,
85                self.bounds_max,
86                uv0,
87                uv1,
88                tint,
89                self.flags.bits() as i32,
90            )
91        })
92    }
93
94    fn label(&self) -> &str {
95        self.label
96    }
97}
98
99/// Convenience methods on PlotUi
100impl<'ui> crate::PlotUi<'ui> {
101    pub fn plot_image(
102        &self,
103        label: &str,
104        tex_id: sys::ImTextureID,
105        bounds_min: sys::ImPlotPoint,
106        bounds_max: sys::ImPlotPoint,
107    ) -> Result<(), PlotError> {
108        let plot = ImagePlot::new(label, tex_id, bounds_min, bounds_max);
109        plot.validate()?;
110        plot.plot();
111        Ok(())
112    }
113
114    /// Plot an image using ImGui's TextureId wrapper (if available)
115    #[allow(unused_variables)]
116    pub fn plot_image_with_imgui_texture(
117        &self,
118        label: &str,
119        texture: dear_imgui_rs::TextureId,
120        bounds_min: sys::ImPlotPoint,
121        bounds_max: sys::ImPlotPoint,
122    ) -> Result<(), PlotError> {
123        // ImTextureID is ImU64 in the shared dear-imgui-sys bindings.
124        let raw: sys::ImTextureID = texture.id();
125        self.plot_image(label, raw, bounds_min, bounds_max)
126    }
127}