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_two(
79 &self,
80 txt_0: impl AsRef<str>,
81 txt_1: impl AsRef<str>,
82 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
83 unsafe {
84 let handle = &mut *self.buffer.get();
85 handle.scratch_txt_two(txt_0, txt_1)
86 }
87 }
88
89 pub(crate) fn scratch_txt_with_opt(
91 &self,
92 txt_0: impl AsRef<str>,
93 txt_1: Option<impl AsRef<str>>,
94 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
95 unsafe {
96 let handle = &mut *self.buffer.get();
97 handle.scratch_txt_with_opt(txt_0, txt_1)
98 }
99 }
100
101 pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
103 &self.buffer
104 }
105
106 #[doc(alias = "TextUnformatted")]
108 pub fn text<T: AsRef<str>>(&self, text: T) {
109 let s = text.as_ref();
110 unsafe {
111 let start = s.as_ptr();
112 let end = start.add(s.len());
113 crate::sys::igTextUnformatted(
114 start as *const std::os::raw::c_char,
115 end as *const std::os::raw::c_char,
116 );
117 }
118 }
119
120 #[doc(alias = "SetNextWindowViewport")]
125 pub fn set_next_window_viewport(&self, viewport_id: Id) {
126 unsafe { sys::igSetNextWindowViewport(viewport_id.into()) }
127 }
128
129 #[doc(alias = "GetWindowViewport")]
133 pub fn window_viewport(&self) -> &crate::platform_io::Viewport {
134 unsafe {
135 let ptr = sys::igGetWindowViewport();
136 if ptr.is_null() {
137 panic!("Ui::window_viewport() requires a current window");
138 }
139 crate::platform_io::Viewport::from_raw(ptr as *const sys::ImGuiViewport)
140 }
141 }
142
143 #[doc(alias = "FindViewportByID")]
145 pub fn find_viewport_by_id(&self, viewport_id: Id) -> Option<&crate::platform_io::Viewport> {
146 unsafe {
147 let ptr = sys::igFindViewportByID(viewport_id.raw());
148 if ptr.is_null() {
149 None
150 } else {
151 Some(crate::platform_io::Viewport::from_raw(
152 ptr as *const sys::ImGuiViewport,
153 ))
154 }
155 }
156 }
157
158 #[doc(alias = "FindViewportByPlatformHandle")]
162 #[allow(clippy::not_unsafe_ptr_arg_deref)]
163 pub fn find_viewport_by_platform_handle(
164 &self,
165 platform_handle: *mut std::ffi::c_void,
166 ) -> Option<&crate::platform_io::Viewport> {
167 unsafe {
168 let ptr = sys::igFindViewportByPlatformHandle(platform_handle);
169 if ptr.is_null() {
170 None
171 } else {
172 Some(crate::platform_io::Viewport::from_raw(
173 ptr as *const sys::ImGuiViewport,
174 ))
175 }
176 }
177 }
178
179 #[doc(alias = "GetID")]
184 pub fn get_id(&self, label: &str) -> Id {
185 unsafe { Id::from(sys::igGetID_Str(self.scratch_txt(label))) }
186 }
187
188 #[doc(alias = "GetWindowDrawList")]
190 pub fn get_window_draw_list(&self) -> DrawListMut<'_> {
191 DrawListMut::window(self)
192 }
193
194 #[doc(alias = "GetBackgroundDrawList")]
196 pub fn get_background_draw_list(&self) -> DrawListMut<'_> {
197 DrawListMut::background(self)
198 }
199
200 #[doc(alias = "GetForegroundDrawList")]
202 pub fn get_foreground_draw_list(&self) -> DrawListMut<'_> {
203 DrawListMut::foreground(self)
204 }
205
206 pub fn window<'ui>(
208 &'ui self,
209 name: impl Into<std::borrow::Cow<'ui, str>>,
210 ) -> crate::window::Window<'ui> {
211 crate::window::Window::new(self, name)
212 }
213
214 #[doc(alias = "ShowDemoWindow")]
217 pub fn show_demo_window(&self, opened: &mut bool) {
218 unsafe {
219 crate::sys::igShowDemoWindow(opened);
220 }
221 }
222
223 #[doc(alias = "ImageWithBg")]
227 pub fn image_with_bg(
228 &self,
229 texture: impl Into<TextureRef>,
230 size: [f32; 2],
231 bg_color: [f32; 4],
232 tint_color: [f32; 4],
233 ) {
234 crate::widget::image::Image::new(self, texture, size).build_with_bg(bg_color, tint_color)
235 }
236
237 #[doc(alias = "ShowAboutWindow")]
241 pub fn show_about_window(&self, opened: &mut bool) {
242 unsafe {
243 crate::sys::igShowAboutWindow(opened);
244 }
245 }
246
247 #[doc(alias = "ShowMetricsWindow")]
252 pub fn show_metrics_window(&self, opened: &mut bool) {
253 unsafe {
254 crate::sys::igShowMetricsWindow(opened);
255 }
256 }
257
258 #[doc(alias = "ShowStyleEditor")]
260 pub fn show_style_editor(&self, style: &mut crate::style::Style) {
261 unsafe {
262 crate::sys::igShowStyleEditor(style.raw_mut());
263 }
264 }
265
266 #[doc(alias = "ShowStyleEditor")]
268 pub fn show_default_style_editor(&self) {
269 unsafe {
270 crate::sys::igShowStyleEditor(std::ptr::null_mut());
271 }
272 }
273
274 #[doc(alias = "ShowUserGuide")]
276 pub fn show_user_guide(&self) {
277 unsafe {
278 crate::sys::igShowUserGuide();
279 }
280 }
281
282 #[doc(alias = "DragFloat")]
286 pub fn drag_float(&self, label: impl AsRef<str>, value: &mut f32) -> bool {
287 crate::widget::drag::Drag::new(label).build(self, value)
288 }
289
290 #[doc(alias = "DragFloat")]
292 pub fn drag_float_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<f32, L> {
293 crate::widget::drag::Drag::new(label)
294 }
295
296 #[doc(alias = "DragInt")]
298 pub fn drag_int(&self, label: impl AsRef<str>, value: &mut i32) -> bool {
299 crate::widget::drag::Drag::new(label).build(self, value)
300 }
301
302 #[doc(alias = "DragInt")]
304 pub fn drag_int_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<i32, L> {
305 crate::widget::drag::Drag::new(label)
306 }
307
308 #[doc(alias = "DragFloatRange2")]
310 pub fn drag_float_range2(&self, label: impl AsRef<str>, min: &mut f32, max: &mut f32) -> bool {
311 crate::widget::drag::DragRange::<f32, _>::new(label).build(self, min, max)
312 }
313
314 #[doc(alias = "DragFloatRange2")]
316 pub fn drag_float_range2_config<L: AsRef<str>>(
317 &self,
318 label: L,
319 ) -> crate::widget::drag::DragRange<f32, L> {
320 crate::widget::drag::DragRange::new(label)
321 }
322
323 #[doc(alias = "DragIntRange2")]
325 pub fn drag_int_range2(&self, label: impl AsRef<str>, min: &mut i32, max: &mut i32) -> bool {
326 crate::widget::drag::DragRange::<i32, _>::new(label).build(self, min, max)
327 }
328
329 #[doc(alias = "DragIntRange2")]
331 pub fn drag_int_range2_config<L: AsRef<str>>(
332 &self,
333 label: L,
334 ) -> crate::widget::drag::DragRange<i32, L> {
335 crate::widget::drag::DragRange::new(label)
336 }
337
338 #[doc(alias = "GetMouseCursor")]
342 pub fn mouse_cursor(&self) -> Option<MouseCursor> {
343 unsafe {
344 match sys::igGetMouseCursor() {
345 sys::ImGuiMouseCursor_Arrow => Some(MouseCursor::Arrow),
346 sys::ImGuiMouseCursor_TextInput => Some(MouseCursor::TextInput),
347 sys::ImGuiMouseCursor_ResizeAll => Some(MouseCursor::ResizeAll),
348 sys::ImGuiMouseCursor_ResizeNS => Some(MouseCursor::ResizeNS),
349 sys::ImGuiMouseCursor_ResizeEW => Some(MouseCursor::ResizeEW),
350 sys::ImGuiMouseCursor_ResizeNESW => Some(MouseCursor::ResizeNESW),
351 sys::ImGuiMouseCursor_ResizeNWSE => Some(MouseCursor::ResizeNWSE),
352 sys::ImGuiMouseCursor_Hand => Some(MouseCursor::Hand),
353 sys::ImGuiMouseCursor_NotAllowed => Some(MouseCursor::NotAllowed),
354 _ => None,
355 }
356 }
357 }
358
359 #[doc(alias = "SetMouseCursor")]
363 pub fn set_mouse_cursor(&self, cursor_type: Option<MouseCursor>) {
364 unsafe {
365 let val: sys::ImGuiMouseCursor = cursor_type
366 .map(|x| x as sys::ImGuiMouseCursor)
367 .unwrap_or(sys::ImGuiMouseCursor_None);
368 sys::igSetMouseCursor(val);
369 }
370 }
371
372 #[doc(alias = "SetKeyboardFocusHere")]
381 pub fn set_keyboard_focus_here(&self) {
382 self.set_keyboard_focus_here_with_offset(0);
383 }
384
385 #[doc(alias = "SetKeyboardFocusHere")]
389 pub fn set_keyboard_focus_here_with_offset(&self, offset: i32) {
390 unsafe {
391 sys::igSetKeyboardFocusHere(offset);
392 }
393 }
394
395 #[doc(alias = "SetNavCursorVisible")]
397 pub fn set_nav_cursor_visible(&self, visible: bool) {
398 unsafe { sys::igSetNavCursorVisible(visible) }
399 }
400
401 #[doc(alias = "SetWindowFocus")]
407 pub fn set_window_focus(&self, name: Option<&str>) {
408 unsafe {
409 match name {
410 Some(name) => sys::igSetWindowFocus_Str(self.scratch_txt(name)),
411 None => sys::igSetWindowFocus_Nil(),
412 }
413 }
414 }
415
416 #[doc(alias = "SetWindowPos")]
418 pub fn set_window_pos(&self, pos: [f32; 2]) {
419 self.set_window_pos_with_cond(pos, crate::Condition::Always);
420 }
421
422 #[doc(alias = "SetWindowPos")]
424 pub fn set_window_pos_with_cond(&self, pos: [f32; 2], cond: crate::Condition) {
425 let pos_vec = sys::ImVec2_c {
426 x: pos[0],
427 y: pos[1],
428 };
429 unsafe { sys::igSetWindowPos_Vec2(pos_vec, cond as sys::ImGuiCond) }
430 }
431
432 #[doc(alias = "SetWindowPos")]
434 pub fn set_window_pos_by_name(&self, name: impl AsRef<str>, pos: [f32; 2]) {
435 self.set_window_pos_by_name_with_cond(name, pos, crate::Condition::Always);
436 }
437
438 #[doc(alias = "SetWindowPos")]
440 pub fn set_window_pos_by_name_with_cond(
441 &self,
442 name: impl AsRef<str>,
443 pos: [f32; 2],
444 cond: crate::Condition,
445 ) {
446 let pos_vec = sys::ImVec2_c {
447 x: pos[0],
448 y: pos[1],
449 };
450 unsafe { sys::igSetWindowPos_Str(self.scratch_txt(name), pos_vec, cond as sys::ImGuiCond) }
451 }
452
453 #[doc(alias = "SetWindowSize")]
455 pub fn set_window_size(&self, size: [f32; 2]) {
456 self.set_window_size_with_cond(size, crate::Condition::Always);
457 }
458
459 #[doc(alias = "SetWindowSize")]
461 pub fn set_window_size_with_cond(&self, size: [f32; 2], cond: crate::Condition) {
462 let size_vec = sys::ImVec2_c {
463 x: size[0],
464 y: size[1],
465 };
466 unsafe { sys::igSetWindowSize_Vec2(size_vec, cond as sys::ImGuiCond) }
467 }
468
469 #[doc(alias = "SetWindowSize")]
471 pub fn set_window_size_by_name(&self, name: impl AsRef<str>, size: [f32; 2]) {
472 self.set_window_size_by_name_with_cond(name, size, crate::Condition::Always);
473 }
474
475 #[doc(alias = "SetWindowSize")]
477 pub fn set_window_size_by_name_with_cond(
478 &self,
479 name: impl AsRef<str>,
480 size: [f32; 2],
481 cond: crate::Condition,
482 ) {
483 let size_vec = sys::ImVec2_c {
484 x: size[0],
485 y: size[1],
486 };
487 unsafe {
488 sys::igSetWindowSize_Str(self.scratch_txt(name), size_vec, cond as sys::ImGuiCond);
489 }
490 }
491
492 #[doc(alias = "SetWindowCollapsed")]
494 pub fn set_window_collapsed(&self, collapsed: bool) {
495 self.set_window_collapsed_with_cond(collapsed, crate::Condition::Always);
496 }
497
498 #[doc(alias = "SetWindowCollapsed")]
500 pub fn set_window_collapsed_with_cond(&self, collapsed: bool, cond: crate::Condition) {
501 unsafe { sys::igSetWindowCollapsed_Bool(collapsed, cond as sys::ImGuiCond) }
502 }
503
504 #[doc(alias = "SetWindowCollapsed")]
506 pub fn set_window_collapsed_by_name(&self, name: impl AsRef<str>, collapsed: bool) {
507 self.set_window_collapsed_by_name_with_cond(name, collapsed, crate::Condition::Always);
508 }
509
510 #[doc(alias = "SetWindowCollapsed")]
512 pub fn set_window_collapsed_by_name_with_cond(
513 &self,
514 name: impl AsRef<str>,
515 collapsed: bool,
516 cond: crate::Condition,
517 ) {
518 unsafe {
519 sys::igSetWindowCollapsed_Str(
520 self.scratch_txt(name),
521 collapsed,
522 cond as sys::ImGuiCond,
523 );
524 }
525 }
526
527 #[doc(alias = "SetNextItemOpen")]
531 pub fn set_next_item_open(&self, is_open: bool) {
532 unsafe {
533 sys::igSetNextItemOpen(is_open, 0); }
535 }
536
537 #[doc(alias = "SetNextItemOpen")]
539 pub fn set_next_item_open_with_cond(&self, is_open: bool, cond: crate::Condition) {
540 unsafe { sys::igSetNextItemOpen(is_open, cond as sys::ImGuiCond) }
541 }
542
543 #[doc(alias = "SetNextItemWidth")]
547 pub fn set_next_item_width(&self, item_width: f32) {
548 unsafe {
549 sys::igSetNextItemWidth(item_width);
550 }
551 }
552
553 #[doc(alias = "GetStyle")]
569 pub unsafe fn style(&self) -> &crate::Style {
570 unsafe {
571 &*(sys::igGetStyle() as *const crate::Style)
573 }
574 }
575
576 #[doc(alias = "GetStyle")]
580 pub fn clone_style(&self) -> crate::Style {
581 unsafe { self.style().clone() }
582 }
583
584 #[doc(alias = "StyleColorsDark")]
586 pub fn style_colors_dark(&self) {
587 unsafe { sys::igStyleColorsDark(std::ptr::null_mut()) }
588 }
589
590 #[doc(alias = "StyleColorsLight")]
592 pub fn style_colors_light(&self) {
593 unsafe { sys::igStyleColorsLight(std::ptr::null_mut()) }
594 }
595
596 #[doc(alias = "StyleColorsClassic")]
598 pub fn style_colors_classic(&self) {
599 unsafe { sys::igStyleColorsClassic(std::ptr::null_mut()) }
600 }
601
602 #[doc(alias = "StyleColorsDark")]
604 pub fn style_colors_dark_into(&self, dst: &mut crate::Style) {
605 unsafe { sys::igStyleColorsDark(dst.raw_mut() as *mut sys::ImGuiStyle) }
606 }
607
608 #[doc(alias = "StyleColorsLight")]
610 pub fn style_colors_light_into(&self, dst: &mut crate::Style) {
611 unsafe { sys::igStyleColorsLight(dst.raw_mut() as *mut sys::ImGuiStyle) }
612 }
613
614 #[doc(alias = "StyleColorsClassic")]
616 pub fn style_colors_classic_into(&self, dst: &mut crate::Style) {
617 unsafe { sys::igStyleColorsClassic(dst.raw_mut() as *mut sys::ImGuiStyle) }
618 }
619
620 #[doc(alias = "GetWindowDpiScale")]
622 pub fn window_dpi_scale(&self) -> f32 {
623 unsafe { sys::igGetWindowDpiScale() }
624 }
625
626 #[doc(alias = "Value")]
628 pub fn value_bool(&self, prefix: impl AsRef<str>, v: bool) {
629 unsafe { sys::igValue_Bool(self.scratch_txt(prefix), v) }
630 }
631
632 #[doc(alias = "GetWindowWidth")]
634 pub fn window_width(&self) -> f32 {
635 unsafe { sys::igGetWindowWidth() }
636 }
637
638 #[doc(alias = "GetWindowHeight")]
640 pub fn window_height(&self) -> f32 {
641 unsafe { sys::igGetWindowHeight() }
642 }
643
644 #[doc(alias = "GetWindowPos")]
646 pub fn window_pos(&self) -> [f32; 2] {
647 let v = unsafe { sys::igGetWindowPos() };
648 [v.x, v.y]
649 }
650
651 #[doc(alias = "GetWindowSize")]
653 pub fn window_size(&self) -> [f32; 2] {
654 let v = unsafe { sys::igGetWindowSize() };
655 [v.x, v.y]
656 }
657
658 #[doc(alias = "ShowDebugLogWindow")]
666 pub fn show_debug_log_window(&self, opened: &mut bool) {
667 unsafe {
668 sys::igShowDebugLogWindow(opened);
669 }
670 }
671
672 #[doc(alias = "ShowIDStackToolWindow")]
676 pub fn show_id_stack_tool_window(&self, opened: &mut bool) {
677 unsafe {
678 sys::igShowIDStackToolWindow(opened);
679 }
680 }
681
682 #[doc(alias = "ShowStyleSelector")]
686 pub fn show_style_selector(&self, label: impl AsRef<str>) -> bool {
687 unsafe { sys::igShowStyleSelector(self.scratch_txt(label)) }
688 }
689
690 #[doc(alias = "ShowFontSelector")]
692 pub fn show_font_selector(&self, label: impl AsRef<str>) {
693 unsafe {
694 sys::igShowFontSelector(self.scratch_txt(label));
695 }
696 }
697
698 #[doc(alias = "GetVersion")]
700 pub fn get_version(&self) -> &str {
701 unsafe {
702 let version_ptr = sys::igGetVersion();
703 if version_ptr.is_null() {
704 return "Unknown";
705 }
706 let c_str = std::ffi::CStr::from_ptr(version_ptr);
707 c_str.to_str().unwrap_or("Unknown")
708 }
709 }
710}