Skip to main content

dear_implot/plots/
image.rs

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