#[cfg(all(target_arch = "wasm32", feature = "multi-viewport"))]
compile_error!("The `multi-viewport` feature is not supported on wasm32 targets yet.");
use crate::sys;
#[cfg(feature = "multi-viewport")]
use core::ffi::c_char;
use std::cell::UnsafeCell;
#[cfg(feature = "multi-viewport")]
use std::ffi::c_void;
#[repr(transparent)]
pub struct PlatformIo {
raw: UnsafeCell<sys::ImGuiPlatformIO>,
}
const _: [(); std::mem::size_of::<sys::ImGuiPlatformIO>()] =
[(); std::mem::size_of::<PlatformIo>()];
const _: [(); std::mem::align_of::<sys::ImGuiPlatformIO>()] =
[(); std::mem::align_of::<PlatformIo>()];
#[cfg(feature = "multi-viewport")]
mod trampolines;
mod viewport;
pub use viewport::Viewport;
impl PlatformIo {
#[inline]
fn inner(&self) -> &sys::ImGuiPlatformIO {
unsafe { &*self.raw.get() }
}
#[inline]
fn inner_mut(&mut self) -> &mut sys::ImGuiPlatformIO {
unsafe { &mut *self.raw.get() }
}
pub unsafe fn from_raw<'a>(raw: *const sys::ImGuiPlatformIO) -> &'a Self {
unsafe { &*(raw as *const Self) }
}
pub unsafe fn from_raw_mut<'a>(raw: *mut sys::ImGuiPlatformIO) -> &'a mut Self {
unsafe { &mut *(raw as *mut Self) }
}
pub fn as_raw(&self) -> *const sys::ImGuiPlatformIO {
self.raw.get().cast_const()
}
pub fn as_raw_mut(&mut self) -> *mut sys::ImGuiPlatformIO {
self.raw.get()
}
#[cfg(feature = "multi-viewport")]
pub fn clear_platform_handlers(&mut self) {
unsafe { sys::ImGuiPlatformIO_ClearPlatformHandlers(self.as_raw_mut()) }
}
#[cfg(feature = "multi-viewport")]
pub fn clear_renderer_handlers(&mut self) {
unsafe { sys::ImGuiPlatformIO_ClearRendererHandlers(self.as_raw_mut()) }
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_create_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Platform_CreateWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_create_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&PLATFORM_CREATE_WINDOW_CB, callback);
self.set_platform_create_window_raw(callback.map(|_| {
trampolines::platform_create_window as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_destroy_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Platform_DestroyWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_destroy_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&PLATFORM_DESTROY_WINDOW_CB, callback);
self.set_platform_destroy_window_raw(callback.map(|_| {
trampolines::platform_destroy_window as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_show_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Platform_ShowWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_show_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SHOW_WINDOW_CB, callback);
self.set_platform_show_window_raw(callback.map(|_| {
trampolines::platform_show_window as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_set_window_pos_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, sys::ImVec2)>,
) {
self.inner_mut().Platform_SetWindowPos = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_set_window_pos(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, sys::ImVec2)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SET_WINDOW_POS_CB, callback);
self.set_platform_set_window_pos_raw(callback.map(|_| {
trampolines::platform_set_window_pos
as unsafe extern "C" fn(*mut sys::ImGuiViewport, sys::ImVec2)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_get_window_pos_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport) -> sys::ImVec2>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_POS_RAW_CB, callback);
store_cb(&PLATFORM_GET_WINDOW_POS_CB, None);
unsafe {
match callback {
Some(_) => sys::ImGuiPlatformIO_Set_Platform_GetWindowPos(
self.as_raw_mut(),
Some(
trampolines::platform_get_window_pos_out
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut sys::ImVec2),
),
),
None => self.inner_mut().Platform_GetWindowPos = None,
}
}
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_get_window_pos(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport) -> sys::ImVec2>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_POS_RAW_CB, None);
store_cb(&PLATFORM_GET_WINDOW_POS_CB, callback);
unsafe {
match callback {
Some(_) => sys::ImGuiPlatformIO_Set_Platform_GetWindowPos(
self.as_raw_mut(),
Some(
trampolines::platform_get_window_pos_out
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut sys::ImVec2),
),
),
None => self.inner_mut().Platform_GetWindowPos = None,
}
}
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_set_window_size_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, sys::ImVec2)>,
) {
self.inner_mut().Platform_SetWindowSize = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_set_window_size(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, sys::ImVec2)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SET_WINDOW_SIZE_CB, callback);
self.set_platform_set_window_size_raw(callback.map(|_| {
trampolines::platform_set_window_size
as unsafe extern "C" fn(*mut sys::ImGuiViewport, sys::ImVec2)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_get_window_size_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport) -> sys::ImVec2>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_SIZE_RAW_CB, callback);
store_cb(&PLATFORM_GET_WINDOW_SIZE_CB, None);
unsafe {
match callback {
Some(_) => sys::ImGuiPlatformIO_Set_Platform_GetWindowSize(
self.as_raw_mut(),
Some(
trampolines::platform_get_window_size_out
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut sys::ImVec2),
),
),
None => self.inner_mut().Platform_GetWindowSize = None,
}
}
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_get_window_size(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport) -> sys::ImVec2>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_SIZE_RAW_CB, None);
store_cb(&PLATFORM_GET_WINDOW_SIZE_CB, callback);
unsafe {
match callback {
Some(_) => sys::ImGuiPlatformIO_Set_Platform_GetWindowSize(
self.as_raw_mut(),
Some(
trampolines::platform_get_window_size_out
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut sys::ImVec2),
),
),
None => self.inner_mut().Platform_GetWindowSize = None,
}
}
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_set_window_focus_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Platform_SetWindowFocus = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_set_window_focus(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SET_WINDOW_FOCUS_CB, callback);
self.set_platform_set_window_focus_raw(callback.map(|_| {
trampolines::platform_set_window_focus as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_get_window_dpi_scale_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport) -> f32>,
) {
self.inner_mut().Platform_GetWindowDpiScale = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_get_window_dpi_scale(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport) -> f32>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_DPI_SCALE_CB, callback);
self.set_platform_get_window_dpi_scale_raw(callback.map(|_| {
trampolines::platform_get_window_dpi_scale
as unsafe extern "C" fn(*mut sys::ImGuiViewport) -> f32
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_get_window_focus_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport) -> bool>,
) {
self.inner_mut().Platform_GetWindowFocus = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_get_window_focus(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport) -> bool>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_FOCUS_CB, callback);
self.set_platform_get_window_focus_raw(callback.map(|_| {
trampolines::platform_get_window_focus
as unsafe extern "C" fn(*mut sys::ImGuiViewport) -> bool
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_get_window_minimized_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport) -> bool>,
) {
self.inner_mut().Platform_GetWindowMinimized = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_get_window_minimized(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport) -> bool>,
) {
use trampolines::*;
store_cb(&PLATFORM_GET_WINDOW_MINIMIZED_CB, callback);
self.set_platform_get_window_minimized_raw(callback.map(|_| {
trampolines::platform_get_window_minimized
as unsafe extern "C" fn(*mut sys::ImGuiViewport) -> bool
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_on_changed_viewport_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Platform_OnChangedViewport = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_on_changed_viewport(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&PLATFORM_ON_CHANGED_VIEWPORT_CB, callback);
self.set_platform_on_changed_viewport_raw(callback.map(|_| {
trampolines::platform_on_changed_viewport
as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_set_window_title_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, *const c_char)>,
) {
self.inner_mut().Platform_SetWindowTitle = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_set_window_title(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, *const c_char)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SET_WINDOW_TITLE_CB, callback);
self.set_platform_set_window_title_raw(callback.map(|_| {
trampolines::platform_set_window_title
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *const c_char)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_set_window_alpha_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, f32)>,
) {
self.inner_mut().Platform_SetWindowAlpha = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_set_window_alpha(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, f32)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SET_WINDOW_ALPHA_CB, callback);
self.set_platform_set_window_alpha_raw(callback.map(|_| {
trampolines::platform_set_window_alpha
as unsafe extern "C" fn(*mut sys::ImGuiViewport, f32)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_update_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Platform_UpdateWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_update_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&PLATFORM_UPDATE_WINDOW_CB, callback);
self.set_platform_update_window_raw(callback.map(|_| {
trampolines::platform_update_window as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_render_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)>,
) {
self.inner_mut().Platform_RenderWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_render_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, *mut c_void)>,
) {
use trampolines::*;
store_cb(&PLATFORM_RENDER_WINDOW_CB, callback);
self.set_platform_render_window_raw(callback.map(|_| {
trampolines::platform_render_window
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_swap_buffers_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)>,
) {
self.inner_mut().Platform_SwapBuffers = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_platform_swap_buffers(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, *mut c_void)>,
) {
use trampolines::*;
store_cb(&PLATFORM_SWAP_BUFFERS_CB, callback);
self.set_platform_swap_buffers_raw(callback.map(|_| {
trampolines::platform_swap_buffers
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn platform_create_vk_surface_raw(
&self,
) -> Option<
unsafe extern "C" fn(
vp: *mut sys::ImGuiViewport,
vk_inst: sys::ImU64,
vk_allocators: *const c_void,
out_vk_surface: *mut sys::ImU64,
) -> std::os::raw::c_int,
> {
self.inner().Platform_CreateVkSurface
}
#[cfg(feature = "multi-viewport")]
pub fn set_platform_create_vk_surface_raw(
&mut self,
callback: Option<
unsafe extern "C" fn(
vp: *mut sys::ImGuiViewport,
vk_inst: sys::ImU64,
vk_allocators: *const c_void,
out_vk_surface: *mut sys::ImU64,
) -> std::os::raw::c_int,
>,
) {
self.inner_mut().Platform_CreateVkSurface = callback;
}
#[cfg(feature = "multi-viewport")]
pub fn set_renderer_create_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Renderer_CreateWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_renderer_create_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&RENDERER_CREATE_WINDOW_CB, callback);
self.set_renderer_create_window_raw(callback.map(|_| {
trampolines::renderer_create_window as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_renderer_destroy_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport)>,
) {
self.inner_mut().Renderer_DestroyWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_renderer_destroy_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport)>,
) {
use trampolines::*;
store_cb(&RENDERER_DESTROY_WINDOW_CB, callback);
self.set_renderer_destroy_window_raw(callback.map(|_| {
trampolines::renderer_destroy_window as unsafe extern "C" fn(*mut sys::ImGuiViewport)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_renderer_set_window_size_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, sys::ImVec2)>,
) {
self.inner_mut().Renderer_SetWindowSize = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_renderer_set_window_size(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, sys::ImVec2)>,
) {
use trampolines::*;
store_cb(&RENDERER_SET_WINDOW_SIZE_CB, callback);
self.set_renderer_set_window_size_raw(callback.map(|_| {
trampolines::renderer_set_window_size
as unsafe extern "C" fn(*mut sys::ImGuiViewport, sys::ImVec2)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_renderer_render_window_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)>,
) {
self.inner_mut().Renderer_RenderWindow = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_renderer_render_window(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, *mut c_void)>,
) {
use trampolines::*;
store_cb(&RENDERER_RENDER_WINDOW_CB, callback);
self.set_renderer_render_window_raw(callback.map(|_| {
trampolines::renderer_render_window
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn set_renderer_swap_buffers_raw(
&mut self,
callback: Option<unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)>,
) {
self.inner_mut().Renderer_SwapBuffers = callback;
}
#[cfg(feature = "multi-viewport")]
pub unsafe fn set_renderer_swap_buffers(
&mut self,
callback: Option<unsafe extern "C" fn(*mut Viewport, *mut c_void)>,
) {
use trampolines::*;
store_cb(&RENDERER_SWAP_BUFFERS_CB, callback);
self.set_renderer_swap_buffers_raw(callback.map(|_| {
trampolines::renderer_swap_buffers
as unsafe extern "C" fn(*mut sys::ImGuiViewport, *mut c_void)
}));
}
#[cfg(feature = "multi-viewport")]
pub fn monitors(&self) -> &crate::internal::ImVector<sys::ImGuiPlatformMonitor> {
unsafe {
crate::internal::imvector_cast_ref::<
sys::ImGuiPlatformMonitor,
sys::ImVector_ImGuiPlatformMonitor,
>(&self.inner().Monitors)
}
}
#[cfg(feature = "multi-viewport")]
pub fn monitors_mut(&mut self) -> &mut crate::internal::ImVector<sys::ImGuiPlatformMonitor> {
unsafe {
crate::internal::imvector_cast_mut::<
sys::ImGuiPlatformMonitor,
sys::ImVector_ImGuiPlatformMonitor,
>(&mut self.inner_mut().Monitors)
}
}
#[cfg(feature = "multi-viewport")]
pub(crate) fn viewports(&self) -> &crate::internal::ImVector<*mut sys::ImGuiViewport> {
unsafe {
crate::internal::imvector_cast_ref::<
*mut sys::ImGuiViewport,
sys::ImVector_ImGuiViewportPtr,
>(&self.inner().Viewports)
}
}
#[cfg(feature = "multi-viewport")]
pub(crate) fn viewports_mut(
&mut self,
) -> &mut crate::internal::ImVector<*mut sys::ImGuiViewport> {
unsafe {
crate::internal::imvector_cast_mut::<
*mut sys::ImGuiViewport,
sys::ImVector_ImGuiViewportPtr,
>(&mut self.inner_mut().Viewports)
}
}
#[cfg(feature = "multi-viewport")]
pub fn viewports_iter(&self) -> impl Iterator<Item = &Viewport> {
self.viewports()
.iter()
.map(|&ptr| unsafe { Viewport::from_raw(ptr) })
}
#[cfg(feature = "multi-viewport")]
pub fn viewports_iter_mut(&mut self) -> impl Iterator<Item = &mut Viewport> {
self.viewports_mut()
.iter_mut()
.map(|&mut ptr| unsafe { Viewport::from_raw_mut(ptr) })
}
pub fn textures(&self) -> crate::render::draw_data::TextureIterator<'_> {
unsafe {
let vector = &self.inner().Textures;
let size = match usize::try_from(vector.Size) {
Ok(size) => size,
Err(_) => 0,
};
if size == 0 || vector.Data.is_null() {
crate::render::draw_data::TextureIterator::new(std::ptr::null(), std::ptr::null())
} else {
crate::render::draw_data::TextureIterator::new(vector.Data, vector.Data.add(size))
}
}
}
pub fn textures_count(&self) -> usize {
let vector = &self.inner().Textures;
if vector.Data.is_null() {
return 0;
}
usize::try_from(vector.Size).unwrap_or(0)
}
pub fn apply_texture_feedback(
&mut self,
feedback: &[crate::render::snapshot::TextureFeedback],
) -> usize {
if feedback.is_empty() {
return 0;
}
let mut by_id: std::collections::HashMap<i32, crate::render::snapshot::TextureFeedback> =
std::collections::HashMap::with_capacity(feedback.len());
for &fb in feedback {
by_id.insert(fb.id.0, fb);
}
let mut applied = 0usize;
for mut tex in self.textures() {
let uid = tex.unique_id();
let Some(fb) = by_id.get(&uid) else { continue };
if fb.status == crate::texture::TextureStatus::Destroyed {
tex.set_status(fb.status);
} else {
if let Some(tex_id) = fb.tex_id {
tex.set_tex_id(tex_id);
}
tex.set_status(fb.status);
}
applied += 1;
}
applied
}
pub fn texture(&self, index: usize) -> Option<&crate::texture::TextureData> {
unsafe {
crate::render::draw_data::assert_texture_data_not_borrowed();
let vector = &self.inner().Textures;
let size = usize::try_from(vector.Size).ok()?;
if size == 0 || vector.Data.is_null() {
return None;
}
if index >= size {
return None;
}
let texture_ptr = *vector.Data.add(index);
if texture_ptr.is_null() {
return None;
}
Some(crate::texture::TextureData::from_raw_ref(
texture_ptr as *const _,
))
}
}
pub fn texture_mut(&mut self, index: usize) -> Option<&mut crate::texture::TextureData> {
unsafe {
let vector = &self.inner().Textures;
let size = usize::try_from(vector.Size).ok()?;
if size == 0 || vector.Data.is_null() {
return None;
}
if index >= size {
return None;
}
let texture_ptr = *vector.Data.add(index);
if texture_ptr.is_null() {
return None;
}
Some(crate::texture::TextureData::from_raw(texture_ptr))
}
}
pub unsafe fn set_renderer_render_state(&mut self, render_state: *mut std::ffi::c_void) {
self.inner_mut().Renderer_RenderState = render_state;
}
pub unsafe fn renderer_render_state(&self) -> *mut std::ffi::c_void {
self.inner().Renderer_RenderState
}
}
#[cfg(test)]
mod tests {
use super::*;
fn new_platform_io() -> sys::ImGuiPlatformIO {
unsafe {
let p = sys::ImGuiPlatformIO_ImGuiPlatformIO();
assert!(
!p.is_null(),
"ImGuiPlatformIO_ImGuiPlatformIO() returned null"
);
let v = *p;
sys::ImGuiPlatformIO_destroy(p);
v
}
}
#[test]
fn platform_io_textures_empty_is_safe() {
let mut raw: sys::ImGuiPlatformIO = new_platform_io();
raw.Textures.Size = 0;
raw.Textures.Data = std::ptr::null_mut();
let pio = PlatformIo {
raw: UnsafeCell::new(raw),
};
assert_eq!(pio.textures().count(), 0);
assert_eq!(pio.textures_count(), 0);
let mut raw: sys::ImGuiPlatformIO = new_platform_io();
raw.Textures.Size = 1;
raw.Textures.Data = std::ptr::null_mut();
let pio = PlatformIo {
raw: UnsafeCell::new(raw),
};
assert_eq!(pio.textures().count(), 0);
assert_eq!(pio.textures_count(), 0);
assert!(pio.texture(0).is_none());
}
#[test]
fn platform_io_from_raw_matches_mut_wrapper() {
let mut raw: sys::ImGuiPlatformIO = new_platform_io();
let raw_ptr = (&mut raw) as *mut sys::ImGuiPlatformIO;
let shared = unsafe { PlatformIo::from_raw(raw_ptr.cast_const()) };
let mutable = unsafe { PlatformIo::from_raw_mut(raw_ptr) };
assert_eq!(shared.as_raw(), mutable.as_raw());
}
#[cfg(feature = "multi-viewport")]
#[test]
fn platform_io_clear_handlers_resets_platform_and_renderer_callbacks() {
unsafe extern "C" fn platform_cb(_viewport: *mut sys::ImGuiViewport) {}
unsafe extern "C" fn renderer_cb(_viewport: *mut sys::ImGuiViewport) {}
unsafe extern "C" fn platform_dpi_scale_cb(_viewport: *mut sys::ImGuiViewport) -> f32 {
1.0
}
let mut raw: sys::ImGuiPlatformIO = new_platform_io();
raw.Platform_CreateWindow = Some(platform_cb);
raw.Platform_DestroyWindow = Some(platform_cb);
raw.Platform_GetWindowDpiScale = Some(platform_dpi_scale_cb);
raw.Platform_OnChangedViewport = Some(platform_cb);
raw.Renderer_CreateWindow = Some(renderer_cb);
raw.Renderer_DestroyWindow = Some(renderer_cb);
let pio = unsafe { PlatformIo::from_raw_mut((&mut raw) as *mut sys::ImGuiPlatformIO) };
pio.clear_platform_handlers();
pio.clear_renderer_handlers();
assert!(raw.Platform_CreateWindow.is_none());
assert!(raw.Platform_DestroyWindow.is_none());
assert!(raw.Platform_GetWindowDpiScale.is_none());
assert!(raw.Platform_OnChangedViewport.is_none());
assert!(raw.Renderer_CreateWindow.is_none());
assert!(raw.Renderer_DestroyWindow.is_none());
}
}