use std::cell::RefCell;
use std::marker::PhantomData;
use crate::sys;
mod clip;
mod geometry;
mod image;
mod raw;
mod split;
#[cfg(test)]
mod tests;
mod text;
mod texture;
pub use texture::DrawListTextureToken;
thread_local! {
static BORROWED_DRAW_LISTS: RefCell<Vec<usize>> = RefCell::new(Vec::new());
}
pub struct DrawListMut<'ui> {
pub(super) draw_list: *mut sys::ImDrawList,
pub(super) _phantom: PhantomData<&'ui crate::Ui>,
}
pub(super) struct ChannelsSplitMergeGuard<'ui> {
pub(super) draw_list: &'ui DrawListMut<'ui>,
}
impl Drop for ChannelsSplitMergeGuard<'_> {
fn drop(&mut self) {
unsafe { sys::ImDrawList_ChannelsMerge(self.draw_list.draw_list) };
}
}
pub(super) struct DrawListClipRectGuard<'ui> {
pub(super) draw_list: &'ui DrawListMut<'ui>,
}
impl Drop for DrawListClipRectGuard<'_> {
fn drop(&mut self) {
unsafe { sys::ImDrawList_PopClipRect(self.draw_list.draw_list) };
}
}
impl Drop for DrawListMut<'_> {
fn drop(&mut self) {
let ptr = self.draw_list as usize;
BORROWED_DRAW_LISTS.with(|borrowed| {
let mut borrowed = borrowed.borrow_mut();
if let Some(index) = borrowed.iter().position(|&value| value == ptr) {
borrowed.swap_remove(index);
}
});
}
}
impl<'ui> DrawListMut<'ui> {
fn borrow_draw_list(draw_list: *mut sys::ImDrawList) {
assert!(
!draw_list.is_null(),
"DrawListMut::borrow_draw_list() received a null draw list"
);
let ptr = draw_list as usize;
BORROWED_DRAW_LISTS.with(|borrowed| {
let mut borrowed = borrowed.borrow_mut();
if borrowed.contains(&ptr) {
panic!("A DrawListMut is already in use for this draw list");
}
borrowed.push(ptr);
});
}
fn from_raw(draw_list: *mut sys::ImDrawList) -> Self {
Self::borrow_draw_list(draw_list);
Self {
draw_list,
_phantom: PhantomData,
}
}
pub unsafe fn from_raw_mut(_ui: &'ui crate::Ui, draw_list: *mut sys::ImDrawList) -> Self {
Self::from_raw(draw_list)
}
pub(crate) fn window(_ui: &'ui crate::Ui) -> Self {
Self::from_raw(unsafe { sys::igGetWindowDrawList() })
}
pub(crate) fn background(_ui: &'ui crate::Ui) -> Self {
let viewport = unsafe { sys::igGetMainViewport() };
Self::from_raw(unsafe { sys::igGetBackgroundDrawList(viewport) })
}
pub(crate) fn foreground(_ui: &'ui crate::Ui) -> Self {
let viewport = unsafe { sys::igGetMainViewport() };
Self::from_raw(unsafe { sys::igGetForegroundDrawList_ViewportPtr(viewport) })
}
}