Skip to main content

dear_imgui_rs/widget/multi_select/
basic_selection.rs

1use crate::{Id, sys};
2
3/// Selection container backed by Dear ImGui's `ImGuiSelectionBasicStorage`.
4///
5/// This stores a set of selected `ImGuiID` values using the optimized helper
6/// provided by Dear ImGui. It is suitable when items are naturally identified
7/// by stable IDs (e.g. table rows, tree nodes).
8#[derive(Debug)]
9pub struct BasicSelection {
10    raw: *mut sys::ImGuiSelectionBasicStorage,
11}
12
13impl BasicSelection {
14    /// Create an empty selection storage.
15    pub fn new() -> Self {
16        unsafe {
17            let ptr = sys::ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage();
18            if ptr.is_null() {
19                panic!("ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage() returned null");
20            }
21            Self { raw: ptr }
22        }
23    }
24
25    /// Return the number of selected items.
26    pub fn len(&self) -> usize {
27        unsafe {
28            let size = (*self.raw).Size;
29            if size <= 0 { 0 } else { size as usize }
30        }
31    }
32
33    /// Returns true if the selection is empty.
34    pub fn is_empty(&self) -> bool {
35        self.len() == 0
36    }
37
38    /// Clear the selection set.
39    pub fn clear(&mut self) {
40        unsafe {
41            sys::ImGuiSelectionBasicStorage_Clear(self.raw);
42        }
43    }
44
45    /// Returns true if the given id is selected.
46    pub fn contains(&self, id: Id) -> bool {
47        unsafe { sys::ImGuiSelectionBasicStorage_Contains(self.raw, id.raw()) }
48    }
49
50    /// Set selection state for a given id.
51    pub fn set_selected(&mut self, id: Id, selected: bool) {
52        unsafe {
53            sys::ImGuiSelectionBasicStorage_SetItemSelected(self.raw, id.raw(), selected);
54        }
55    }
56
57    /// Iterate over selected ids.
58    pub fn iter(&self) -> BasicSelectionIter<'_> {
59        BasicSelectionIter {
60            storage: self,
61            it: std::ptr::null_mut(),
62        }
63    }
64
65    /// Expose raw pointer for internal helpers.
66    pub(crate) fn as_raw(&self) -> *mut sys::ImGuiSelectionBasicStorage {
67        self.raw
68    }
69}
70
71impl Default for BasicSelection {
72    fn default() -> Self {
73        Self::new()
74    }
75}
76
77impl Drop for BasicSelection {
78    fn drop(&mut self) {
79        unsafe {
80            if !self.raw.is_null() {
81                sys::ImGuiSelectionBasicStorage_destroy(self.raw);
82                self.raw = std::ptr::null_mut();
83            }
84        }
85    }
86}
87
88/// Iterator over selected ids stored in [`BasicSelection`].
89pub struct BasicSelectionIter<'a> {
90    storage: &'a BasicSelection,
91    it: *mut std::os::raw::c_void,
92}
93
94impl<'a> Iterator for BasicSelectionIter<'a> {
95    type Item = Id;
96
97    fn next(&mut self) -> Option<Self::Item> {
98        unsafe {
99            let mut out_id: sys::ImGuiID = 0;
100            let has_next = sys::ImGuiSelectionBasicStorage_GetNextSelectedItem(
101                self.storage.as_raw(),
102                &mut self.it,
103                &mut out_id,
104            );
105            if has_next {
106                Some(Id::from(out_id))
107            } else {
108                None
109            }
110        }
111    }
112}