use crate::{Id, sys};
use std::marker::PhantomData;
use std::ptr::NonNull;
#[derive(Copy, Clone, Debug)]
pub struct StateStorage<'ui> {
raw: NonNull<sys::ImGuiStorage>,
_phantom: PhantomData<&'ui mut sys::ImGuiStorage>,
}
impl<'ui> StateStorage<'ui> {
pub unsafe fn from_raw(raw: *mut sys::ImGuiStorage) -> Self {
let raw = NonNull::new(raw).expect("StateStorage::from_raw() requires non-null pointer");
Self {
raw,
_phantom: PhantomData,
}
}
pub fn as_raw(self) -> *mut sys::ImGuiStorage {
self.raw.as_ptr()
}
pub fn clear(&mut self) {
unsafe { sys::ImGuiStorage_Clear(self.raw.as_ptr()) }
}
pub fn get_int(&self, key: Id, default: i32) -> i32 {
unsafe { sys::ImGuiStorage_GetInt(self.raw.as_ptr(), key.raw(), default) }
}
pub fn set_int(&mut self, key: Id, value: i32) {
unsafe { sys::ImGuiStorage_SetInt(self.raw.as_ptr(), key.raw(), value) }
}
pub fn get_bool(&self, key: Id, default: bool) -> bool {
unsafe { sys::ImGuiStorage_GetBool(self.raw.as_ptr(), key.raw(), default) }
}
pub fn set_bool(&mut self, key: Id, value: bool) {
unsafe { sys::ImGuiStorage_SetBool(self.raw.as_ptr(), key.raw(), value) }
}
pub fn get_float(&self, key: Id, default: f32) -> f32 {
unsafe { sys::ImGuiStorage_GetFloat(self.raw.as_ptr(), key.raw(), default) }
}
pub fn set_float(&mut self, key: Id, value: f32) {
unsafe { sys::ImGuiStorage_SetFloat(self.raw.as_ptr(), key.raw(), value) }
}
}
#[derive(Debug, Default)]
pub struct OwnedStateStorage {
raw: sys::ImGuiStorage,
}
impl OwnedStateStorage {
pub fn new() -> Self {
Self::default()
}
pub fn as_mut(&mut self) -> &mut sys::ImGuiStorage {
&mut self.raw
}
pub fn as_ref(&self) -> &sys::ImGuiStorage {
&self.raw
}
pub fn as_raw_mut(&mut self) -> *mut sys::ImGuiStorage {
&mut self.raw as *mut sys::ImGuiStorage
}
pub fn as_raw(&self) -> *const sys::ImGuiStorage {
&self.raw as *const sys::ImGuiStorage
}
}
impl Drop for OwnedStateStorage {
fn drop(&mut self) {
unsafe { sys::ImGuiStorage_Clear(self.as_raw_mut()) }
}
}
struct StateStorageOverride {
previous: *mut sys::ImGuiStorage,
}
impl Drop for StateStorageOverride {
fn drop(&mut self) {
unsafe { sys::igSetStateStorage(self.previous) }
}
}
impl crate::ui::Ui {
#[doc(alias = "GetStateStorage")]
pub fn with_current_state_storage<R>(
&self,
f: impl for<'storage> FnOnce(StateStorage<'storage>) -> R,
) -> R {
self.run_with_bound_context(|| unsafe {
f(StateStorage::from_raw(sys::igGetStateStorage()))
})
}
#[doc(alias = "SetStateStorage")]
pub fn with_state_storage<R>(
&self,
storage: &mut OwnedStateStorage,
f: impl for<'storage> FnOnce(StateStorage<'storage>) -> R,
) -> R {
self.run_with_bound_context(|| {
let replacement = storage.as_raw_mut();
let scoped_storage = unsafe { StateStorage::from_raw(replacement) };
let previous = unsafe { sys::igGetStateStorage() };
unsafe { sys::igSetStateStorage(replacement) };
let storage_override = StateStorageOverride { previous };
let result = f(scoped_storage);
drop(storage_override);
result
})
}
#[doc(alias = "SetNextItemStorageID")]
pub fn set_next_item_storage_id(&self, storage_id: Id) {
self.run_with_bound_context(|| unsafe { sys::igSetNextItemStorageID(storage_id.raw()) });
}
}