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 = "GetWindowViewport")]
144 pub fn window_viewport(&self) -> &crate::platform_io::Viewport {
145 unsafe {
146 let ptr = sys::igGetWindowViewport();
147 if ptr.is_null() {
148 panic!("Ui::window_viewport() requires a current window");
149 }
150 crate::platform_io::Viewport::from_raw(ptr as *const sys::ImGuiViewport)
151 }
152 }
153
154 #[doc(alias = "FindViewportByID")]
156 pub fn find_viewport_by_id(&self, viewport_id: Id) -> Option<&crate::platform_io::Viewport> {
157 unsafe {
158 let ptr = sys::igFindViewportByID(viewport_id.raw());
159 if ptr.is_null() {
160 None
161 } else {
162 Some(crate::platform_io::Viewport::from_raw(
163 ptr as *const sys::ImGuiViewport,
164 ))
165 }
166 }
167 }
168
169 #[doc(alias = "FindViewportByPlatformHandle")]
173 #[allow(clippy::not_unsafe_ptr_arg_deref)]
174 pub fn find_viewport_by_platform_handle(
175 &self,
176 platform_handle: *mut std::ffi::c_void,
177 ) -> Option<&crate::platform_io::Viewport> {
178 unsafe {
179 let ptr = sys::igFindViewportByPlatformHandle(platform_handle);
180 if ptr.is_null() {
181 None
182 } else {
183 Some(crate::platform_io::Viewport::from_raw(
184 ptr as *const sys::ImGuiViewport,
185 ))
186 }
187 }
188 }
189
190 #[doc(alias = "GetID")]
195 pub fn get_id(&self, label: &str) -> Id {
196 unsafe { Id::from(sys::igGetID_Str(self.scratch_txt(label))) }
197 }
198
199 #[doc(alias = "GetWindowDrawList")]
201 pub fn get_window_draw_list(&self) -> DrawListMut<'_> {
202 DrawListMut::window(self)
203 }
204
205 #[doc(alias = "GetBackgroundDrawList")]
207 pub fn get_background_draw_list(&self) -> DrawListMut<'_> {
208 DrawListMut::background(self)
209 }
210
211 #[doc(alias = "GetForegroundDrawList")]
213 pub fn get_foreground_draw_list(&self) -> DrawListMut<'_> {
214 DrawListMut::foreground(self)
215 }
216
217 pub fn window<'ui>(
219 &'ui self,
220 name: impl Into<std::borrow::Cow<'ui, str>>,
221 ) -> crate::window::Window<'ui> {
222 crate::window::Window::new(self, name)
223 }
224
225 #[doc(alias = "ShowDemoWindow")]
228 pub fn show_demo_window(&self, opened: &mut bool) {
229 unsafe {
230 crate::sys::igShowDemoWindow(opened);
231 }
232 }
233
234 #[doc(alias = "ImageWithBg")]
238 pub fn image_with_bg(
239 &self,
240 texture: impl Into<TextureRef>,
241 size: [f32; 2],
242 bg_color: [f32; 4],
243 tint_color: [f32; 4],
244 ) {
245 crate::widget::image::Image::new(self, texture, size).build_with_bg(bg_color, tint_color)
246 }
247
248 #[doc(alias = "ShowAboutWindow")]
252 pub fn show_about_window(&self, opened: &mut bool) {
253 unsafe {
254 crate::sys::igShowAboutWindow(opened);
255 }
256 }
257
258 #[doc(alias = "ShowMetricsWindow")]
263 pub fn show_metrics_window(&self, opened: &mut bool) {
264 unsafe {
265 crate::sys::igShowMetricsWindow(opened);
266 }
267 }
268
269 #[doc(alias = "ShowStyleEditor")]
271 pub fn show_style_editor(&self, style: &mut crate::style::Style) {
272 unsafe {
273 crate::sys::igShowStyleEditor(style.raw_mut());
274 }
275 }
276
277 #[doc(alias = "ShowStyleEditor")]
279 pub fn show_default_style_editor(&self) {
280 unsafe {
281 crate::sys::igShowStyleEditor(std::ptr::null_mut());
282 }
283 }
284
285 #[doc(alias = "ShowUserGuide")]
287 pub fn show_user_guide(&self) {
288 unsafe {
289 crate::sys::igShowUserGuide();
290 }
291 }
292
293 #[doc(alias = "DragFloat")]
297 pub fn drag_float(&self, label: impl AsRef<str>, value: &mut f32) -> bool {
298 crate::widget::drag::Drag::new(label).build(self, value)
299 }
300
301 #[doc(alias = "DragFloat")]
303 pub fn drag_float_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<f32, L> {
304 crate::widget::drag::Drag::new(label)
305 }
306
307 #[doc(alias = "DragInt")]
309 pub fn drag_int(&self, label: impl AsRef<str>, value: &mut i32) -> bool {
310 crate::widget::drag::Drag::new(label).build(self, value)
311 }
312
313 #[doc(alias = "DragInt")]
315 pub fn drag_int_config<L: AsRef<str>>(&self, label: L) -> crate::widget::drag::Drag<i32, L> {
316 crate::widget::drag::Drag::new(label)
317 }
318
319 #[doc(alias = "DragFloatRange2")]
321 pub fn drag_float_range2(&self, label: impl AsRef<str>, min: &mut f32, max: &mut f32) -> bool {
322 crate::widget::drag::DragRange::<f32, _>::new(label).build(self, min, max)
323 }
324
325 #[doc(alias = "DragFloatRange2")]
327 pub fn drag_float_range2_config<L: AsRef<str>>(
328 &self,
329 label: L,
330 ) -> crate::widget::drag::DragRange<f32, L> {
331 crate::widget::drag::DragRange::new(label)
332 }
333
334 #[doc(alias = "DragIntRange2")]
336 pub fn drag_int_range2(&self, label: impl AsRef<str>, min: &mut i32, max: &mut i32) -> bool {
337 crate::widget::drag::DragRange::<i32, _>::new(label).build(self, min, max)
338 }
339
340 #[doc(alias = "DragIntRange2")]
342 pub fn drag_int_range2_config<L: AsRef<str>>(
343 &self,
344 label: L,
345 ) -> crate::widget::drag::DragRange<i32, L> {
346 crate::widget::drag::DragRange::new(label)
347 }
348
349 #[doc(alias = "GetMouseCursor")]
353 pub fn mouse_cursor(&self) -> Option<MouseCursor> {
354 unsafe {
355 match sys::igGetMouseCursor() {
356 sys::ImGuiMouseCursor_Arrow => Some(MouseCursor::Arrow),
357 sys::ImGuiMouseCursor_TextInput => Some(MouseCursor::TextInput),
358 sys::ImGuiMouseCursor_ResizeAll => Some(MouseCursor::ResizeAll),
359 sys::ImGuiMouseCursor_ResizeNS => Some(MouseCursor::ResizeNS),
360 sys::ImGuiMouseCursor_ResizeEW => Some(MouseCursor::ResizeEW),
361 sys::ImGuiMouseCursor_ResizeNESW => Some(MouseCursor::ResizeNESW),
362 sys::ImGuiMouseCursor_ResizeNWSE => Some(MouseCursor::ResizeNWSE),
363 sys::ImGuiMouseCursor_Hand => Some(MouseCursor::Hand),
364 sys::ImGuiMouseCursor_NotAllowed => Some(MouseCursor::NotAllowed),
365 _ => None,
366 }
367 }
368 }
369
370 #[doc(alias = "SetMouseCursor")]
374 pub fn set_mouse_cursor(&self, cursor_type: Option<MouseCursor>) {
375 unsafe {
376 let val: sys::ImGuiMouseCursor = cursor_type
377 .map(|x| x as sys::ImGuiMouseCursor)
378 .unwrap_or(sys::ImGuiMouseCursor_None);
379 sys::igSetMouseCursor(val);
380 }
381 }
382
383 #[doc(alias = "SetKeyboardFocusHere")]
392 pub fn set_keyboard_focus_here(&self) {
393 self.set_keyboard_focus_here_with_offset(0);
394 }
395
396 #[doc(alias = "SetKeyboardFocusHere")]
400 pub fn set_keyboard_focus_here_with_offset(&self, offset: i32) {
401 unsafe {
402 sys::igSetKeyboardFocusHere(offset);
403 }
404 }
405
406 #[doc(alias = "SetNavCursorVisible")]
408 pub fn set_nav_cursor_visible(&self, visible: bool) {
409 unsafe { sys::igSetNavCursorVisible(visible) }
410 }
411
412 #[doc(alias = "SetWindowFocus")]
418 pub fn set_window_focus(&self, name: Option<&str>) {
419 unsafe {
420 match name {
421 Some(name) => sys::igSetWindowFocus_Str(self.scratch_txt(name)),
422 None => sys::igSetWindowFocus_Nil(),
423 }
424 }
425 }
426
427 #[doc(alias = "SetWindowPos")]
429 pub fn set_window_pos(&self, pos: [f32; 2]) {
430 self.set_window_pos_with_cond(pos, crate::Condition::Always);
431 }
432
433 #[doc(alias = "SetWindowPos")]
435 pub fn set_window_pos_with_cond(&self, pos: [f32; 2], cond: crate::Condition) {
436 let pos_vec = sys::ImVec2_c {
437 x: pos[0],
438 y: pos[1],
439 };
440 unsafe { sys::igSetWindowPos_Vec2(pos_vec, cond as sys::ImGuiCond) }
441 }
442
443 #[doc(alias = "SetWindowPos")]
445 pub fn set_window_pos_by_name(&self, name: impl AsRef<str>, pos: [f32; 2]) {
446 self.set_window_pos_by_name_with_cond(name, pos, crate::Condition::Always);
447 }
448
449 #[doc(alias = "SetWindowPos")]
451 pub fn set_window_pos_by_name_with_cond(
452 &self,
453 name: impl AsRef<str>,
454 pos: [f32; 2],
455 cond: crate::Condition,
456 ) {
457 let pos_vec = sys::ImVec2_c {
458 x: pos[0],
459 y: pos[1],
460 };
461 unsafe { sys::igSetWindowPos_Str(self.scratch_txt(name), pos_vec, cond as sys::ImGuiCond) }
462 }
463
464 #[doc(alias = "SetWindowSize")]
466 pub fn set_window_size(&self, size: [f32; 2]) {
467 self.set_window_size_with_cond(size, crate::Condition::Always);
468 }
469
470 #[doc(alias = "SetWindowSize")]
472 pub fn set_window_size_with_cond(&self, size: [f32; 2], cond: crate::Condition) {
473 let size_vec = sys::ImVec2_c {
474 x: size[0],
475 y: size[1],
476 };
477 unsafe { sys::igSetWindowSize_Vec2(size_vec, cond as sys::ImGuiCond) }
478 }
479
480 #[doc(alias = "SetWindowSize")]
482 pub fn set_window_size_by_name(&self, name: impl AsRef<str>, size: [f32; 2]) {
483 self.set_window_size_by_name_with_cond(name, size, crate::Condition::Always);
484 }
485
486 #[doc(alias = "SetWindowSize")]
488 pub fn set_window_size_by_name_with_cond(
489 &self,
490 name: impl AsRef<str>,
491 size: [f32; 2],
492 cond: crate::Condition,
493 ) {
494 let size_vec = sys::ImVec2_c {
495 x: size[0],
496 y: size[1],
497 };
498 unsafe {
499 sys::igSetWindowSize_Str(self.scratch_txt(name), size_vec, cond as sys::ImGuiCond);
500 }
501 }
502
503 #[doc(alias = "SetWindowCollapsed")]
505 pub fn set_window_collapsed(&self, collapsed: bool) {
506 self.set_window_collapsed_with_cond(collapsed, crate::Condition::Always);
507 }
508
509 #[doc(alias = "SetWindowCollapsed")]
511 pub fn set_window_collapsed_with_cond(&self, collapsed: bool, cond: crate::Condition) {
512 unsafe { sys::igSetWindowCollapsed_Bool(collapsed, cond as sys::ImGuiCond) }
513 }
514
515 #[doc(alias = "SetWindowCollapsed")]
517 pub fn set_window_collapsed_by_name(&self, name: impl AsRef<str>, collapsed: bool) {
518 self.set_window_collapsed_by_name_with_cond(name, collapsed, crate::Condition::Always);
519 }
520
521 #[doc(alias = "SetWindowCollapsed")]
523 pub fn set_window_collapsed_by_name_with_cond(
524 &self,
525 name: impl AsRef<str>,
526 collapsed: bool,
527 cond: crate::Condition,
528 ) {
529 unsafe {
530 sys::igSetWindowCollapsed_Str(
531 self.scratch_txt(name),
532 collapsed,
533 cond as sys::ImGuiCond,
534 );
535 }
536 }
537
538 #[doc(alias = "SetNextItemOpen")]
542 pub fn set_next_item_open(&self, is_open: bool) {
543 unsafe {
544 sys::igSetNextItemOpen(is_open, 0); }
546 }
547
548 #[doc(alias = "SetNextItemOpen")]
550 pub fn set_next_item_open_with_cond(&self, is_open: bool, cond: crate::Condition) {
551 unsafe { sys::igSetNextItemOpen(is_open, cond as sys::ImGuiCond) }
552 }
553
554 #[doc(alias = "SetNextItemWidth")]
558 pub fn set_next_item_width(&self, item_width: f32) {
559 unsafe {
560 sys::igSetNextItemWidth(item_width);
561 }
562 }
563
564 #[doc(alias = "GetStyle")]
580 pub unsafe fn style(&self) -> &crate::Style {
581 unsafe {
582 &*(sys::igGetStyle() as *const crate::Style)
584 }
585 }
586
587 #[doc(alias = "GetStyle")]
591 pub fn clone_style(&self) -> crate::Style {
592 unsafe { self.style().clone() }
593 }
594
595 #[doc(alias = "StyleColorsDark")]
597 pub fn style_colors_dark(&self) {
598 unsafe { sys::igStyleColorsDark(std::ptr::null_mut()) }
599 }
600
601 #[doc(alias = "StyleColorsLight")]
603 pub fn style_colors_light(&self) {
604 unsafe { sys::igStyleColorsLight(std::ptr::null_mut()) }
605 }
606
607 #[doc(alias = "StyleColorsClassic")]
609 pub fn style_colors_classic(&self) {
610 unsafe { sys::igStyleColorsClassic(std::ptr::null_mut()) }
611 }
612
613 #[doc(alias = "StyleColorsDark")]
615 pub fn style_colors_dark_into(&self, dst: &mut crate::Style) {
616 unsafe { sys::igStyleColorsDark(dst.raw_mut() as *mut sys::ImGuiStyle) }
617 }
618
619 #[doc(alias = "StyleColorsLight")]
621 pub fn style_colors_light_into(&self, dst: &mut crate::Style) {
622 unsafe { sys::igStyleColorsLight(dst.raw_mut() as *mut sys::ImGuiStyle) }
623 }
624
625 #[doc(alias = "StyleColorsClassic")]
627 pub fn style_colors_classic_into(&self, dst: &mut crate::Style) {
628 unsafe { sys::igStyleColorsClassic(dst.raw_mut() as *mut sys::ImGuiStyle) }
629 }
630
631 #[doc(alias = "GetWindowDpiScale")]
633 pub fn window_dpi_scale(&self) -> f32 {
634 unsafe { sys::igGetWindowDpiScale() }
635 }
636
637 #[doc(alias = "Value")]
639 pub fn value_bool(&self, prefix: impl AsRef<str>, v: bool) {
640 unsafe { sys::igValue_Bool(self.scratch_txt(prefix), v) }
641 }
642
643 #[doc(alias = "GetWindowWidth")]
645 pub fn window_width(&self) -> f32 {
646 unsafe { sys::igGetWindowWidth() }
647 }
648
649 #[doc(alias = "GetWindowHeight")]
651 pub fn window_height(&self) -> f32 {
652 unsafe { sys::igGetWindowHeight() }
653 }
654
655 #[doc(alias = "GetWindowPos")]
657 pub fn window_pos(&self) -> [f32; 2] {
658 let v = unsafe { sys::igGetWindowPos() };
659 [v.x, v.y]
660 }
661
662 #[doc(alias = "GetWindowSize")]
664 pub fn window_size(&self) -> [f32; 2] {
665 let v = unsafe { sys::igGetWindowSize() };
666 [v.x, v.y]
667 }
668
669 #[doc(alias = "ShowDebugLogWindow")]
677 pub fn show_debug_log_window(&self, opened: &mut bool) {
678 unsafe {
679 sys::igShowDebugLogWindow(opened);
680 }
681 }
682
683 #[doc(alias = "ShowIDStackToolWindow")]
687 pub fn show_id_stack_tool_window(&self, opened: &mut bool) {
688 unsafe {
689 sys::igShowIDStackToolWindow(opened);
690 }
691 }
692
693 #[doc(alias = "ShowStyleSelector")]
697 pub fn show_style_selector(&self, label: impl AsRef<str>) -> bool {
698 unsafe { sys::igShowStyleSelector(self.scratch_txt(label)) }
699 }
700
701 #[doc(alias = "ShowFontSelector")]
703 pub fn show_font_selector(&self, label: impl AsRef<str>) {
704 unsafe {
705 sys::igShowFontSelector(self.scratch_txt(label));
706 }
707 }
708
709 #[doc(alias = "GetVersion")]
711 pub fn get_version(&self) -> &str {
712 unsafe {
713 let version_ptr = sys::igGetVersion();
714 if version_ptr.is_null() {
715 return "Unknown";
716 }
717 let c_str = std::ffi::CStr::from_ptr(version_ptr);
718 c_str.to_str().unwrap_or("Unknown")
719 }
720 }
721}