1use super::*;
2
3impl Ui {
4 pub(crate) fn assert_finite_f32(caller: &str, name: &str, value: f32) {
5 assert!(value.is_finite(), "{caller} {name} must be finite");
6 }
7
8 pub(super) fn assert_finite_vec2(caller: &str, name: &str, value: [f32; 2]) {
9 assert!(
10 value[0].is_finite() && value[1].is_finite(),
11 "{caller} {name} must contain finite values"
12 );
13 }
14
15 pub(crate) fn new(
19 ctx: *mut sys::ImGuiContext,
20 ctx_binding: crate::ContextBinding,
21 texture_registry: crate::context::SharedTextureRegistry,
22 ) -> Self {
23 Ui {
24 ctx,
25 ctx_binding,
26 texture_registry,
27 native_scopes: std::cell::RefCell::new(crate::scope::NativeScopeTracker::default()),
28 buffer: UnsafeCell::new(UiBuffer::new(1024)),
29 }
30 }
31
32 pub(crate) fn context_raw(&self) -> *mut sys::ImGuiContext {
33 self.ctx
34 }
35
36 pub fn binding(&self) -> crate::ContextBinding {
38 self.ctx_binding.clone()
39 }
40
41 pub fn context_id(&self) -> crate::ContextId {
43 self.ctx_binding.id()
44 }
45
46 pub(crate) fn run_with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
47 self.assert_native_scopes_usable();
48 self.ctx_binding.with_bound_context(f)
49 }
50
51 pub(crate) fn resolve_texture_ref(
52 &self,
53 texture: crate::texture::TextureRef<'_>,
54 ) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
55 match texture.source() {
56 crate::texture::TextureSource::Legacy(id) => Ok(sys::ImTextureRef {
57 _TexData: std::ptr::null_mut(),
58 _TexID: sys::ImTextureID::from(id),
59 }),
60 crate::texture::TextureSource::Managed(id) => {
61 self.texture_registry.borrow().resolve(id)
62 }
63 crate::texture::TextureSource::FontAtlas { atlas, texture } => {
64 let io = unsafe { sys::igGetIO_ContextPtr(self.ctx) };
65 if io.is_null() || !std::ptr::eq(unsafe { (*io).Fonts }, atlas) {
66 return Err(crate::texture::ManagedTextureError::ForeignFontAtlas);
67 }
68 Ok(texture)
69 }
70 }
71 }
72
73 #[doc(hidden)]
80 pub unsafe fn resolve_texture_ref_raw(
81 &self,
82 texture: crate::texture::TextureRef<'_>,
83 ) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
84 self.run_with_bound_context(|| self.resolve_texture_ref(texture))
85 }
86
87 pub fn with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
94 self.run_with_bound_context(f)
95 }
96
97 #[doc(alias = "GetIO")]
99 pub fn io(&self) -> &crate::io::Io {
100 self.run_with_bound_context(|| unsafe {
101 let io = sys::igGetIO_Nil();
102 if io.is_null() {
103 panic!("Ui::io() requires an active ImGui context");
104 }
105 &*(io as *const crate::io::Io)
106 })
107 }
108
109 pub(crate) fn scratch_txt(&self, txt: impl AsRef<str>) -> *const std::os::raw::c_char {
111 unsafe {
112 let handle = &mut *self.buffer.get();
113 handle.scratch_txt(txt)
114 }
115 }
116
117 pub(crate) fn scratch_txt_range(
119 &self,
120 txt: impl AsRef<str>,
121 ) -> std::ops::Range<*const std::os::raw::c_char> {
122 unsafe {
123 let handle = &mut *self.buffer.get();
124 handle.scratch_txt_range(txt)
125 }
126 }
127
128 pub(crate) fn scratch_txt_two(
130 &self,
131 txt_0: impl AsRef<str>,
132 txt_1: impl AsRef<str>,
133 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
134 unsafe {
135 let handle = &mut *self.buffer.get();
136 handle.scratch_txt_two(txt_0, txt_1)
137 }
138 }
139
140 pub(crate) fn scratch_txt_with_opt(
142 &self,
143 txt_0: impl AsRef<str>,
144 txt_1: Option<impl AsRef<str>>,
145 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
146 unsafe {
147 let handle = &mut *self.buffer.get();
148 handle.scratch_txt_with_opt(txt_0, txt_1)
149 }
150 }
151
152 pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
154 &self.buffer
155 }
156
157 #[doc(alias = "GetID")]
162 pub fn get_id(&self, label: &str) -> Id {
163 let label = self.scratch_txt_range(label);
164 self.run_with_bound_context(|| unsafe {
165 Id::from(sys::igGetID_StrStr(label.start, label.end))
166 })
167 }
168}