use super::*;
impl Ui {
pub(crate) fn assert_finite_f32(caller: &str, name: &str, value: f32) {
assert!(value.is_finite(), "{caller} {name} must be finite");
}
pub(super) fn assert_finite_vec2(caller: &str, name: &str, value: [f32; 2]) {
assert!(
value[0].is_finite() && value[1].is_finite(),
"{caller} {name} must contain finite values"
);
}
pub(crate) fn new(
ctx: *mut sys::ImGuiContext,
ctx_binding: crate::ContextBinding,
texture_registry: crate::context::SharedTextureRegistry,
) -> Self {
Ui {
ctx,
ctx_binding,
texture_registry,
native_scopes: std::cell::RefCell::new(crate::scope::NativeScopeTracker::default()),
buffer: UnsafeCell::new(UiBuffer::new(1024)),
}
}
pub(crate) fn context_raw(&self) -> *mut sys::ImGuiContext {
self.ctx
}
pub fn binding(&self) -> crate::ContextBinding {
self.ctx_binding.clone()
}
pub fn context_id(&self) -> crate::ContextId {
self.ctx_binding.id()
}
pub(crate) fn run_with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
self.assert_native_scopes_usable();
self.ctx_binding.with_bound_context(f)
}
pub(crate) fn resolve_texture_ref(
&self,
texture: crate::texture::TextureRef<'_>,
) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
match texture.source() {
crate::texture::TextureSource::Legacy(id) => Ok(sys::ImTextureRef {
_TexData: std::ptr::null_mut(),
_TexID: sys::ImTextureID::from(id),
}),
crate::texture::TextureSource::Managed(id) => {
self.texture_registry.borrow().resolve(id)
}
crate::texture::TextureSource::FontAtlas { atlas, texture } => {
let io = unsafe { sys::igGetIO_ContextPtr(self.ctx) };
if io.is_null() || !std::ptr::eq(unsafe { (*io).Fonts }, atlas) {
return Err(crate::texture::ManagedTextureError::ForeignFontAtlas);
}
Ok(texture)
}
}
}
#[doc(hidden)]
pub unsafe fn resolve_texture_ref_raw(
&self,
texture: crate::texture::TextureRef<'_>,
) -> Result<sys::ImTextureRef, crate::texture::ManagedTextureError> {
self.run_with_bound_context(|| self.resolve_texture_ref(texture))
}
pub fn with_bound_context<R>(&self, f: impl FnOnce() -> R) -> R {
self.run_with_bound_context(f)
}
#[doc(alias = "GetIO")]
pub fn io(&self) -> &crate::io::Io {
self.run_with_bound_context(|| unsafe {
let io = sys::igGetIO_Nil();
if io.is_null() {
panic!("Ui::io() requires an active ImGui context");
}
&*(io as *const crate::io::Io)
})
}
pub(crate) fn scratch_txt(&self, txt: impl AsRef<str>) -> *const std::os::raw::c_char {
unsafe {
let handle = &mut *self.buffer.get();
handle.scratch_txt(txt)
}
}
pub(crate) fn scratch_txt_range(
&self,
txt: impl AsRef<str>,
) -> std::ops::Range<*const std::os::raw::c_char> {
unsafe {
let handle = &mut *self.buffer.get();
handle.scratch_txt_range(txt)
}
}
pub(crate) fn scratch_txt_two(
&self,
txt_0: impl AsRef<str>,
txt_1: impl AsRef<str>,
) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
unsafe {
let handle = &mut *self.buffer.get();
handle.scratch_txt_two(txt_0, txt_1)
}
}
pub(crate) fn scratch_txt_with_opt(
&self,
txt_0: impl AsRef<str>,
txt_1: Option<impl AsRef<str>>,
) -> (*const std::os::raw::c_char, *const std::os::raw::c_char) {
unsafe {
let handle = &mut *self.buffer.get();
handle.scratch_txt_with_opt(txt_0, txt_1)
}
}
pub(crate) fn scratch_buffer(&self) -> &UnsafeCell<UiBuffer> {
&self.buffer
}
#[doc(alias = "GetID")]
pub fn get_id(&self, label: &str) -> Id {
let label = self.scratch_txt_range(label);
self.run_with_bound_context(|| unsafe {
Id::from(sys::igGetID_StrStr(label.start, label.end))
})
}
}