1use crate::Id;
16use crate::draw::DrawListMut;
17use crate::input::MouseCursor;
18use crate::internal::RawWrapper;
19use crate::string::UiBuffer;
20use crate::sys;
21use crate::texture::TextureRef;
22use std::cell::UnsafeCell;
23
24#[derive(Debug)]
26pub struct Ui {
27 buffer: UnsafeCell<UiBuffer>,
29}
30
31impl Ui {
32 #[doc(alias = "GetMainViewport")]
39 pub fn main_viewport(&self) -> &crate::platform_io::Viewport {
40 unsafe {
41 let ptr = sys::igGetMainViewport();
42 if ptr.is_null() {
43 panic!("Ui::main_viewport() requires an active ImGui context");
44 }
45 crate::platform_io::Viewport::from_raw(ptr as *const sys::ImGuiViewport)
46 }
47 }
48 pub(crate) fn new() -> Self {
52 Ui {
53 buffer: UnsafeCell::new(UiBuffer::new(1024)),
54 }
55 }
56
57 #[doc(alias = "GetIO")]
59 pub fn io(&self) -> &crate::io::Io {
60 unsafe {
61 let io = sys::igGetIO_Nil();
62 if io.is_null() {
63 panic!("Ui::io() requires an active ImGui context");
64 }
65 &*(io as *const crate::io::Io)
66 }
67 }
68
69 pub(crate) fn scratch_txt(&self, txt: impl AsRef<str>) -> *const std::os::raw::c_char {
71 unsafe {
72 let handle = &mut *self.buffer.get();
73 handle.scratch_txt(txt)
74 }
75 }
76
77 pub(crate) fn scratch_txt_opt(
79 &self,
80 txt: Option<impl AsRef<str>>,
81 ) -> *const std::os::raw::c_char {
82 unsafe {
83 let handle = &mut *self.buffer.get();
84 handle.scratch_txt_opt(txt)
85 }
86 }
87
88 pub(crate) fn scratch_txt_two(
90 &self,
91 txt_0: impl AsRef<str>,
92 txt_1: impl AsRef<str>,
93 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
94 unsafe {
95 let handle = &mut *self.buffer.get();
96 handle.scratch_txt_two(txt_0, txt_1)
97 }
98 }
99
100 pub(crate) fn scratch_txt_with_opt(
102 &self,
103 txt_0: impl AsRef<str>,
104 txt_1: Option<impl AsRef<str>>,
105 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
106 unsafe {
107 let handle = &mut *self.buffer.get();
108 handle.scratch_txt_with_opt(txt_0, txt_1)
109 }
110 }
111
112 pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
114 &self.buffer
115 }
116
117 #[doc(alias = "TextUnformatted")]
119 pub fn text<T: AsRef<str>>(&self, text: T) {
120 let s = text.as_ref();
121 unsafe {
122 let start = s.as_ptr();
123 let end = start.add(s.len());
124 crate::sys::igTextUnformatted(
125 start as *const std::os::raw::c_char,
126 end as *const std::os::raw::c_char,
127 );
128 }
129 }
130
131 #[doc(alias = "SetNextWindowViewport")]
136 pub fn set_next_window_viewport(&self, viewport_id: Id) {
137 unsafe { sys::igSetNextWindowViewport(viewport_id.into()) }
138 }
139
140 #[doc(alias = "GetID")]
145 pub fn get_id(&self, label: &str) -> Id {
146 unsafe { Id::from(sys::igGetID_Str(self.scratch_txt(label))) }
147 }
148
149 #[doc(alias = "GetWindowDrawList")]
151 pub fn get_window_draw_list(&self) -> DrawListMut<'_> {
152 DrawListMut::window(self)
153 }
154
155 #[doc(alias = "GetBackgroundDrawList")]
157 pub fn get_background_draw_list(&self) -> DrawListMut<'_> {
158 DrawListMut::background(self)
159 }
160
161 #[doc(alias = "GetForegroundDrawList")]
163 pub fn get_foreground_draw_list(&self) -> DrawListMut<'_> {
164 DrawListMut::foreground(self)
165 }
166
167 pub fn window<'ui>(
169 &'ui self,
170 name: impl Into<std::borrow::Cow<'ui, str>>,
171 ) -> crate::window::Window<'ui> {
172 crate::window::Window::new(self, name)
173 }
174
175 #[doc(alias = "ShowDemoWindow")]
178 pub fn show_demo_window(&self, opened: &mut bool) {
179 unsafe {
180 crate::sys::igShowDemoWindow(opened);
181 }
182 }
183
184 #[doc(alias = "ImageWithBg")]
188 pub fn image_with_bg(
189 &self,
190 texture: impl Into<TextureRef>,
191 size: [f32; 2],
192 bg_color: [f32; 4],
193 tint_color: [f32; 4],
194 ) {
195 crate::widget::image::Image::new(self, texture, size).build_with_bg(bg_color, tint_color)
196 }
197
198 #[doc(alias = "ShowAboutWindow")]
202 pub fn show_about_window(&self, opened: &mut bool) {
203 unsafe {
204 crate::sys::igShowAboutWindow(opened);
205 }
206 }
207
208 #[doc(alias = "ShowMetricsWindow")]
213 pub fn show_metrics_window(&self, opened: &mut bool) {
214 unsafe {
215 crate::sys::igShowMetricsWindow(opened);
216 }
217 }
218
219 #[doc(alias = "ShowStyleEditor")]
221 pub fn show_style_editor(&self, style: &mut crate::style::Style) {
222 unsafe {
223 crate::sys::igShowStyleEditor(style.raw_mut());
224 }
225 }
226
227 #[doc(alias = "ShowStyleEditor")]
229 pub fn show_default_style_editor(&self) {
230 unsafe {
231 crate::sys::igShowStyleEditor(std::ptr::null_mut());
232 }
233 }
234
235 #[doc(alias = "ShowUserGuide")]
237 pub fn show_user_guide(&self) {
238 unsafe {
239 crate::sys::igShowUserGuide();
240 }
241 }
242
243 #[doc(alias = "DragFloat")]
247 pub fn drag_float(&self, label: impl AsRef<str>, value: &mut f32) -> bool {
248 crate::widget::drag::Drag::new(label).build(self, value)
249 }
250
251 #[doc(alias = "DragFloat")]
253 pub fn drag_float_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<f32, L> {
254 crate::widget::drag::Drag::new(label)
255 }
256
257 #[doc(alias = "DragInt")]
259 pub fn drag_int(&self, label: impl AsRef<str>, value: &mut i32) -> bool {
260 crate::widget::drag::Drag::new(label).build(self, value)
261 }
262
263 #[doc(alias = "DragInt")]
265 pub fn drag_int_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<i32, L> {
266 crate::widget::drag::Drag::new(label)
267 }
268
269 #[doc(alias = "DragFloatRange2")]
271 pub fn drag_float_range2(&self, label: impl AsRef<str>, min: &mut f32, max: &mut f32) -> bool {
272 crate::widget::drag::DragRange::<f32, _>::new(label).build(self, min, max)
273 }
274
275 #[doc(alias = "DragFloatRange2")]
277 pub fn drag_float_range2_config<L: AsRef<str>>(
278 &self,
279 label: L,
280 ) -> crate::widget::drag::DragRange<f32, L> {
281 crate::widget::drag::DragRange::new(label)
282 }
283
284 #[doc(alias = "DragIntRange2")]
286 pub fn drag_int_range2(&self, label: impl AsRef<str>, min: &mut i32, max: &mut i32) -> bool {
287 crate::widget::drag::DragRange::<i32, _>::new(label).build(self, min, max)
288 }
289
290 #[doc(alias = "DragIntRange2")]
292 pub fn drag_int_range2_config<L: AsRef<str>>(
293 &self,
294 label: L,
295 ) -> crate::widget::drag::DragRange<i32, L> {
296 crate::widget::drag::DragRange::new(label)
297 }
298
299 #[doc(alias = "GetMouseCursor")]
303 pub fn mouse_cursor(&self) -> Option<MouseCursor> {
304 unsafe {
305 match sys::igGetMouseCursor() {
306 sys::ImGuiMouseCursor_Arrow => Some(MouseCursor::Arrow),
307 sys::ImGuiMouseCursor_TextInput => Some(MouseCursor::TextInput),
308 sys::ImGuiMouseCursor_ResizeAll => Some(MouseCursor::ResizeAll),
309 sys::ImGuiMouseCursor_ResizeNS => Some(MouseCursor::ResizeNS),
310 sys::ImGuiMouseCursor_ResizeEW => Some(MouseCursor::ResizeEW),
311 sys::ImGuiMouseCursor_ResizeNESW => Some(MouseCursor::ResizeNESW),
312 sys::ImGuiMouseCursor_ResizeNWSE => Some(MouseCursor::ResizeNWSE),
313 sys::ImGuiMouseCursor_Hand => Some(MouseCursor::Hand),
314 sys::ImGuiMouseCursor_NotAllowed => Some(MouseCursor::NotAllowed),
315 _ => None,
316 }
317 }
318 }
319
320 #[doc(alias = "SetMouseCursor")]
324 pub fn set_mouse_cursor(&self, cursor_type: Option<MouseCursor>) {
325 unsafe {
326 let val: sys::ImGuiMouseCursor = cursor_type
327 .map(|x| x as sys::ImGuiMouseCursor)
328 .unwrap_or(sys::ImGuiMouseCursor_None);
329 sys::igSetMouseCursor(val);
330 }
331 }
332
333 #[doc(alias = "SetKeyboardFocusHere")]
342 pub fn set_keyboard_focus_here(&self) {
343 self.set_keyboard_focus_here_with_offset(0);
344 }
345
346 #[doc(alias = "SetKeyboardFocusHere")]
350 pub fn set_keyboard_focus_here_with_offset(&self, offset: i32) {
351 unsafe {
352 sys::igSetKeyboardFocusHere(offset);
353 }
354 }
355
356 #[doc(alias = "SetNextItemOpen")]
360 pub fn set_next_item_open(&self, is_open: bool) {
361 unsafe {
362 sys::igSetNextItemOpen(is_open, 0); }
364 }
365
366 #[doc(alias = "SetNextItemOpen")]
368 pub fn set_next_item_open_with_cond(&self, is_open: bool, cond: crate::Condition) {
369 unsafe { sys::igSetNextItemOpen(is_open, cond as sys::ImGuiCond) }
370 }
371
372 #[doc(alias = "SetNextItemWidth")]
376 pub fn set_next_item_width(&self, item_width: f32) {
377 unsafe {
378 sys::igSetNextItemWidth(item_width);
379 }
380 }
381
382 #[doc(alias = "GetStyle")]
398 pub unsafe fn style(&self) -> &crate::Style {
399 unsafe {
400 &*(sys::igGetStyle() as *const crate::Style)
402 }
403 }
404
405 #[doc(alias = "GetStyle")]
409 pub fn clone_style(&self) -> crate::Style {
410 unsafe { self.style().clone() }
411 }
412
413 #[doc(alias = "StyleColorsDark")]
415 pub fn style_colors_dark(&self) {
416 unsafe { sys::igStyleColorsDark(std::ptr::null_mut()) }
417 }
418
419 #[doc(alias = "StyleColorsLight")]
421 pub fn style_colors_light(&self) {
422 unsafe { sys::igStyleColorsLight(std::ptr::null_mut()) }
423 }
424
425 #[doc(alias = "StyleColorsClassic")]
427 pub fn style_colors_classic(&self) {
428 unsafe { sys::igStyleColorsClassic(std::ptr::null_mut()) }
429 }
430
431 #[doc(alias = "StyleColorsDark")]
433 pub fn style_colors_dark_into(&self, dst: &mut crate::Style) {
434 unsafe { sys::igStyleColorsDark(dst.raw_mut() as *mut sys::ImGuiStyle) }
435 }
436
437 #[doc(alias = "StyleColorsLight")]
439 pub fn style_colors_light_into(&self, dst: &mut crate::Style) {
440 unsafe { sys::igStyleColorsLight(dst.raw_mut() as *mut sys::ImGuiStyle) }
441 }
442
443 #[doc(alias = "StyleColorsClassic")]
445 pub fn style_colors_classic_into(&self, dst: &mut crate::Style) {
446 unsafe { sys::igStyleColorsClassic(dst.raw_mut() as *mut sys::ImGuiStyle) }
447 }
448
449 #[doc(alias = "GetWindowDpiScale")]
451 pub fn window_dpi_scale(&self) -> f32 {
452 unsafe { sys::igGetWindowDpiScale() }
453 }
454
455 #[doc(alias = "Value")]
457 pub fn value_bool(&self, prefix: impl AsRef<str>, v: bool) {
458 unsafe { sys::igValue_Bool(self.scratch_txt(prefix), v) }
459 }
460
461 #[doc(alias = "GetWindowWidth")]
463 pub fn window_width(&self) -> f32 {
464 unsafe { sys::igGetWindowWidth() }
465 }
466
467 #[doc(alias = "GetWindowHeight")]
469 pub fn window_height(&self) -> f32 {
470 unsafe { sys::igGetWindowHeight() }
471 }
472
473 #[doc(alias = "GetWindowPos")]
475 pub fn window_pos(&self) -> [f32; 2] {
476 let v = unsafe { sys::igGetWindowPos() };
477 [v.x, v.y]
478 }
479
480 #[doc(alias = "GetWindowSize")]
482 pub fn window_size(&self) -> [f32; 2] {
483 let v = unsafe { sys::igGetWindowSize() };
484 [v.x, v.y]
485 }
486
487 #[doc(alias = "ShowDebugLogWindow")]
495 pub fn show_debug_log_window(&self, opened: &mut bool) {
496 unsafe {
497 sys::igShowDebugLogWindow(opened);
498 }
499 }
500
501 #[doc(alias = "ShowIDStackToolWindow")]
505 pub fn show_id_stack_tool_window(&self, opened: &mut bool) {
506 unsafe {
507 sys::igShowIDStackToolWindow(opened);
508 }
509 }
510
511 #[doc(alias = "ShowStyleSelector")]
515 pub fn show_style_selector(&self, label: impl AsRef<str>) -> bool {
516 unsafe { sys::igShowStyleSelector(self.scratch_txt(label)) }
517 }
518
519 #[doc(alias = "ShowFontSelector")]
521 pub fn show_font_selector(&self, label: impl AsRef<str>) {
522 unsafe {
523 sys::igShowFontSelector(self.scratch_txt(label));
524 }
525 }
526
527 #[doc(alias = "GetVersion")]
529 pub fn get_version(&self) -> &str {
530 unsafe {
531 let version_ptr = sys::igGetVersion();
532 if version_ptr.is_null() {
533 return "Unknown";
534 }
535 let c_str = std::ffi::CStr::from_ptr(version_ptr);
536 c_str.to_str().unwrap_or("Unknown")
537 }
538 }
539}