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 ime: std::rc::Rc<std::cell::RefCell<crate::context::ime::ImeState>>,
23 ) -> Self {
24 Ui {
25 ctx,
26 ctx_binding,
27 texture_registry,
28 ime,
29 native_scopes: std::cell::RefCell::new(crate::scope::NativeScopeTracker::default()),
30 buffer: UnsafeCell::new(UiBuffer::new(1024)),
31 }
32 }
33
34 pub(crate) fn context_raw(&self) -> *mut sys::ImGuiContext {
35 self.ctx
36 }
37
38 pub fn binding(&self) -> crate::ContextBinding {
40 self.ctx_binding.clone()
41 }
42
43 pub fn context_id(&self) -> crate::ContextId {
45 self.ctx_binding.id()
46 }
47
48 pub(crate) fn run_with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
49 self.assert_native_scopes_usable();
50 self.ctx_binding.with_bound_context(f)
51 }
52
53 pub(crate) fn resolve_texture_ref(
54 &self,
55 texture: crate::texture::TextureRef<'_>,
56 ) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
57 match texture.source() {
58 crate::texture::TextureSource::Legacy(id) => Ok(sys::ImTextureRef {
59 _TexData: std::ptr::null_mut(),
60 _TexID: sys::ImTextureID::from(id),
61 }),
62 crate::texture::TextureSource::Managed(id) => {
63 self.texture_registry.borrow().resolve(id)
64 }
65 crate::texture::TextureSource::FontAtlas { atlas, texture } => {
66 let io = unsafe { sys::igGetIO_ContextPtr(self.ctx) };
67 if io.is_null() || !std::ptr::eq(unsafe { (*io).Fonts }, atlas) {
68 return Err(crate::texture::ManagedTextureError::ForeignFontAtlas);
69 }
70 Ok(texture)
71 }
72 }
73 }
74
75 #[doc(hidden)]
82 pub unsafe fn resolve_texture_ref_raw(
83 &self,
84 texture: crate::texture::TextureRef<'_>,
85 ) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
86 self.run_with_bound_context(|| self.resolve_texture_ref(texture))
87 }
88
89 pub fn with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
96 self.run_with_bound_context(f)
97 }
98
99 #[doc(alias = "GetIO")]
101 pub fn io(&self) -> &crate::io::Io {
102 self.run_with_bound_context(|| unsafe {
103 let io = sys::igGetIO_Nil();
104 if io.is_null() {
105 panic!("Ui::io() requires an active ImGui context");
106 }
107 &*(io as *const crate::io::Io)
108 })
109 }
110
111 pub(crate) fn scratch_txt(&self, txt: impl AsRef<str>) -> *const std::os::raw::c_char {
113 unsafe {
114 let handle = &mut *self.buffer.get();
115 handle.scratch_txt(txt)
116 }
117 }
118
119 pub(crate) fn scratch_txt_range(
121 &self,
122 txt: impl AsRef<str>,
123 ) -> std::ops::Range<*const std::os::raw::c_char> {
124 unsafe {
125 let handle = &mut *self.buffer.get();
126 handle.scratch_txt_range(txt)
127 }
128 }
129
130 pub(crate) fn scratch_txt_two(
132 &self,
133 txt_0: impl AsRef<str>,
134 txt_1: impl AsRef<str>,
135 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
136 unsafe {
137 let handle = &mut *self.buffer.get();
138 handle.scratch_txt_two(txt_0, txt_1)
139 }
140 }
141
142 pub(crate) fn scratch_txt_with_opt(
144 &self,
145 txt_0: impl AsRef<str>,
146 txt_1: Option<impl AsRef<str>>,
147 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
148 unsafe {
149 let handle = &mut *self.buffer.get();
150 handle.scratch_txt_with_opt(txt_0, txt_1)
151 }
152 }
153
154 pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
156 &self.buffer
157 }
158
159 #[doc(alias = "GetID")]
164 pub fn get_id(&self, label: &str) -> Id {
165 let label = self.scratch_txt_range(label);
166 self.run_with_bound_context(|| unsafe {
167 Id::from(sys::igGetID_StrStr(label.start, label.end))
168 })
169 }
170}