aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-03 23:09:43 +0800
committercrupest <crupest@outlook.com>2022-02-03 23:09:43 +0800
commit3cff638896ed1bacd9953d5bf29542556e7abaf2 (patch)
tree32d5a971f749ac5fdfe353007c4ee4d8baf8ae1a
parent168c73731cefabdec877e0c9c2cdf15e1b06a9bc (diff)
downloadcru-3cff638896ed1bacd9953d5bf29542556e7abaf2.tar.gz
cru-3cff638896ed1bacd9953d5bf29542556e7abaf2.tar.bz2
cru-3cff638896ed1bacd9953d5bf29542556e7abaf2.zip
...
-rw-r--r--demos/main/main.cpp12
-rw-r--r--src/osx/gui/Menu.mm24
-rw-r--r--src/osx/gui/MenuPrivate.h4
3 files changed, 37 insertions, 3 deletions
diff --git a/demos/main/main.cpp b/demos/main/main.cpp
index 9a3e8d62..223d4974 100644
--- a/demos/main/main.cpp
+++ b/demos/main/main.cpp
@@ -23,6 +23,18 @@ using cru::ui::controls::Window;
int main() {
IUiApplication* application = cru::platform::bootstrap::CreateUiApplication();
+ auto application_menu = application->GetApplicationMenu();
+
+ if (application_menu) {
+ auto mi = application->GetApplicationMenu()
+ ->GetItemAt(0)
+ ->GetSubmenu()
+ ->CreateItemAt(0);
+ mi->SetTitle(u"Quit");
+ mi->SetEnabled(true);
+ mi->SetOnClickHandler([&]() { application->RequestQuit(0); });
+ }
+
const auto window = Window::Create();
const auto flex_layout = FlexLayout::Create();
diff --git a/src/osx/gui/Menu.mm b/src/osx/gui/Menu.mm
index a980b7f6..69e45ad3 100644
--- a/src/osx/gui/Menu.mm
+++ b/src/osx/gui/Menu.mm
@@ -15,6 +15,7 @@ namespace details {
OsxMenuItemPrivate::OsxMenuItemPrivate(OsxMenuItem* d) {
d_ = d;
sub_menu_ = new OsxMenu(d->GetUiApplication());
+ sub_menu_->p_->SetParentItem(d);
handler_ = [[CruOsxMenuItemClickHandler alloc] init:this];
}
@@ -80,8 +81,14 @@ OsxMenu* OsxMenu::CreateOrGetApplicationMenu(IUiApplication* ui_application) {
return application_menu.get();
}
+ NSMenu* native_main_menu = [[NSMenu alloc] init];
+ [NSApp setMainMenu:native_main_menu];
+ [native_main_menu setAutoenablesItems:NO];
+
application_menu.reset(new OsxMenu(ui_application));
- application_menu->p_->AttachToNative([NSApp mainMenu]);
+ application_menu->p_->AttachToNative(native_main_menu);
+
+ application_menu->CreateItemAt(0);
return application_menu.get();
}
@@ -106,6 +113,13 @@ IMenuItem* OsxMenu::CreateItemAt(int index) {
if (index < 0) index = 0;
if (index > p_->items_.size()) index = p_->items_.size();
+ if (p_->parent_item_ && p_->items_.empty()) {
+ Expects(p_->menu_ == nullptr);
+ p_->menu_ = [[NSMenu alloc] init];
+ [p_->menu_ setAutoenablesItems:NO];
+ [p_->parent_item_->p_->GetNative() setSubmenu:p_->menu_];
+ }
+
auto native_item = [[NSMenuItem alloc] init];
[p_->menu_ insertItem:native_item atIndex:index];
@@ -127,6 +141,12 @@ void OsxMenu::RemoveItemAt(int index) {
p_->items_.erase(p_->items_.begin() + index);
delete item;
+
+ if (p_->items_.empty() && p_->parent_item_) {
+ Expects(p_->menu_ != nullptr);
+ [p_->parent_item_->p_->GetNative() setSubmenu:nullptr];
+ p_->menu_ = nullptr;
+ }
}
}
@@ -139,7 +159,7 @@ void OsxMenu::RemoveItemAt(int index) {
return self;
}
-- (void)handleClick:(id)sender {
+- (void)handleClick {
if (p_->GetOnClickHandler()) {
p_->GetOnClickHandler()();
}
diff --git a/src/osx/gui/MenuPrivate.h b/src/osx/gui/MenuPrivate.h
index 433f246d..02b34422 100644
--- a/src/osx/gui/MenuPrivate.h
+++ b/src/osx/gui/MenuPrivate.h
@@ -6,7 +6,7 @@
@interface CruOsxMenuItemClickHandler : NSObject
- init:(cru::platform::gui::osx::details::OsxMenuItemPrivate*)p;
-- (void)handleClick:(id)sender;
+- (void)handleClick;
@end
namespace cru::platform::gui::osx {
@@ -51,10 +51,12 @@ class OsxMenuPrivate {
~OsxMenuPrivate();
public:
+ void SetParentItem(OsxMenuItem* item) { parent_item_ = item; }
void AttachToNative(NSMenu* native_menu);
private:
OsxMenu* d_;
+ OsxMenuItem* parent_item_ = nullptr;
NSMenu* menu_ = nullptr;
std::vector<OsxMenuItem*> items_;
};