1#![allow(
7 clippy::cast_possible_truncation,
8 clippy::cast_sign_loss,
9 clippy::as_conversions
10)]
11use crate::sys;
12use crate::ui::Ui;
13use crate::window::WindowFlags;
14
15impl Ui {
17 #[doc(alias = "OpenPopup")]
28 pub fn open_popup(&self, str_id: impl AsRef<str>) {
29 let str_id_ptr = self.scratch_txt(str_id);
30 unsafe { sys::igOpenPopup_Str(str_id_ptr, PopupFlags::NONE.bits()) }
31 }
32
33 #[doc(alias = "OpenPopup")]
35 pub fn open_popup_with_flags(&self, str_id: impl AsRef<str>, flags: PopupFlags) {
36 let str_id_ptr = self.scratch_txt(str_id);
37 unsafe {
38 sys::igOpenPopup_Str(str_id_ptr, flags.bits());
39 }
40 }
41
42 #[doc(alias = "OpenPopupOnItemClick")]
46 pub fn open_popup_on_item_click(&self, str_id: Option<&str>) {
47 self.open_popup_on_item_click_with_flags(str_id, PopupFlags::MOUSE_BUTTON_RIGHT);
48 }
49
50 #[doc(alias = "OpenPopupOnItemClick")]
52 pub fn open_popup_on_item_click_with_flags(&self, str_id: Option<&str>, flags: PopupFlags) {
53 let str_id_ptr = str_id
54 .map(|s| self.scratch_txt(s))
55 .unwrap_or(std::ptr::null());
56 unsafe { sys::igOpenPopupOnItemClick(str_id_ptr, flags.bits()) }
57 }
58
59 #[doc(alias = "BeginPopup")]
64 pub fn begin_popup(&self, str_id: impl AsRef<str>) -> Option<PopupToken<'_>> {
65 self.begin_popup_with_flags(str_id, WindowFlags::empty())
66 }
67
68 #[doc(alias = "BeginPopup")]
70 pub fn begin_popup_with_flags(
71 &self,
72 str_id: impl AsRef<str>,
73 flags: WindowFlags,
74 ) -> Option<PopupToken<'_>> {
75 let str_id_ptr = self.scratch_txt(str_id);
76 let render = unsafe { sys::igBeginPopup(str_id_ptr, flags.bits()) };
77
78 if render {
79 Some(PopupToken::new(self))
80 } else {
81 None
82 }
83 }
84
85 #[doc(alias = "BeginPopup")]
90 pub fn popup<F>(&self, str_id: impl AsRef<str>, f: F)
91 where
92 F: FnOnce(),
93 {
94 if let Some(_token) = self.begin_popup(str_id) {
95 f();
96 }
97 }
98
99 #[doc(alias = "BeginPopupModal")]
103 pub fn begin_modal_popup(&self, name: impl AsRef<str>) -> Option<ModalPopupToken<'_>> {
104 let name_ptr = self.scratch_txt(name);
105 let render = unsafe {
106 sys::igBeginPopupModal(name_ptr, std::ptr::null_mut(), WindowFlags::empty().bits())
107 };
108
109 if render {
110 Some(ModalPopupToken::new(self))
111 } else {
112 None
113 }
114 }
115
116 #[doc(alias = "BeginPopupModal")]
125 pub fn begin_modal_popup_with_opened(
126 &self,
127 name: impl AsRef<str>,
128 opened: &mut bool,
129 ) -> Option<ModalPopupToken<'_>> {
130 let name_ptr = self.scratch_txt(name);
131 let opened_ptr = opened as *mut bool;
132 let render =
133 unsafe { sys::igBeginPopupModal(name_ptr, opened_ptr, WindowFlags::empty().bits()) };
134
135 if render {
136 Some(ModalPopupToken::new(self))
137 } else {
138 None
139 }
140 }
141
142 pub fn begin_modal_popup_config<'a>(&'a self, name: &'a str) -> ModalPopup<'a> {
144 ModalPopup {
145 name,
146 opened: None,
147 flags: WindowFlags::empty(),
148 ui: self,
149 }
150 }
151
152 pub fn modal_popup<F, R>(&self, name: impl AsRef<str>, f: F) -> Option<R>
156 where
157 F: FnOnce() -> R,
158 {
159 self.begin_modal_popup(name).map(|_token| f())
160 }
161
162 pub fn modal_popup_with_opened<F, R>(
167 &self,
168 name: impl AsRef<str>,
169 opened: &mut bool,
170 f: F,
171 ) -> Option<R>
172 where
173 F: FnOnce() -> R,
174 {
175 self.begin_modal_popup_with_opened(name, opened)
176 .map(|_token| f())
177 }
178
179 #[doc(alias = "CloseCurrentPopup")]
181 pub fn close_current_popup(&self) {
182 unsafe {
183 sys::igCloseCurrentPopup();
184 }
185 }
186
187 #[doc(alias = "IsPopupOpen")]
189 pub fn is_popup_open(&self, str_id: impl AsRef<str>) -> bool {
190 let str_id_ptr = self.scratch_txt(str_id);
191 unsafe { sys::igIsPopupOpen_Str(str_id_ptr, PopupFlags::NONE.bits()) }
192 }
193
194 #[doc(alias = "IsPopupOpen")]
196 pub fn is_popup_open_with_flags(&self, str_id: impl AsRef<str>, flags: PopupFlags) -> bool {
197 let str_id_ptr = self.scratch_txt(str_id);
198 unsafe { sys::igIsPopupOpen_Str(str_id_ptr, flags.bits()) }
199 }
200
201 #[doc(alias = "BeginPopupContextItem")]
203 pub fn begin_popup_context_item(&self) -> Option<PopupToken<'_>> {
204 self.begin_popup_context_item_with_flags(None, PopupFlags::NONE)
205 }
206
207 #[doc(alias = "BeginPopupContextItem")]
209 pub fn begin_popup_context_item_with_label(
210 &self,
211 str_id: Option<&str>,
212 ) -> Option<PopupToken<'_>> {
213 self.begin_popup_context_item_with_flags(str_id, PopupFlags::NONE)
214 }
215
216 #[doc(alias = "BeginPopupContextItem")]
218 pub fn begin_popup_context_item_with_flags(
219 &self,
220 str_id: Option<&str>,
221 flags: PopupFlags,
222 ) -> Option<PopupToken<'_>> {
223 let str_id_ptr = str_id
224 .map(|s| self.scratch_txt(s))
225 .unwrap_or(std::ptr::null());
226
227 let render = unsafe { sys::igBeginPopupContextItem(str_id_ptr, flags.bits()) };
228
229 render.then(|| PopupToken::new(self))
230 }
231
232 #[doc(alias = "BeginPopupContextWindow")]
234 pub fn begin_popup_context_window(&self) -> Option<PopupToken<'_>> {
235 self.begin_popup_context_window_with_flags(None, PopupFlags::NONE)
236 }
237
238 #[doc(alias = "BeginPopupContextWindow")]
240 pub fn begin_popup_context_window_with_label(
241 &self,
242 str_id: Option<&str>,
243 ) -> Option<PopupToken<'_>> {
244 self.begin_popup_context_window_with_flags(str_id, PopupFlags::NONE)
245 }
246
247 #[doc(alias = "BeginPopupContextWindow")]
249 pub fn begin_popup_context_window_with_flags(
250 &self,
251 str_id: Option<&str>,
252 flags: PopupFlags,
253 ) -> Option<PopupToken<'_>> {
254 let str_id_ptr = str_id
255 .map(|s| self.scratch_txt(s))
256 .unwrap_or(std::ptr::null());
257
258 let render = unsafe { sys::igBeginPopupContextWindow(str_id_ptr, flags.bits()) };
259
260 render.then(|| PopupToken::new(self))
261 }
262
263 #[doc(alias = "BeginPopupContextVoid")]
265 pub fn begin_popup_context_void(&self) -> Option<PopupToken<'_>> {
266 self.begin_popup_context_void_with_flags(None, PopupFlags::NONE)
267 }
268
269 #[doc(alias = "BeginPopupContextVoid")]
271 pub fn begin_popup_context_void_with_label(
272 &self,
273 str_id: Option<&str>,
274 ) -> Option<PopupToken<'_>> {
275 self.begin_popup_context_void_with_flags(str_id, PopupFlags::NONE)
276 }
277
278 #[doc(alias = "BeginPopupContextVoid")]
280 pub fn begin_popup_context_void_with_flags(
281 &self,
282 str_id: Option<&str>,
283 flags: PopupFlags,
284 ) -> Option<PopupToken<'_>> {
285 let str_id_ptr = str_id
286 .map(|s| self.scratch_txt(s))
287 .unwrap_or(std::ptr::null());
288
289 let render = unsafe { sys::igBeginPopupContextVoid(str_id_ptr, flags.bits()) };
290
291 render.then(|| PopupToken::new(self))
292 }
293}
294
295bitflags::bitflags! {
296 #[repr(transparent)]
298 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
299 pub struct PopupFlags: i32 {
300 const NONE = sys::ImGuiPopupFlags_None as i32;
302 const MOUSE_BUTTON_LEFT = sys::ImGuiPopupFlags_MouseButtonLeft as i32;
304 const MOUSE_BUTTON_RIGHT = sys::ImGuiPopupFlags_MouseButtonRight as i32;
306 const MOUSE_BUTTON_MIDDLE = sys::ImGuiPopupFlags_MouseButtonMiddle as i32;
308 const NO_OPEN_OVER_EXISTING_POPUP = sys::ImGuiPopupFlags_NoOpenOverExistingPopup as i32;
310 const NO_OPEN_OVER_ITEMS = sys::ImGuiPopupFlags_NoOpenOverItems as i32;
312 const ANY_POPUP_ID = sys::ImGuiPopupFlags_AnyPopupId as i32;
314 const ANY_POPUP_LEVEL = sys::ImGuiPopupFlags_AnyPopupLevel as i32;
316 const ANY_POPUP = Self::ANY_POPUP_ID.bits() | Self::ANY_POPUP_LEVEL.bits();
318 }
319}
320
321#[derive(Debug)]
323#[must_use]
324pub struct ModalPopup<'ui> {
325 name: &'ui str,
326 opened: Option<&'ui mut bool>,
327 flags: WindowFlags,
328 ui: &'ui Ui,
329}
330
331impl<'ui> ModalPopup<'ui> {
332 pub fn opened(mut self, opened: &'ui mut bool) -> Self {
334 self.opened = Some(opened);
335 self
336 }
337
338 pub fn flags(mut self, flags: WindowFlags) -> Self {
340 self.flags = flags;
341 self
342 }
343
344 pub fn begin(self) -> Option<ModalPopupToken<'ui>> {
346 let name_ptr = self.ui.scratch_txt(self.name);
347 let opened_ptr = self
348 .opened
349 .map(|o| o as *mut bool)
350 .unwrap_or(std::ptr::null_mut());
351
352 let render = unsafe { sys::igBeginPopupModal(name_ptr, opened_ptr, self.flags.bits()) };
353
354 if render {
355 Some(ModalPopupToken::new(self.ui))
356 } else {
357 None
358 }
359 }
360}
361
362#[must_use]
364pub struct PopupToken<'ui> {
365 ui: &'ui Ui,
366}
367
368impl<'ui> PopupToken<'ui> {
369 fn new(ui: &'ui Ui) -> Self {
371 PopupToken { ui }
372 }
373
374 pub fn end(self) {
376 }
378}
379
380impl<'ui> Drop for PopupToken<'ui> {
381 fn drop(&mut self) {
382 unsafe {
383 sys::igEndPopup();
384 }
385 }
386}
387
388#[must_use]
390pub struct ModalPopupToken<'ui> {
391 ui: &'ui Ui,
392}
393
394impl<'ui> ModalPopupToken<'ui> {
395 fn new(ui: &'ui Ui) -> Self {
397 ModalPopupToken { ui }
398 }
399
400 pub fn end(self) {
402 }
404}
405
406impl<'ui> Drop for ModalPopupToken<'ui> {
407 fn drop(&mut self) {
408 unsafe {
409 sys::igEndPopup();
410 }
411 }
412}