use super::{DrawCmd, DrawListIterator};
use crate::internal::{RawCast, RawWrapper};
use crate::sys;
use std::slice;
#[repr(transparent)]
pub struct DrawData(pub(super) sys::ImDrawData);
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub struct DrawRequirements {
raw_callbacks: bool,
}
impl DrawRequirements {
#[must_use]
pub const fn requires_raw_callback_support(self) -> bool {
self.raw_callbacks
}
}
unsafe impl RawCast<sys::ImDrawData> for DrawData {}
pub(super) fn total_count_from_i32(caller: &str, raw: i32) -> usize {
usize::try_from(raw).unwrap_or_else(|_| panic!("{caller} returned a negative count"))
}
impl RawWrapper for DrawData {
type Raw = sys::ImDrawData;
unsafe fn raw(&self) -> &Self::Raw {
unsafe { <Self as RawCast<Self::Raw>>::raw(self) }
}
unsafe fn raw_mut(&mut self) -> &mut Self::Raw {
unsafe { <Self as RawCast<Self::Raw>>::raw_mut(self) }
}
}
impl DrawData {
#[inline]
pub fn valid(&self) -> bool {
self.0.Valid
}
#[inline]
pub fn frame_count(&self) -> usize {
total_count_from_i32("DrawData::frame_count()", self.0.FrameCount)
}
#[inline]
pub fn draw_lists(&self) -> DrawListIterator<'_> {
unsafe { DrawListIterator::new(self.cmd_lists().iter()) }
}
#[inline]
pub fn draw_lists_count(&self) -> usize {
unsafe { self.cmd_lists().len() }
}
#[must_use]
pub fn requirements(&self) -> DrawRequirements {
let raw_callbacks = self.draw_lists().any(|draw_list| {
draw_list
.commands()
.any(|command| matches!(command, DrawCmd::RawCallback(_)))
});
DrawRequirements { raw_callbacks }
}
#[inline]
pub fn total_idx_count(&self) -> usize {
total_count_from_i32("DrawData::total_idx_count()", self.0.TotalIdxCount)
}
#[inline]
pub fn total_vtx_count(&self) -> usize {
total_count_from_i32("DrawData::total_vtx_count()", self.0.TotalVtxCount)
}
#[inline]
pub fn display_pos(&self) -> [f32; 2] {
[self.0.DisplayPos.x, self.0.DisplayPos.y]
}
#[inline]
pub fn display_size(&self) -> [f32; 2] {
[self.0.DisplaySize.x, self.0.DisplaySize.y]
}
#[inline]
pub fn framebuffer_scale(&self) -> [f32; 2] {
[self.0.FramebufferScale.x, self.0.FramebufferScale.y]
}
#[inline]
pub fn owner_viewport(&self) -> *mut sys::ImGuiViewport {
self.0.OwnerViewport
}
#[inline]
pub(crate) unsafe fn cmd_lists(&self) -> &[*mut sys::ImDrawList] {
unsafe {
if self.0.CmdLists.Size <= 0 || self.0.CmdLists.Data.is_null() {
return &[];
}
let len = match usize::try_from(self.0.CmdLists.Size) {
Ok(len) => len,
Err(_) => return &[],
};
slice::from_raw_parts(self.0.CmdLists.Data, len)
}
}
#[doc(alias = "DeIndexAllBuffers")]
pub fn deindex_all_buffers(&mut self) {
unsafe {
sys::ImDrawData_DeIndexAllBuffers(RawWrapper::raw_mut(self));
}
}
#[doc(alias = "ScaleClipRects")]
pub fn scale_clip_rects(&mut self, fb_scale: [f32; 2]) {
unsafe {
let scale = sys::ImVec2 {
x: fb_scale[0],
y: fb_scale[1],
};
sys::ImDrawData_ScaleClipRects(RawWrapper::raw_mut(self), scale);
}
}
}