dear_imgui_rs/widget/
image.rs

1//! Image widgets
2//!
3//! Draw images from a legacy `TextureId` or from modern `TextureData` handled
4//! via `DrawData::textures()`. See crate-level docs for texture management.
5//!
6//! Quick example (image button):
7//! ```no_run
8//! # use dear_imgui_rs::*;
9//! # let mut ctx = Context::create();
10//! # let ui = ctx.frame();
11//! let tex_id = texture::TextureId::new(42);
12//! if ui.image_button("btn", tex_id, [32.0, 32.0]) {
13//!     // clicked
14//! }
15//! ```
16//!
17use crate::sys;
18use crate::texture::TextureRef;
19use crate::ui::Ui;
20
21/// # Image Widgets
22///
23/// Examples
24/// - Using a plain texture id:
25/// ```no_run
26/// # use dear_imgui_rs::*;
27/// # fn demo(ui: &Ui) {
28/// let tex_id = texture::TextureId::new(0xDEAD_BEEF);
29/// ui.image(tex_id, [128.0, 128.0]);
30/// # }
31/// ```
32/// - Using an ImGui-managed texture:
33/// ```no_run
34/// # use dear_imgui_rs::*;
35/// # fn demo(ui: &Ui) {
36/// let mut tex = texture::TextureData::new();
37/// tex.create(texture::TextureFormat::RGBA32, 64, 64);
38/// ui.image(&mut *tex, [64.0, 64.0]);
39/// # }
40/// ```
41impl Ui {
42    /// Creates an image widget
43    #[doc(alias = "Image")]
44    pub fn image(&self, texture: impl Into<TextureRef>, size: [f32; 2]) {
45        self.image_config(texture, size).build()
46    }
47
48    /// Creates an image button widget
49    #[doc(alias = "ImageButton")]
50    pub fn image_button(
51        &self,
52        str_id: impl AsRef<str>,
53        texture: impl Into<TextureRef>,
54        size: [f32; 2],
55    ) -> bool {
56        self.image_button_config(str_id, texture, size).build()
57    }
58
59    /// Creates an image builder
60    pub fn image_config(&self, texture: impl Into<TextureRef>, size: [f32; 2]) -> Image<'_> {
61        Image::new(self, texture, size)
62    }
63
64    /// Creates an image button builder
65    pub fn image_button_config(
66        &self,
67        str_id: impl AsRef<str>,
68        texture: impl Into<TextureRef>,
69        size: [f32; 2],
70    ) -> ImageButton<'_> {
71        ImageButton::new(self, str_id, texture, size)
72    }
73}
74
75/// Builder for an image widget
76#[derive(Debug)]
77#[must_use]
78pub struct Image<'ui> {
79    ui: &'ui Ui,
80    texture: TextureRef,
81    size: [f32; 2],
82    uv0: [f32; 2],
83    uv1: [f32; 2],
84    tint_color: [f32; 4],
85    border_color: [f32; 4],
86}
87
88impl<'ui> Image<'ui> {
89    /// Creates a new image builder
90    pub fn new(ui: &'ui Ui, texture: impl Into<TextureRef>, size: [f32; 2]) -> Self {
91        Self {
92            ui,
93            texture: texture.into(),
94            size,
95            uv0: [0.0, 0.0],
96            uv1: [1.0, 1.0],
97            tint_color: [1.0, 1.0, 1.0, 1.0],
98            border_color: [0.0, 0.0, 0.0, 0.0],
99        }
100    }
101
102    /// Sets the UV coordinates for the top-left corner (default: [0.0, 0.0])
103    pub fn uv0(mut self, uv0: [f32; 2]) -> Self {
104        self.uv0 = uv0;
105        self
106    }
107
108    /// Sets the UV coordinates for the bottom-right corner (default: [1.0, 1.0])
109    pub fn uv1(mut self, uv1: [f32; 2]) -> Self {
110        self.uv1 = uv1;
111        self
112    }
113
114    /// Sets the tint color (default: white, no tint)
115    pub fn tint_color(mut self, tint_color: [f32; 4]) -> Self {
116        self.tint_color = tint_color;
117        self
118    }
119
120    /// Sets the border color (default: transparent, no border)
121    pub fn border_color(mut self, border_color: [f32; 4]) -> Self {
122        self.border_color = border_color;
123        self
124    }
125
126    /// Builds the image widget
127    pub fn build(self) {
128        let size_vec: sys::ImVec2 = self.size.into();
129        let uv0_vec: sys::ImVec2 = self.uv0.into();
130        let uv1_vec: sys::ImVec2 = self.uv1.into();
131        let _tint_vec: sys::ImVec4 = sys::ImVec4 {
132            x: self.tint_color[0],
133            y: self.tint_color[1],
134            z: self.tint_color[2],
135            w: self.tint_color[3],
136        };
137        let _border_vec: sys::ImVec4 = sys::ImVec4 {
138            x: self.border_color[0],
139            y: self.border_color[1],
140            z: self.border_color[2],
141            w: self.border_color[3],
142        };
143
144        unsafe { sys::igImage(self.texture.raw(), size_vec, uv0_vec, uv1_vec) }
145    }
146
147    /// Builds the image widget with background color and tint (v1.92+)
148    pub fn build_with_bg(self, bg_color: [f32; 4], tint_color: [f32; 4]) {
149        let size_vec: sys::ImVec2 = self.size.into();
150        let uv0_vec: sys::ImVec2 = self.uv0.into();
151        let uv1_vec: sys::ImVec2 = self.uv1.into();
152        let bg_vec = sys::ImVec4 {
153            x: bg_color[0],
154            y: bg_color[1],
155            z: bg_color[2],
156            w: bg_color[3],
157        };
158        let tint_vec = sys::ImVec4 {
159            x: tint_color[0],
160            y: tint_color[1],
161            z: tint_color[2],
162            w: tint_color[3],
163        };
164
165        unsafe {
166            sys::igImageWithBg(
167                self.texture.raw(),
168                size_vec,
169                uv0_vec,
170                uv1_vec,
171                bg_vec,
172                tint_vec,
173            )
174        }
175    }
176}
177
178/// Builder for an image button widget
179#[derive(Debug)]
180#[must_use]
181pub struct ImageButton<'ui> {
182    ui: &'ui Ui,
183    str_id: String,
184    texture: TextureRef,
185    size: [f32; 2],
186    uv0: [f32; 2],
187    uv1: [f32; 2],
188    bg_color: [f32; 4],
189    tint_color: [f32; 4],
190}
191
192impl<'ui> ImageButton<'ui> {
193    /// Creates a new image button builder
194    pub fn new(
195        ui: &'ui Ui,
196        str_id: impl AsRef<str>,
197        texture: impl Into<TextureRef>,
198        size: [f32; 2],
199    ) -> Self {
200        Self {
201            ui,
202            str_id: str_id.as_ref().to_string(),
203            texture: texture.into(),
204            size,
205            uv0: [0.0, 0.0],
206            uv1: [1.0, 1.0],
207            bg_color: [0.0, 0.0, 0.0, 0.0],
208            tint_color: [1.0, 1.0, 1.0, 1.0],
209        }
210    }
211
212    /// Sets the UV coordinates for the top-left corner (default: [0.0, 0.0])
213    pub fn uv0(mut self, uv0: [f32; 2]) -> Self {
214        self.uv0 = uv0;
215        self
216    }
217
218    /// Sets the UV coordinates for the bottom-right corner (default: [1.0, 1.0])
219    pub fn uv1(mut self, uv1: [f32; 2]) -> Self {
220        self.uv1 = uv1;
221        self
222    }
223
224    /// Sets the background color (default: transparent)
225    pub fn bg_color(mut self, bg_color: [f32; 4]) -> Self {
226        self.bg_color = bg_color;
227        self
228    }
229
230    /// Sets the tint color (default: white, no tint)
231    pub fn tint_color(mut self, tint_color: [f32; 4]) -> Self {
232        self.tint_color = tint_color;
233        self
234    }
235
236    /// Builds the image button widget
237    pub fn build(self) -> bool {
238        let str_id_ptr = self.ui.scratch_txt(&self.str_id);
239        let size_vec: sys::ImVec2 = self.size.into();
240        let uv0_vec: sys::ImVec2 = self.uv0.into();
241        let uv1_vec: sys::ImVec2 = self.uv1.into();
242        let bg_vec: sys::ImVec4 = sys::ImVec4 {
243            x: self.bg_color[0],
244            y: self.bg_color[1],
245            z: self.bg_color[2],
246            w: self.bg_color[3],
247        };
248        let tint_vec: sys::ImVec4 = sys::ImVec4 {
249            x: self.tint_color[0],
250            y: self.tint_color[1],
251            z: self.tint_color[2],
252            w: self.tint_color[3],
253        };
254
255        unsafe {
256            sys::igImageButton(
257                str_id_ptr,
258                self.texture.raw(),
259                size_vec,
260                uv0_vec,
261                uv1_vec,
262                bg_vec,
263                tint_vec,
264            )
265        }
266    }
267}