Skip to main content

dear_implot/plots/
image.rs

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