Skip to main content

dear_imgui_rs/render/draw_data/
list.rs

1use super::{DrawCmdIterator, DrawIdx, DrawVert};
2use crate::internal::RawWrapper;
3use crate::sys;
4use std::slice;
5
6/// Iterator over draw lists
7pub struct DrawListIterator<'a> {
8    iter: std::slice::Iter<'a, *mut sys::ImDrawList>,
9}
10
11impl<'a> Iterator for DrawListIterator<'a> {
12    type Item = &'a DrawList;
13
14    fn next(&mut self) -> Option<Self::Item> {
15        self.iter.next().and_then(|&ptr| {
16            if ptr.is_null() {
17                None
18            } else {
19                Some(unsafe { DrawList::from_raw(ptr.cast_const()) })
20            }
21        })
22    }
23}
24
25impl<'a> ExactSizeIterator for DrawListIterator<'a> {
26    fn len(&self) -> usize {
27        self.iter.len()
28    }
29}
30
31impl<'a> DrawListIterator<'a> {
32    pub(super) fn new(iter: std::slice::Iter<'a, *mut sys::ImDrawList>) -> Self {
33        Self { iter }
34    }
35}
36
37/// Draw command list
38#[repr(transparent)]
39pub struct DrawList(sys::ImDrawList);
40
41// Ensure the wrapper stays layout-compatible with the sys bindings.
42const _: [(); std::mem::size_of::<sys::ImDrawList>()] = [(); std::mem::size_of::<DrawList>()];
43const _: [(); std::mem::align_of::<sys::ImDrawList>()] = [(); std::mem::align_of::<DrawList>()];
44
45impl RawWrapper for DrawList {
46    type Raw = sys::ImDrawList;
47    #[inline]
48    unsafe fn raw(&self) -> &sys::ImDrawList {
49        &self.0
50    }
51    #[inline]
52    unsafe fn raw_mut(&mut self) -> &mut sys::ImDrawList {
53        &mut self.0
54    }
55}
56
57impl DrawList {
58    #[inline]
59    pub(crate) unsafe fn from_raw<'a>(raw: *const sys::ImDrawList) -> &'a Self {
60        unsafe { &*(raw as *const Self) }
61    }
62
63    #[inline]
64    pub(crate) unsafe fn cmd_buffer(&self) -> &[sys::ImDrawCmd] {
65        unsafe {
66            let cmd_buffer = &self.0.CmdBuffer;
67            if cmd_buffer.Size <= 0 || cmd_buffer.Data.is_null() {
68                return &[];
69            }
70            let len = match usize::try_from(cmd_buffer.Size) {
71                Ok(len) => len,
72                Err(_) => return &[],
73            };
74            slice::from_raw_parts(cmd_buffer.Data, len)
75        }
76    }
77
78    /// Returns an iterator over the draw commands in this draw list
79    pub fn commands(&self) -> DrawCmdIterator<'_> {
80        unsafe { DrawCmdIterator::new(self.cmd_buffer().iter()) }
81    }
82
83    /// Get vertex buffer as slice
84    pub fn vtx_buffer(&self) -> &[DrawVert] {
85        unsafe {
86            let vtx_buffer = &self.0.VtxBuffer;
87            if vtx_buffer.Size <= 0 || vtx_buffer.Data.is_null() {
88                return &[];
89            }
90            let len = match usize::try_from(vtx_buffer.Size) {
91                Ok(len) => len,
92                Err(_) => return &[],
93            };
94            slice::from_raw_parts(vtx_buffer.Data as *const DrawVert, len)
95        }
96    }
97
98    /// Get index buffer as slice
99    pub fn idx_buffer(&self) -> &[DrawIdx] {
100        unsafe {
101            let idx_buffer = &self.0.IdxBuffer;
102            if idx_buffer.Size <= 0 || idx_buffer.Data.is_null() {
103                return &[];
104            }
105            let len = match usize::try_from(idx_buffer.Size) {
106                Ok(len) => len,
107                Err(_) => return &[],
108            };
109            slice::from_raw_parts(idx_buffer.Data, len)
110        }
111    }
112}
113
114/// Owned draw list returned by `CloneOutput`.
115///
116/// This owns an independent copy of a draw list and will free it on drop.
117pub struct OwnedDrawList(*mut sys::ImDrawList);
118
119impl Drop for OwnedDrawList {
120    fn drop(&mut self) {
121        unsafe { sys::ImDrawList_destroy(self.0) }
122    }
123}
124
125impl OwnedDrawList {
126    /// Create from raw pointer.
127    ///
128    /// Safety: `ptr` must be a valid pointer returned by `ImDrawList_CloneOutput` or `ImDrawList_ImDrawList`.
129    pub(crate) unsafe fn from_raw(ptr: *mut sys::ImDrawList) -> Self {
130        Self(ptr)
131    }
132
133    /// Borrow as a read-only draw list view.
134    pub fn as_view(&self) -> &DrawList {
135        unsafe { DrawList::from_raw(self.0) }
136    }
137
138    /// Clear free memory held by the draw list (release heap allocations).
139    pub fn clear_free_memory(&mut self) {
140        unsafe { sys::ImDrawList__ClearFreeMemory(self.0) }
141    }
142
143    /// Reset for new frame (not commonly needed for cloned lists).
144    pub fn reset_for_new_frame(&mut self) {
145        unsafe { sys::ImDrawList__ResetForNewFrame(self.0) }
146    }
147}