dear_imgui/widget/
popup.rs1#![allow(
2 clippy::cast_possible_truncation,
3 clippy::cast_sign_loss,
4 clippy::as_conversions
5)]
6use crate::sys;
7use crate::ui::Ui;
8use crate::window::WindowFlags;
9
10impl Ui {
12 #[doc(alias = "OpenPopup")]
23 pub fn open_popup(&self, str_id: impl AsRef<str>) {
24 let str_id_ptr = self.scratch_txt(str_id);
25 unsafe { sys::igOpenPopup_Str(str_id_ptr, PopupFlags::NONE.bits()) }
26 }
27
28 #[doc(alias = "OpenPopup")]
30 pub fn open_popup_with_flags(&self, str_id: impl AsRef<str>, flags: PopupFlags) {
31 let str_id_ptr = self.scratch_txt(str_id);
32 unsafe {
33 sys::igOpenPopup_Str(str_id_ptr, flags.bits());
34 }
35 }
36
37 #[doc(alias = "BeginPopup")]
42 pub fn begin_popup(&self, str_id: impl AsRef<str>) -> Option<PopupToken<'_>> {
43 self.begin_popup_with_flags(str_id, WindowFlags::empty())
44 }
45
46 #[doc(alias = "BeginPopup")]
48 pub fn begin_popup_with_flags(
49 &self,
50 str_id: impl AsRef<str>,
51 flags: WindowFlags,
52 ) -> Option<PopupToken<'_>> {
53 let str_id_ptr = self.scratch_txt(str_id);
54 let render = unsafe { sys::igBeginPopup(str_id_ptr, flags.bits()) };
55
56 if render {
57 Some(PopupToken::new(self))
58 } else {
59 None
60 }
61 }
62
63 #[doc(alias = "BeginPopup")]
68 pub fn popup<F>(&self, str_id: impl AsRef<str>, f: F)
69 where
70 F: FnOnce(),
71 {
72 if let Some(_token) = self.begin_popup(str_id) {
73 f();
74 }
75 }
76
77 #[doc(alias = "BeginPopupModal")]
81 pub fn begin_modal_popup(&self, name: impl AsRef<str>) -> Option<ModalPopupToken<'_>> {
82 let name_ptr = self.scratch_txt(name);
83 let render = unsafe {
84 sys::igBeginPopupModal(name_ptr, std::ptr::null_mut(), WindowFlags::empty().bits())
85 };
86
87 if render {
88 Some(ModalPopupToken::new(self))
89 } else {
90 None
91 }
92 }
93
94 pub fn begin_modal_popup_config<'a>(&'a self, name: &'a str) -> ModalPopup<'a> {
96 ModalPopup {
97 name,
98 opened: None,
99 flags: WindowFlags::empty(),
100 ui: self,
101 }
102 }
103
104 pub fn modal_popup<F, R>(&self, name: impl AsRef<str>, f: F) -> Option<R>
108 where
109 F: FnOnce() -> R,
110 {
111 self.begin_modal_popup(name).map(|_token| f())
112 }
113
114 #[doc(alias = "CloseCurrentPopup")]
116 pub fn close_current_popup(&self) {
117 unsafe {
118 sys::igCloseCurrentPopup();
119 }
120 }
121
122 #[doc(alias = "IsPopupOpen")]
124 pub fn is_popup_open(&self, str_id: impl AsRef<str>) -> bool {
125 let str_id_ptr = self.scratch_txt(str_id);
126 unsafe { sys::igIsPopupOpen_Str(str_id_ptr, PopupFlags::NONE.bits()) }
127 }
128
129 #[doc(alias = "IsPopupOpen")]
131 pub fn is_popup_open_with_flags(&self, str_id: impl AsRef<str>, flags: PopupFlags) -> bool {
132 let str_id_ptr = self.scratch_txt(str_id);
133 unsafe { sys::igIsPopupOpen_Str(str_id_ptr, flags.bits()) }
134 }
135
136 #[doc(alias = "BeginPopupContextItem")]
139 pub fn begin_popup_context_item(&self) -> Option<PopupToken<'_>> {
140 self.begin_popup_context_item_with_label(None)
141 }
142
143 #[doc(alias = "BeginPopupContextItem")]
145 pub fn begin_popup_context_item_with_label(
146 &self,
147 str_id: Option<&str>,
148 ) -> Option<PopupToken<'_>> {
149 let str_id_ptr = str_id
150 .map(|s| self.scratch_txt(s))
151 .unwrap_or(std::ptr::null());
152
153 let render = unsafe {
154 sys::igBeginPopupContextItem(str_id_ptr, PopupFlags::MOUSE_BUTTON_RIGHT.bits())
155 };
156
157 if render {
158 Some(PopupToken::new(self))
159 } else {
160 None
161 }
162 }
163
164 #[doc(alias = "BeginPopupContextWindow")]
166 pub fn begin_popup_context_window(&self) -> Option<PopupToken<'_>> {
167 self.begin_popup_context_window_with_label(None)
168 }
169
170 #[doc(alias = "BeginPopupContextWindow")]
172 pub fn begin_popup_context_window_with_label(
173 &self,
174 str_id: Option<&str>,
175 ) -> Option<PopupToken<'_>> {
176 let str_id_ptr = str_id
177 .map(|s| self.scratch_txt(s))
178 .unwrap_or(std::ptr::null());
179
180 let render = unsafe {
181 sys::igBeginPopupContextWindow(str_id_ptr, PopupFlags::MOUSE_BUTTON_RIGHT.bits())
182 };
183
184 if render {
185 Some(PopupToken::new(self))
186 } else {
187 None
188 }
189 }
190
191 #[doc(alias = "BeginPopupContextVoid")]
193 pub fn begin_popup_context_void(&self) -> Option<PopupToken<'_>> {
194 self.begin_popup_context_void_with_label(None)
195 }
196
197 #[doc(alias = "BeginPopupContextVoid")]
199 pub fn begin_popup_context_void_with_label(
200 &self,
201 str_id: Option<&str>,
202 ) -> Option<PopupToken<'_>> {
203 let str_id_ptr = str_id
204 .map(|s| self.scratch_txt(s))
205 .unwrap_or(std::ptr::null());
206
207 let render = unsafe {
208 sys::igBeginPopupContextVoid(str_id_ptr, PopupFlags::MOUSE_BUTTON_RIGHT.bits())
209 };
210
211 if render {
212 Some(PopupToken::new(self))
213 } else {
214 None
215 }
216 }
217}
218
219bitflags::bitflags! {
220 #[repr(transparent)]
222 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
223 pub struct PopupFlags: i32 {
224 const NONE = sys::ImGuiPopupFlags_None as i32;
226 const MOUSE_BUTTON_LEFT = sys::ImGuiPopupFlags_MouseButtonLeft as i32;
228 const MOUSE_BUTTON_RIGHT = sys::ImGuiPopupFlags_MouseButtonRight as i32;
230 const MOUSE_BUTTON_MIDDLE = sys::ImGuiPopupFlags_MouseButtonMiddle as i32;
232 const NO_OPEN_OVER_EXISTING_POPUP = sys::ImGuiPopupFlags_NoOpenOverExistingPopup as i32;
234 const NO_OPEN_OVER_ITEMS = sys::ImGuiPopupFlags_NoOpenOverItems as i32;
236 const ANY_POPUP_ID = sys::ImGuiPopupFlags_AnyPopupId as i32;
238 const ANY_POPUP_LEVEL = sys::ImGuiPopupFlags_AnyPopupLevel as i32;
240 const ANY_POPUP = Self::ANY_POPUP_ID.bits() | Self::ANY_POPUP_LEVEL.bits();
242 }
243}
244
245#[derive(Debug)]
247#[must_use]
248pub struct ModalPopup<'ui> {
249 name: &'ui str,
250 opened: Option<&'ui mut bool>,
251 flags: WindowFlags,
252 ui: &'ui Ui,
253}
254
255impl<'ui> ModalPopup<'ui> {
256 pub fn opened(mut self, opened: &'ui mut bool) -> Self {
258 self.opened = Some(opened);
259 self
260 }
261
262 pub fn flags(mut self, flags: WindowFlags) -> Self {
264 self.flags = flags;
265 self
266 }
267
268 pub fn begin(self) -> Option<ModalPopupToken<'ui>> {
270 let name_ptr = self.ui.scratch_txt(self.name);
271 let opened_ptr = self
272 .opened
273 .map(|o| o as *mut bool)
274 .unwrap_or(std::ptr::null_mut());
275
276 let render = unsafe { sys::igBeginPopupModal(name_ptr, opened_ptr, self.flags.bits()) };
277
278 if render {
279 Some(ModalPopupToken::new(self.ui))
280 } else {
281 None
282 }
283 }
284}
285
286#[must_use]
288pub struct PopupToken<'ui> {
289 ui: &'ui Ui,
290}
291
292impl<'ui> PopupToken<'ui> {
293 fn new(ui: &'ui Ui) -> Self {
295 PopupToken { ui }
296 }
297
298 pub fn end(self) {
300 }
302}
303
304impl<'ui> Drop for PopupToken<'ui> {
305 fn drop(&mut self) {
306 unsafe {
307 sys::igEndPopup();
308 }
309 }
310}
311
312#[must_use]
314pub struct ModalPopupToken<'ui> {
315 ui: &'ui Ui,
316}
317
318impl<'ui> ModalPopupToken<'ui> {
319 fn new(ui: &'ui Ui) -> Self {
321 ModalPopupToken { ui }
322 }
323
324 pub fn end(self) {
326 }
328}
329
330impl<'ui> Drop for ModalPopupToken<'ui> {
331 fn drop(&mut self) {
332 unsafe {
333 sys::igEndPopup();
334 }
335 }
336}