Skip to main content

dear_imgui_rs/widget/menu/
entry.rs

1use crate::sys;
2use crate::ui::Ui;
3
4use super::{MainMenuBarToken, MenuBarToken, MenuToken};
5
6/// # Menu Widgets
7impl Ui {
8    /// Creates and starts appending to a full-screen menu bar.
9    ///
10    /// Returns `Some(MainMenuBarToken)` if the menu bar is visible. After content has been
11    /// rendered, the token must be ended by calling `.end()`.
12    ///
13    /// Returns `None` if the menu bar is not visible and no content should be rendered.
14    #[must_use]
15    #[doc(alias = "BeginMainMenuBar")]
16    pub fn begin_main_menu_bar(&self) -> Option<MainMenuBarToken<'_>> {
17        if self.run_with_bound_context(|| unsafe { sys::igBeginMainMenuBar() }) {
18            Some(MainMenuBarToken::new(self))
19        } else {
20            None
21        }
22    }
23
24    /// Creates the full-screen main menu bar and runs a closure to construct its contents.
25    ///
26    /// Returns `None` without calling `f` when the menu bar is not visible. The menu bar is ended
27    /// before a successful closure result is returned and during unwinding if `f` panics.
28    #[doc(alias = "BeginMainMenuBar", alias = "EndMainMenuBar")]
29    pub fn main_menu_bar<R>(&self, f: impl FnOnce() -> R) -> Option<R> {
30        let token = self.begin_main_menu_bar()?;
31        let result = f();
32        drop(token);
33        Some(result)
34    }
35
36    /// Creates and starts appending to a menu bar for a window.
37    ///
38    /// Returns `Some(MenuBarToken)` if the menu bar is visible. After content has been
39    /// rendered, the token must be ended by calling `.end()`.
40    ///
41    /// Returns `None` if the menu bar is not visible and no content should be rendered.
42    #[must_use]
43    #[doc(alias = "BeginMenuBar")]
44    pub fn begin_menu_bar(&self) -> Option<MenuBarToken<'_>> {
45        if self.run_with_bound_context(|| unsafe { sys::igBeginMenuBar() }) {
46            Some(MenuBarToken::new(self))
47        } else {
48            None
49        }
50    }
51
52    /// Creates the current window's menu bar and runs a closure to construct its contents.
53    ///
54    /// Returns `None` without calling `f` when the menu bar is not visible. The menu bar is ended
55    /// before a successful closure result is returned and during unwinding if `f` panics.
56    #[doc(alias = "BeginMenuBar", alias = "EndMenuBar")]
57    pub fn menu_bar<R>(&self, f: impl FnOnce() -> R) -> Option<R> {
58        let token = self.begin_menu_bar()?;
59        let result = f();
60        drop(token);
61        Some(result)
62    }
63
64    /// Creates a menu and starts appending to it.
65    ///
66    /// Returns `Some(MenuToken)` if the menu is open. After content has been
67    /// rendered, the token must be ended by calling `.end()`.
68    ///
69    /// Returns `None` if the menu is not open and no content should be rendered.
70    #[must_use]
71    #[doc(alias = "BeginMenu")]
72    pub fn begin_menu(&self, label: impl AsRef<str>) -> Option<MenuToken<'_>> {
73        self.begin_menu_with_enabled(label, true)
74    }
75
76    /// Creates a menu with enabled state and starts appending to it.
77    ///
78    /// Returns `Some(MenuToken)` if the menu is open. After content has been
79    /// rendered, the token must be ended by calling `.end()`.
80    ///
81    /// Returns `None` if the menu is not open and no content should be rendered.
82    #[must_use]
83    #[doc(alias = "BeginMenu")]
84    pub fn begin_menu_with_enabled(
85        &self,
86        label: impl AsRef<str>,
87        enabled: bool,
88    ) -> Option<MenuToken<'_>> {
89        let label_ptr = self.scratch_txt(label);
90        if self.run_with_bound_context(|| unsafe { sys::igBeginMenu(label_ptr, enabled) }) {
91            Some(MenuToken::new(self))
92        } else {
93            None
94        }
95    }
96
97    /// Creates a menu and runs a closure to construct the contents.
98    ///
99    /// Note: the closure is not called if the menu is not visible.
100    ///
101    /// This is the equivalent of [menu_with_enabled](Self::menu_with_enabled)
102    /// with `enabled` set to `true`.
103    #[doc(alias = "BeginMenu")]
104    pub fn menu<F: FnOnce()>(&self, label: impl AsRef<str>, f: F) {
105        self.menu_with_enabled(label, true, f);
106    }
107
108    /// Creates a menu and runs a closure to construct the contents.
109    ///
110    /// Note: the closure is not called if the menu is not visible.
111    #[doc(alias = "BeginMenu")]
112    pub fn menu_with_enabled<F: FnOnce()>(&self, label: impl AsRef<str>, enabled: bool, f: F) {
113        if let Some(_menu) = self.begin_menu_with_enabled(label, enabled) {
114            f();
115        }
116    }
117}