dear_imgui_rs/widget/
popup.rs1#![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 = "BeginPopup")]
47 pub fn begin_popup(&self, str_id: impl AsRef<str>) -> Option<PopupToken<'_>> {
48 self.begin_popup_with_flags(str_id, WindowFlags::empty())
49 }
50
51 #[doc(alias = "BeginPopup")]
53 pub fn begin_popup_with_flags(
54 &self,
55 str_id: impl AsRef<str>,
56 flags: WindowFlags,
57 ) -> Option<PopupToken<'_>> {
58 let str_id_ptr = self.scratch_txt(str_id);
59 let render = unsafe { sys::igBeginPopup(str_id_ptr, flags.bits()) };
60
61 if render {
62 Some(PopupToken::new(self))
63 } else {
64 None
65 }
66 }
67
68 #[doc(alias = "BeginPopup")]
73 pub fn popup<F>(&self, str_id: impl AsRef<str>, f: F)
74 where
75 F: FnOnce(),
76 {
77 if let Some(_token) = self.begin_popup(str_id) {
78 f();
79 }
80 }
81
82 #[doc(alias = "BeginPopupModal")]
86 pub fn begin_modal_popup(&self, name: impl AsRef<str>) -> Option<ModalPopupToken<'_>> {
87 let name_ptr = self.scratch_txt(name);
88 let render = unsafe {
89 sys::igBeginPopupModal(name_ptr, std::ptr::null_mut(), WindowFlags::empty().bits())
90 };
91
92 if render {
93 Some(ModalPopupToken::new(self))
94 } else {
95 None
96 }
97 }
98
99 pub fn begin_modal_popup_config<'a>(&'a self, name: &'a str) -> ModalPopup<'a> {
101 ModalPopup {
102 name,
103 opened: None,
104 flags: WindowFlags::empty(),
105 ui: self,
106 }
107 }
108
109 pub fn modal_popup<F, R>(&self, name: impl AsRef<str>, f: F) -> Option<R>
113 where
114 F: FnOnce() -> R,
115 {
116 self.begin_modal_popup(name).map(|_token| f())
117 }
118
119 #[doc(alias = "CloseCurrentPopup")]
121 pub fn close_current_popup(&self) {
122 unsafe {
123 sys::igCloseCurrentPopup();
124 }
125 }
126
127 #[doc(alias = "IsPopupOpen")]
129 pub fn is_popup_open(&self, str_id: impl AsRef<str>) -> bool {
130 let str_id_ptr = self.scratch_txt(str_id);
131 unsafe { sys::igIsPopupOpen_Str(str_id_ptr, PopupFlags::NONE.bits()) }
132 }
133
134 #[doc(alias = "IsPopupOpen")]
136 pub fn is_popup_open_with_flags(&self, str_id: impl AsRef<str>, flags: PopupFlags) -> bool {
137 let str_id_ptr = self.scratch_txt(str_id);
138 unsafe { sys::igIsPopupOpen_Str(str_id_ptr, flags.bits()) }
139 }
140
141 #[doc(alias = "BeginPopupContextItem")]
144 pub fn begin_popup_context_item(&self) -> Option<PopupToken<'_>> {
145 self.begin_popup_context_item_with_label(None)
146 }
147
148 #[doc(alias = "BeginPopupContextItem")]
150 pub fn begin_popup_context_item_with_label(
151 &self,
152 str_id: Option<&str>,
153 ) -> Option<PopupToken<'_>> {
154 let str_id_ptr = str_id
155 .map(|s| self.scratch_txt(s))
156 .unwrap_or(std::ptr::null());
157
158 let render = unsafe {
159 sys::igBeginPopupContextItem(str_id_ptr, PopupFlags::MOUSE_BUTTON_RIGHT.bits())
160 };
161
162 if render {
163 Some(PopupToken::new(self))
164 } else {
165 None
166 }
167 }
168
169 #[doc(alias = "BeginPopupContextWindow")]
171 pub fn begin_popup_context_window(&self) -> Option<PopupToken<'_>> {
172 self.begin_popup_context_window_with_label(None)
173 }
174
175 #[doc(alias = "BeginPopupContextWindow")]
177 pub fn begin_popup_context_window_with_label(
178 &self,
179 str_id: Option<&str>,
180 ) -> Option<PopupToken<'_>> {
181 let str_id_ptr = str_id
182 .map(|s| self.scratch_txt(s))
183 .unwrap_or(std::ptr::null());
184
185 let render = unsafe {
186 sys::igBeginPopupContextWindow(str_id_ptr, PopupFlags::MOUSE_BUTTON_RIGHT.bits())
187 };
188
189 if render {
190 Some(PopupToken::new(self))
191 } else {
192 None
193 }
194 }
195
196 #[doc(alias = "BeginPopupContextVoid")]
198 pub fn begin_popup_context_void(&self) -> Option<PopupToken<'_>> {
199 self.begin_popup_context_void_with_label(None)
200 }
201
202 #[doc(alias = "BeginPopupContextVoid")]
204 pub fn begin_popup_context_void_with_label(
205 &self,
206 str_id: Option<&str>,
207 ) -> Option<PopupToken<'_>> {
208 let str_id_ptr = str_id
209 .map(|s| self.scratch_txt(s))
210 .unwrap_or(std::ptr::null());
211
212 let render = unsafe {
213 sys::igBeginPopupContextVoid(str_id_ptr, PopupFlags::MOUSE_BUTTON_RIGHT.bits())
214 };
215
216 if render {
217 Some(PopupToken::new(self))
218 } else {
219 None
220 }
221 }
222}
223
224bitflags::bitflags! {
225 #[repr(transparent)]
227 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
228 pub struct PopupFlags: i32 {
229 const NONE = sys::ImGuiPopupFlags_None as i32;
231 const MOUSE_BUTTON_LEFT = sys::ImGuiPopupFlags_MouseButtonLeft as i32;
233 const MOUSE_BUTTON_RIGHT = sys::ImGuiPopupFlags_MouseButtonRight as i32;
235 const MOUSE_BUTTON_MIDDLE = sys::ImGuiPopupFlags_MouseButtonMiddle as i32;
237 const NO_OPEN_OVER_EXISTING_POPUP = sys::ImGuiPopupFlags_NoOpenOverExistingPopup as i32;
239 const NO_OPEN_OVER_ITEMS = sys::ImGuiPopupFlags_NoOpenOverItems as i32;
241 const ANY_POPUP_ID = sys::ImGuiPopupFlags_AnyPopupId as i32;
243 const ANY_POPUP_LEVEL = sys::ImGuiPopupFlags_AnyPopupLevel as i32;
245 const ANY_POPUP = Self::ANY_POPUP_ID.bits() | Self::ANY_POPUP_LEVEL.bits();
247 }
248}
249
250#[derive(Debug)]
252#[must_use]
253pub struct ModalPopup<'ui> {
254 name: &'ui str,
255 opened: Option<&'ui mut bool>,
256 flags: WindowFlags,
257 ui: &'ui Ui,
258}
259
260impl<'ui> ModalPopup<'ui> {
261 pub fn opened(mut self, opened: &'ui mut bool) -> Self {
263 self.opened = Some(opened);
264 self
265 }
266
267 pub fn flags(mut self, flags: WindowFlags) -> Self {
269 self.flags = flags;
270 self
271 }
272
273 pub fn begin(self) -> Option<ModalPopupToken<'ui>> {
275 let name_ptr = self.ui.scratch_txt(self.name);
276 let opened_ptr = self
277 .opened
278 .map(|o| o as *mut bool)
279 .unwrap_or(std::ptr::null_mut());
280
281 let render = unsafe { sys::igBeginPopupModal(name_ptr, opened_ptr, self.flags.bits()) };
282
283 if render {
284 Some(ModalPopupToken::new(self.ui))
285 } else {
286 None
287 }
288 }
289}
290
291#[must_use]
293pub struct PopupToken<'ui> {
294 ui: &'ui Ui,
295}
296
297impl<'ui> PopupToken<'ui> {
298 fn new(ui: &'ui Ui) -> Self {
300 PopupToken { ui }
301 }
302
303 pub fn end(self) {
305 }
307}
308
309impl<'ui> Drop for PopupToken<'ui> {
310 fn drop(&mut self) {
311 unsafe {
312 sys::igEndPopup();
313 }
314 }
315}
316
317#[must_use]
319pub struct ModalPopupToken<'ui> {
320 ui: &'ui Ui,
321}
322
323impl<'ui> ModalPopupToken<'ui> {
324 fn new(ui: &'ui Ui) -> Self {
326 ModalPopupToken { ui }
327 }
328
329 pub fn end(self) {
331 }
333}
334
335impl<'ui> Drop for ModalPopupToken<'ui> {
336 fn drop(&mut self) {
337 unsafe {
338 sys::igEndPopup();
339 }
340 }
341}