1#![allow(
2 clippy::cast_possible_truncation,
3 clippy::cast_sign_loss,
4 clippy::as_conversions
5)]
6use crate::Ui;
7use crate::fonts::FontId;
8use crate::style::{StyleColor, StyleVar};
9use crate::sys;
10
11impl Ui {
13 #[doc(alias = "PushFont")]
36 pub fn push_font(&self, id: FontId) -> FontStackToken<'_> {
37 let font_ptr = id.0 as *mut sys::ImFont;
40 unsafe { sys::igPushFont(font_ptr, 0.0) };
41 FontStackToken::new(self)
42 }
43
44 #[doc(alias = "PushStyleColor")]
60 pub fn push_style_color(
61 &self,
62 style_color: StyleColor,
63 color: impl Into<[f32; 4]>,
64 ) -> ColorStackToken<'_> {
65 let color_array = color.into();
66 unsafe {
67 sys::igPushStyleColor_Vec4(
68 style_color as i32,
69 sys::ImVec4 {
70 x: color_array[0],
71 y: color_array[1],
72 z: color_array[2],
73 w: color_array[3],
74 },
75 )
76 };
77 ColorStackToken::new(self)
78 }
79
80 #[doc(alias = "PushStyleVar")]
96 pub fn push_style_var(&self, style_var: StyleVar) -> StyleStackToken<'_> {
97 unsafe { push_style_var(style_var) };
98 StyleStackToken::new(self)
99 }
100}
101
102create_token!(
103 pub struct FontStackToken<'ui>;
106
107 drop { unsafe { sys::igPopFont() } }
109);
110
111impl FontStackToken<'_> {
112 pub fn pop(self) {
114 self.end()
115 }
116}
117
118create_token!(
119 pub struct ColorStackToken<'ui>;
122
123 drop { unsafe { sys::igPopStyleColor(1) } }
125);
126
127impl ColorStackToken<'_> {
128 pub fn pop(self) {
130 self.end()
131 }
132}
133
134create_token!(
135 pub struct StyleStackToken<'ui>;
138
139 drop { unsafe { sys::igPopStyleVar(1) } }
141);
142
143impl StyleStackToken<'_> {
144 pub fn pop(self) {
146 self.end()
147 }
148}
149
150unsafe fn push_style_var(style_var: StyleVar) {
152 use StyleVar::*;
153 match style_var {
154 Alpha(v) => unsafe { sys::igPushStyleVar_Float(sys::ImGuiStyleVar_Alpha as i32, v) },
155 DisabledAlpha(v) => unsafe {
156 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_DisabledAlpha as i32, v)
157 },
158 WindowPadding(v) => {
159 let p: [f32; 2] = v;
160 let vec = sys::ImVec2 { x: p[0], y: p[1] };
161 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_WindowPadding as i32, vec) }
162 }
163 WindowRounding(v) => unsafe {
164 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_WindowRounding as i32, v)
165 },
166 WindowBorderSize(v) => unsafe {
167 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_WindowBorderSize as i32, v)
168 },
169 WindowMinSize(v) => {
170 let p: [f32; 2] = v;
171 let vec = sys::ImVec2 { x: p[0], y: p[1] };
172 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_WindowMinSize as i32, vec) }
173 }
174 WindowTitleAlign(v) => {
175 let p: [f32; 2] = v;
176 let vec = sys::ImVec2 { x: p[0], y: p[1] };
177 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_WindowTitleAlign as i32, vec) }
178 }
179 ChildRounding(v) => unsafe {
180 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ChildRounding as i32, v)
181 },
182 ChildBorderSize(v) => unsafe {
183 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ChildBorderSize as i32, v)
184 },
185 PopupRounding(v) => unsafe {
186 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_PopupRounding as i32, v)
187 },
188 PopupBorderSize(v) => unsafe {
189 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_PopupBorderSize as i32, v)
190 },
191 FramePadding(v) => {
192 let p: [f32; 2] = v;
193 let vec = sys::ImVec2 { x: p[0], y: p[1] };
194 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_FramePadding as i32, vec) }
195 }
196 FrameRounding(v) => unsafe {
197 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_FrameRounding as i32, v)
198 },
199 FrameBorderSize(v) => unsafe {
200 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_FrameBorderSize as i32, v)
201 },
202 ItemSpacing(v) => {
203 let p: [f32; 2] = v;
204 let vec = sys::ImVec2 { x: p[0], y: p[1] };
205 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_ItemSpacing as i32, vec) }
206 }
207 ItemInnerSpacing(v) => {
208 let p: [f32; 2] = v;
209 let vec = sys::ImVec2 { x: p[0], y: p[1] };
210 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_ItemInnerSpacing as i32, vec) }
211 }
212 IndentSpacing(v) => unsafe {
213 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_IndentSpacing as i32, v)
214 },
215 CellPadding(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_CellPadding as i32, vec) }
219 }
220 ScrollbarSize(v) => unsafe {
221 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ScrollbarSize as i32, v)
222 },
223 ScrollbarRounding(v) => unsafe {
224 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_ScrollbarRounding as i32, v)
225 },
226 GrabMinSize(v) => unsafe {
227 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_GrabMinSize as i32, v)
228 },
229 GrabRounding(v) => unsafe {
230 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_GrabRounding as i32, v)
231 },
232 TabRounding(v) => unsafe {
233 sys::igPushStyleVar_Float(sys::ImGuiStyleVar_TabRounding as i32, v)
234 },
235 ButtonTextAlign(v) => {
236 let p: [f32; 2] = v;
237 let vec = sys::ImVec2 { x: p[0], y: p[1] };
238 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_ButtonTextAlign as i32, vec) }
239 }
240 SelectableTextAlign(v) => {
241 let p: [f32; 2] = v;
242 let vec = sys::ImVec2 { x: p[0], y: p[1] };
243 unsafe { sys::igPushStyleVar_Vec2(sys::ImGuiStyleVar_SelectableTextAlign as i32, vec) }
244 }
245 }
246}
247
248impl Ui {
250 #[doc(alias = "PushItemWidth")]
260 pub fn push_item_width(&self, item_width: f32) -> ItemWidthStackToken<'_> {
261 unsafe { sys::igPushItemWidth(item_width) };
262 ItemWidthStackToken::new(self)
263 }
264
265 #[doc(alias = "PushItemWidth")]
270 pub fn push_item_width_text(&self, text: impl AsRef<str>) -> ItemWidthStackToken<'_> {
271 let text_width = {
272 let text_ptr = self.scratch_txt(text);
273 let mut out = sys::ImVec2 { x: 0.0, y: 0.0 };
274 unsafe { sys::igCalcTextSize(&mut out, text_ptr, std::ptr::null(), false, -1.0) };
275 out.x
276 };
277 self.push_item_width(text_width)
278 }
279
280 #[doc(alias = "PushTextWrapPos")]
289 pub fn push_text_wrap_pos(&self, wrap_pos_x: f32) -> TextWrapPosStackToken<'_> {
290 unsafe { sys::igPushTextWrapPos(wrap_pos_x) };
291 TextWrapPosStackToken::new(self)
292 }
293}
294
295create_token!(
296 pub struct ItemWidthStackToken<'ui>;
299
300 #[doc(alias = "PopItemWidth")]
302 drop { unsafe { sys::igPopItemWidth() } }
303);
304
305create_token!(
306 pub struct TextWrapPosStackToken<'ui>;
309
310 #[doc(alias = "PopTextWrapPos")]
312 drop { unsafe { sys::igPopTextWrapPos() } }
313);
314
315impl Ui {
317 #[doc(alias = "PushID")]
351 pub fn push_id<'a, T: Into<Id<'a>>>(&self, id: T) -> IdStackToken<'_> {
352 let id = id.into();
353 unsafe {
354 match id {
355 Id::Int(i) => sys::igPushID_Int(i),
356 Id::Str(s) => sys::igPushID_Str(self.scratch_txt(s)),
357 Id::Ptr(p) => sys::igPushID_Ptr(p),
358 }
359 }
360 IdStackToken::new(self)
361 }
362}
363
364create_token!(
365 pub struct IdStackToken<'ui>;
368
369 drop { unsafe { sys::igPopID() } }
371);
372
373impl IdStackToken<'_> {
374 pub fn pop(self) {
376 self.end()
377 }
378}
379
380create_token!(
385 pub struct FocusScopeToken<'ui>;
387
388 #[doc(alias = "PopFocusScope")]
390 drop { unsafe { sys::igPopFocusScope() } }
391);
392
393impl Ui {
394 #[doc(alias = "PushFocusScope")]
398 pub fn push_focus_scope(&self, id: sys::ImGuiID) -> FocusScopeToken<'_> {
399 unsafe { sys::igPushFocusScope(id) };
400 FocusScopeToken::new(self)
401 }
402}
403
404#[derive(Copy, Clone, Debug)]
406pub enum Id<'a> {
407 Int(i32),
409 Str(&'a str),
411 Ptr(*const std::ffi::c_void),
413}
414
415impl From<i32> for Id<'_> {
416 fn from(i: i32) -> Self {
417 Id::Int(i)
418 }
419}
420
421impl From<usize> for Id<'_> {
422 fn from(i: usize) -> Self {
423 Id::Int(i as i32)
424 }
425}
426
427impl<'a> From<&'a str> for Id<'a> {
428 fn from(s: &'a str) -> Self {
429 Id::Str(s)
430 }
431}
432
433impl<'a> From<&'a String> for Id<'a> {
434 fn from(s: &'a String) -> Self {
435 Id::Str(s.as_str())
436 }
437}
438
439impl<T> From<*const T> for Id<'_> {
440 fn from(p: *const T) -> Self {
441 Id::Ptr(p as *const std::ffi::c_void)
442 }
443}
444
445impl<T> From<*mut T> for Id<'_> {
446 fn from(p: *mut T) -> Self {
447 Id::Ptr(p as *const std::ffi::c_void)
448 }
449}