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 buffer: UnsafeCell::new(UiBuffer::new(1024)),
28 }
29 }
30
31 pub(crate) fn context_raw(&self) -> *mut sys::ImGuiContext {
32 self.ctx
33 }
34
35 pub fn binding(&self) -> crate::ContextBinding {
37 self.ctx_binding.clone()
38 }
39
40 pub fn context_id(&self) -> crate::ContextId {
42 self.ctx_binding.id()
43 }
44
45 pub(crate) fn run_with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
46 self.ctx_binding.with_bound_context(f)
47 }
48
49 pub(crate) fn resolve_texture_ref(
50 &self,
51 texture: crate::texture::TextureRef<'_>,
52 ) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
53 match texture.source() {
54 crate::texture::TextureSource::Legacy(id) => Ok(sys::ImTextureRef {
55 _TexData: std::ptr::null_mut(),
56 _TexID: sys::ImTextureID::from(id),
57 }),
58 crate::texture::TextureSource::Managed(id) => {
59 self.texture_registry.borrow().resolve(id)
60 }
61 crate::texture::TextureSource::FontAtlas { atlas, texture } => {
62 let io = unsafe { sys::igGetIO_ContextPtr(self.ctx) };
63 if io.is_null() || !std::ptr::eq(unsafe { (*io).Fonts }, atlas) {
64 return Err(crate::texture::ManagedTextureError::ForeignFontAtlas);
65 }
66 Ok(texture)
67 }
68 }
69 }
70
71 #[doc(hidden)]
78 pub unsafe fn resolve_texture_ref_raw(
79 &self,
80 texture: crate::texture::TextureRef<'_>,
81 ) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
82 self.run_with_bound_context(|| self.resolve_texture_ref(texture))
83 }
84
85 pub fn with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
92 self.run_with_bound_context(f)
93 }
94
95 #[doc(alias = "GetIO")]
97 pub fn io(&self) -> &crate::io::Io {
98 self.run_with_bound_context(|| unsafe {
99 let io = sys::igGetIO_Nil();
100 if io.is_null() {
101 panic!("Ui::io() requires an active ImGui context");
102 }
103 &*(io as *const crate::io::Io)
104 })
105 }
106
107 pub(crate) fn scratch_txt(&self, txt: impl AsRef<str>) -> *const std::os::raw::c_char {
109 unsafe {
110 let handle = &mut *self.buffer.get();
111 handle.scratch_txt(txt)
112 }
113 }
114
115 pub(crate) fn scratch_txt_range(
117 &self,
118 txt: impl AsRef<str>,
119 ) -> std::ops::Range<*const std::os::raw::c_char> {
120 unsafe {
121 let handle = &mut *self.buffer.get();
122 handle.scratch_txt_range(txt)
123 }
124 }
125
126 pub(crate) fn scratch_txt_two(
128 &self,
129 txt_0: impl AsRef<str>,
130 txt_1: impl AsRef<str>,
131 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
132 unsafe {
133 let handle = &mut *self.buffer.get();
134 handle.scratch_txt_two(txt_0, txt_1)
135 }
136 }
137
138 pub(crate) fn scratch_txt_with_opt(
140 &self,
141 txt_0: impl AsRef<str>,
142 txt_1: Option<impl AsRef<str>>,
143 ) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
144 unsafe {
145 let handle = &mut *self.buffer.get();
146 handle.scratch_txt_with_opt(txt_0, txt_1)
147 }
148 }
149
150 pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
152 &self.buffer
153 }
154
155 #[doc(alias = "GetID")]
160 pub fn get_id(&self, label: &str) -> Id {
161 let label = self.scratch_txt(label);
162 self.run_with_bound_context(|| unsafe { Id::from(sys::igGetID_Str(label)) })
163 }
164}