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