dear_imgui_rs/widget/multi_select/
scope.rs1use crate::sys;
2
3use super::basic_selection::BasicSelection;
4use super::options::MultiSelectOptions;
5use super::requests::{apply_multi_select_requests_basic, apply_multi_select_requests_indexed};
6use super::storage::MultiSelectIndexStorage;
7
8fn usize_to_i32(name: &str, value: usize) -> i32 {
9 i32::try_from(value).unwrap_or_else(|_| panic!("{name} exceeded ImGui's i32 range"))
10}
11
12pub struct MultiSelectScope<'ui> {
18 ui: &'ui crate::Ui,
19 pub(super) ms_io_begin: *mut sys::ImGuiMultiSelectIO,
20 items_count: i32,
21 ended: bool,
22}
23
24impl<'ui> MultiSelectScope<'ui> {
25 pub(super) fn new(
26 ui: &'ui crate::Ui,
27 flags: impl Into<MultiSelectOptions>,
28 selection_size: Option<i32>,
29 items_count: usize,
30 ) -> Self {
31 let options = flags.into();
32 let selection_size_i32 = selection_size.unwrap_or(-1);
33 let items_count_i32 = usize_to_i32("items_count", items_count);
34 let ms_io_begin = ui.run_with_bound_context(|| unsafe {
35 sys::igBeginMultiSelect(options.raw(), selection_size_i32, items_count_i32)
36 });
37 Self {
38 ui,
39 ms_io_begin,
40 items_count: items_count_i32,
41 ended: false,
42 }
43 }
44
45 pub fn begin_io(&self) -> &sys::ImGuiMultiSelectIO {
47 unsafe { &*self.ms_io_begin }
48 }
49
50 pub fn begin_io_mut(&mut self) -> &mut sys::ImGuiMultiSelectIO {
52 unsafe { &mut *self.ms_io_begin }
53 }
54
55 pub fn apply_begin_requests_indexed<S: MultiSelectIndexStorage>(&mut self, storage: &mut S) {
57 unsafe {
58 apply_multi_select_requests_indexed(self.ms_io_begin, storage);
59 }
60 }
61
62 pub fn end(mut self) -> MultiSelectEnd<'ui> {
67 let ms_io_end = self
68 .ui
69 .run_with_bound_context(|| unsafe { sys::igEndMultiSelect() });
70 self.ended = true;
71 MultiSelectEnd {
72 ms_io_end,
73 items_count: self.items_count,
74 _marker: std::marker::PhantomData,
75 }
76 }
77}
78
79impl Drop for MultiSelectScope<'_> {
80 fn drop(&mut self) {
81 if !self.ended {
82 self.ui.run_with_bound_context(|| unsafe {
83 sys::igEndMultiSelect();
84 });
85 self.ended = true;
86 }
87 }
88}
89
90pub struct MultiSelectEnd<'ui> {
92 ms_io_end: *mut sys::ImGuiMultiSelectIO,
93 items_count: i32,
94 _marker: std::marker::PhantomData<&'ui crate::Ui>,
95}
96
97impl<'ui> MultiSelectEnd<'ui> {
98 pub fn io(&self) -> &sys::ImGuiMultiSelectIO {
100 unsafe { &*self.ms_io_end }
101 }
102
103 pub fn io_mut(&mut self) -> &mut sys::ImGuiMultiSelectIO {
105 unsafe { &mut *self.ms_io_end }
106 }
107
108 pub fn apply_requests_indexed<S: MultiSelectIndexStorage>(&mut self, storage: &mut S) {
110 unsafe {
111 apply_multi_select_requests_indexed(self.ms_io_end, storage);
112 }
113 }
114
115 pub fn apply_requests_basic<G>(&mut self, selection: &mut BasicSelection, mut id_at_index: G)
117 where
118 G: FnMut(usize) -> crate::Id,
119 {
120 unsafe {
121 apply_multi_select_requests_basic(
122 self.ms_io_end,
123 selection,
124 self.items_count as usize,
125 &mut id_at_index,
126 );
127 }
128 }
129}