1#![allow(
7 clippy::cast_possible_truncation,
8 clippy::cast_sign_loss,
9 clippy::as_conversions,
10 clippy::unnecessary_cast
11)]
12use crate::Ui;
13use crate::fonts::FontId;
14use crate::style::{StyleColor, StyleVar, validate_style_color, validate_style_var};
15use crate::sys;
16
17impl Ui {
19 #[doc(alias = "PushFont")]
42 pub fn push_font(&self, id: FontId) -> FontStackToken<'_> {
43 let font_ptr = id.0 as *mut sys::ImFont;
46 unsafe { sys::igPushFont(font_ptr, 0.0) };
47 FontStackToken::new(self)
48 }
49
50 #[doc(alias = "PushStyleColor")]
66 pub fn push_style_color(
67 &self,
68 style_color: StyleColor,
69 color: impl Into<[f32; 4]>,
70 ) -> ColorStackToken<'_> {
71 let color_array = color.into();
72 validate_style_color("Ui::push_style_color()", "color", color_array);
73 unsafe {
74 sys::igPushStyleColor_Vec4(
75 style_color as i32,
76 sys::ImVec4 {
77 x: color_array[0],
78 y: color_array[1],
79 z: color_array[2],
80 w: color_array[3],
81 },
82 )
83 };
84 ColorStackToken::new(self)
85 }
86
87 #[doc(alias = "PushStyleVar")]
103 pub fn push_style_var(&self, style_var: StyleVar) -> StyleStackToken<'_> {
104 validate_style_var("Ui::push_style_var()", style_var);
105 unsafe { push_style_var(style_var) };
106 StyleStackToken::new(self)
107 }
108}
109
110create_token!(
111 pub struct FontStackToken<'ui>;
114
115 drop { unsafe { sys::igPopFont() } }
117);
118
119impl FontStackToken<'_> {
120 pub fn pop(self) {
122 self.end()
123 }
124}
125
126create_token!(
127 pub struct ColorStackToken<'ui>;
130
131 drop { unsafe { sys::igPopStyleColor(1) } }
133);
134
135impl ColorStackToken<'_> {
136 pub fn pop(self) {
138 self.end()
139 }
140}
141
142create_token!(
143 pub struct StyleStackToken<'ui>;
146
147 drop { unsafe { sys::igPopStyleVar(1) } }
149);
150
151impl StyleStackToken<'_> {
152 pub fn pop(self) {
154 self.end()
155 }
156}
157
158unsafe fn push_style_var(style_var: StyleVar) {
160 use StyleVar::*;
161 match style_var {
162 Alpha(v) => unsafe { sys::igPushStyleVar_Float(sys::ImGuiStyleVar_Alpha as i32, v) },
163 DisabledAlpha(v) => unsafe {
164 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_DisabledAlpha as i32, v)
165 },
166 WindowPadding(v) => {
167 let p: [f32; 2] = v;
168 let vec = sys::ImVec2 { x: p[0], y: p[1] };
169 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_WindowPadding as i32, vec) }
170 }
171 WindowRounding(v) => unsafe {
172 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_WindowRounding as i32, v)
173 },
174 WindowBorderSize(v) => unsafe {
175 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_WindowBorderSize as i32, v)
176 },
177 WindowMinSize(v) => {
178 let p: [f32; 2] = v;
179 let vec = sys::ImVec2 { x: p[0], y: p[1] };
180 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_WindowMinSize as i32, vec) }
181 }
182 WindowTitleAlign(v) => {
183 let p: [f32; 2] = v;
184 let vec = sys::ImVec2 { x: p[0], y: p[1] };
185 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_WindowTitleAlign as i32, vec) }
186 }
187 ChildRounding(v) => unsafe {
188 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ChildRounding as i32, v)
189 },
190 ChildBorderSize(v) => unsafe {
191 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ChildBorderSize as i32, v)
192 },
193 PopupRounding(v) => unsafe {
194 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_PopupRounding as i32, v)
195 },
196 PopupBorderSize(v) => unsafe {
197 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_PopupBorderSize as i32, v)
198 },
199 FramePadding(v) => {
200 let p: [f32; 2] = v;
201 let vec = sys::ImVec2 { x: p[0], y: p[1] };
202 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_FramePadding as i32, vec) }
203 }
204 FrameRounding(v) => unsafe {
205 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_FrameRounding as i32, v)
206 },
207 FrameBorderSize(v) => unsafe {
208 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_FrameBorderSize as i32, v)
209 },
210 ItemSpacing(v) => {
211 let p: [f32; 2] = v;
212 let vec = sys::ImVec2 { x: p[0], y: p[1] };
213 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_ItemSpacing as i32, vec) }
214 }
215 ItemInnerSpacing(v) => {
216 let p: [f32; 2] = v;
217 let vec = sys::ImVec2 { x: p[0], y: p[1] };
218 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_ItemInnerSpacing as i32, vec) }
219 }
220 IndentSpacing(v) => unsafe {
221 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_IndentSpacing as i32, v)
222 },
223 CellPadding(v) => {
224 let p: [f32; 2] = v;
225 let vec = sys::ImVec2 { x: p[0], y: p[1] };
226 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_CellPadding as i32, vec) }
227 }
228 ScrollbarSize(v) => unsafe {
229 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ScrollbarSize as i32, v)
230 },
231 ScrollbarRounding(v) => unsafe {
232 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ScrollbarRounding as i32, v)
233 },
234 ScrollbarPadding(v) => unsafe {
235 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ScrollbarPadding as i32, v)
236 },
237 GrabMinSize(v) => unsafe {
238 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_GrabMinSize as i32, v)
239 },
240 GrabRounding(v) => unsafe {
241 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_GrabRounding as i32, v)
242 },
243 ImageRounding(v) => unsafe {
244 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ImageRounding as i32, v)
245 },
246 ImageBorderSize(v) => unsafe {
247 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ImageBorderSize as i32, v)
248 },
249 TabRounding(v) => unsafe {
250 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabRounding as i32, v)
251 },
252 TabBorderSize(v) => unsafe {
253 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabBorderSize as i32, v)
254 },
255 TabMinWidthBase(v) => unsafe {
256 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabMinWidthBase as i32, v)
257 },
258 TabMinWidthShrink(v) => unsafe {
259 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabMinWidthShrink as i32, v)
260 },
261 TabBarBorderSize(v) => unsafe {
262 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabBarBorderSize as i32, v)
263 },
264 TabBarOverlineSize(v) => unsafe {
265 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabBarOverlineSize as i32, v)
266 },
267 TableAngledHeadersAngle(v) => unsafe {
268 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TableAngledHeadersAngle as i32, v)
269 },
270 TableAngledHeadersTextAlign(v) => {
271 let p: [f32; 2] = v;
272 let vec = sys::ImVec2 { x: p[0], y: p[1] };
273 unsafe {
274 sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_TableAngledHeadersTextAlign as i32, vec)
275 }
276 }
277 TreeLinesSize(v) => unsafe {
278 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TreeLinesSize as i32, v)
279 },
280 TreeLinesRounding(v) => unsafe {
281 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TreeLinesRounding as i32, v)
282 },
283 DragDropTargetRounding(v) => unsafe {
284 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_DragDropTargetRounding as i32, v)
285 },
286 ButtonTextAlign(v) => {
287 let p: [f32; 2] = v;
288 let vec = sys::ImVec2 { x: p[0], y: p[1] };
289 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_ButtonTextAlign as i32, vec) }
290 }
291 SelectableTextAlign(v) => {
292 let p: [f32; 2] = v;
293 let vec = sys::ImVec2 { x: p[0], y: p[1] };
294 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_SelectableTextAlign as i32, vec) }
295 }
296 SeparatorSize(v) => unsafe {
297 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_SeparatorSize as i32, v)
298 },
299 SeparatorTextBorderSize(v) => unsafe {
300 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_SeparatorTextBorderSize as i32, v)
301 },
302 SeparatorTextAlign(v) => {
303 let p: [f32; 2] = v;
304 let vec = sys::ImVec2 { x: p[0], y: p[1] };
305 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_SeparatorTextAlign as i32, vec) }
306 }
307 SeparatorTextPadding(v) => {
308 let p: [f32; 2] = v;
309 let vec = sys::ImVec2 { x: p[0], y: p[1] };
310 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_SeparatorTextPadding as i32, vec) }
311 }
312 DockingSeparatorSize(v) => unsafe {
313 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_DockingSeparatorSize as i32, v)
314 },
315 }
316}
317
318impl Ui {
320 #[doc(alias = "PushItemWidth")]
330 pub fn push_item_width(&self, item_width: f32) -> ItemWidthStackToken<'_> {
331 unsafe { sys::igPushItemWidth(item_width) };
332 ItemWidthStackToken::new(self)
333 }
334
335 #[doc(alias = "PushItemWidth")]
340 pub fn push_item_width_text(&self, text: impl AsRef<str>) -> ItemWidthStackToken<'_> {
341 let text_width = unsafe {
342 let text_ptr = self.scratch_txt(text);
343 let out = sys::igCalcTextSize(text_ptr, std::ptr::null(), false, -1.0);
344 out.x
345 };
346 self.push_item_width(text_width)
347 }
348
349 #[doc(alias = "PushTextWrapPos")]
358 pub fn push_text_wrap_pos(&self, wrap_pos_x: f32) -> TextWrapPosStackToken<'_> {
359 unsafe { sys::igPushTextWrapPos(wrap_pos_x) };
360 TextWrapPosStackToken::new(self)
361 }
362}
363
364create_token!(
365 pub struct ItemWidthStackToken<'ui>;
368
369 #[doc(alias = "PopItemWidth")]
371 drop { unsafe { sys::igPopItemWidth() } }
372);
373
374create_token!(
375 pub struct TextWrapPosStackToken<'ui>;
378
379 #[doc(alias = "PopTextWrapPos")]
381 drop { unsafe { sys::igPopTextWrapPos() } }
382);
383
384impl Ui {
386 #[doc(alias = "PushID")]
420 pub fn push_id<'a, T: Into<Id<'a>>>(&self, id: T) -> IdStackToken<'_> {
421 let id = id.into();
422 unsafe {
423 match id {
424 Id::Int(i) => sys::igPushID_Int(i),
425 Id::Str(s) => sys::igPushID_Str(self.scratch_txt(s)),
426 Id::Ptr(p) => sys::igPushID_Ptr(p),
427 }
428 }
429 IdStackToken::new(self)
430 }
431}
432
433create_token!(
434 pub struct IdStackToken<'ui>;
437
438 drop { unsafe { sys::igPopID() } }
440);
441
442impl IdStackToken<'_> {
443 pub fn pop(self) {
445 self.end()
446 }
447}
448
449create_token!(
454 pub struct FocusScopeToken<'ui>;
456
457 #[doc(alias = "PopFocusScope")]
459 drop { unsafe { sys::igPopFocusScope() } }
460);
461
462impl Ui {
463 #[doc(alias = "PushFocusScope")]
467 pub fn push_focus_scope(&self, id: sys::ImGuiID) -> FocusScopeToken<'_> {
468 unsafe { sys::igPushFocusScope(id) };
469 FocusScopeToken::new(self)
470 }
471}
472
473#[derive(Copy, Clone, Debug)]
475pub enum Id<'a> {
476 Int(i32),
478 Str(&'a str),
480 Ptr(*const std::ffi::c_void),
482}
483
484impl From<i32> for Id<'_> {
485 fn from(i: i32) -> Self {
486 Id::Int(i)
487 }
488}
489
490impl From<usize> for Id<'_> {
491 fn from(i: usize) -> Self {
492 Id::Int(i as i32)
493 }
494}
495
496impl<'a> From<&'a str> for Id<'a> {
497 fn from(s: &'a str) -> Self {
498 Id::Str(s)
499 }
500}
501
502impl<'a> From<&'a String> for Id<'a> {
503 fn from(s: &'a String) -> Self {
504 Id::Str(s.as_str())
505 }
506}
507
508impl<T> From<*const T> for Id<'_> {
509 fn from(p: *const T) -> Self {
510 Id::Ptr(p as *const std::ffi::c_void)
511 }
512}
513
514impl<T> From<*mut T> for Id<'_> {
515 fn from(p: *mut T) -> Self {
516 Id::Ptr(p as *const std::ffi::c_void)
517 }
518}