Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MenuBar] Use NativeMenu RIDs instead of indices to track items. #89875

Merged
1 commit merged into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@
<param index="0" name="menu_root" type="String" />
<param index="1" name="tag" type="Variant" />
<description>
Returns the index of the item with the specified [param tag]. Index is automatically assigned to each item by the engine. Index can not be set manually.
Returns the index of the item with the specified [param tag]. Indices are automatically assigned to each item by the engine, and cannot be set manually.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
Expand All @@ -562,7 +562,7 @@
<param index="0" name="menu_root" type="String" />
<param index="1" name="text" type="String" />
<description>
Returns the index of the item with the specified [param text]. Index is automatically assigned to each item by the engine. Index can not be set manually.
Returns the index of the item with the specified [param text]. Indices are automatically assigned to each item by the engine, and cannot be set manually.
[b]Note:[/b] This method is implemented only on macOS.
</description>
</method>
Expand Down
13 changes: 11 additions & 2 deletions doc/classes/NativeMenu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,21 @@
[b]Note:[/b] This method is implemented on macOS and Windows.
</description>
</method>
<method name="find_item_index_with_submenu" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="submenu_rid" type="RID" />
<description>
Returns the index of the item with the submenu specified by [param submenu_rid]. Indices are automatically assigned to each item by the engine, and cannot be set manually.
[b]Note:[/b] This method is implemented on macOS and Windows.
</description>
</method>
<method name="find_item_index_with_tag" qualifiers="const">
<return type="int" />
<param index="0" name="rid" type="RID" />
<param index="1" name="tag" type="Variant" />
<description>
Returns the index of the item with the specified [param tag]. Index is automatically assigned to each item by the engine. Index can not be set manually.
Returns the index of the item with the specified [param tag]. Indices are automatically assigned to each item by the engine, and cannot be set manually.
[b]Note:[/b] This method is implemented on macOS and Windows.
</description>
</method>
Expand All @@ -225,7 +234,7 @@
<param index="0" name="rid" type="RID" />
<param index="1" name="text" type="String" />
<description>
Returns the index of the item with the specified [param text]. Index is automatically assigned to each item by the engine. Index can not be set manually.
Returns the index of the item with the specified [param text]. Indices are automatically assigned to each item by the engine, and cannot be set manually.
[b]Note:[/b] This method is implemented on macOS and Windows.
</description>
</method>
Expand Down
86 changes: 55 additions & 31 deletions scene/gui/menu_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,12 @@ void MenuBar::bind_global_menu() {
RID submenu_rid = popups[i]->bind_global_menu();
if (!popups[i]->is_system_menu()) {
int index = nmenu->add_submenu_item(main_menu, menu_cache[i].name, submenu_rid, global_menu_tag + "#" + itos(i), global_start_idx + i);
menu_cache.write[i].global_index = index;
menu_cache.write[i].submenu_rid = submenu_rid;
nmenu->set_item_hidden(main_menu, index, menu_cache[i].hidden);
nmenu->set_item_disabled(main_menu, index, menu_cache[i].disabled);
nmenu->set_item_tooltip(main_menu, index, menu_cache[i].tooltip);
} else {
menu_cache.write[i].global_index = -1;
menu_cache.write[i].submenu_rid = RID();
}
}
}
Expand All @@ -257,11 +257,14 @@ void MenuBar::unbind_global_menu() {
Vector<PopupMenu *> popups = _get_popups();
for (int i = menu_cache.size() - 1; i >= 0; i--) {
if (!popups[i]->is_system_menu()) {
popups[i]->unbind_global_menu();
if (menu_cache[i].global_index >= 0) {
nmenu->remove_item(main_menu, menu_cache[i].global_index);
if (menu_cache[i].submenu_rid.is_valid()) {
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[i].submenu_rid);
if (item_idx >= 0) {
nmenu->remove_item(main_menu, item_idx);
}
}
menu_cache.write[i].global_index = -1;
popups[i]->unbind_global_menu();
menu_cache.write[i].submenu_rid = RID();
}
}

Expand Down Expand Up @@ -292,8 +295,11 @@ void MenuBar::_notification(int p_what) {
RID main_menu = is_global ? nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID) : RID();
for (int i = 0; i < menu_cache.size(); i++) {
shape(menu_cache.write[i]);
if (is_global && menu_cache[i].global_index >= 0) {
nmenu->set_item_text(main_menu, menu_cache[i].global_index, atr(menu_cache[i].name));
if (is_global && menu_cache[i].submenu_rid.is_valid()) {
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[i].submenu_rid);
if (item_idx >= 0) {
nmenu->set_item_text(main_menu, item_idx, atr(menu_cache[i].name));
}
}
}
} break;
Expand Down Expand Up @@ -500,8 +506,11 @@ void MenuBar::_refresh_menu_names() {
if (!popups[i]->has_meta("_menu_name") && String(popups[i]->get_name()) != get_menu_title(i)) {
menu_cache.write[i].name = popups[i]->get_name();
shape(menu_cache.write[i]);
if (is_global && menu_cache[i].global_index >= 0) {
nmenu->set_item_text(main_menu, menu_cache[i].global_index, atr(menu_cache[i].name));
if (is_global && menu_cache[i].submenu_rid.is_valid()) {
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[i].submenu_rid);
if (item_idx >= 0) {
nmenu->set_item_text(main_menu, item_idx, atr(menu_cache[i].name));
}
}
}
}
Expand Down Expand Up @@ -554,8 +563,8 @@ void MenuBar::add_child_notify(Node *p_child) {

RID submenu_rid = pm->bind_global_menu();
if (!pm->is_system_menu()) {
int index = nmenu->add_submenu_item(main_menu, atr(menu.name), submenu_rid, global_menu_tag + "#" + itos(menu_cache.size() - 1), _find_global_start_index() + menu_cache.size() - 1);
menu_cache.write[menu_cache.size() - 1].global_index = index;
nmenu->add_submenu_item(main_menu, atr(menu.name), submenu_rid, global_menu_tag + "#" + itos(menu_cache.size() - 1), _find_global_start_index() + menu_cache.size() - 1);
menu_cache.write[menu_cache.size() - 1].submenu_rid = submenu_rid;
}
}
update_minimum_size();
Expand Down Expand Up @@ -589,13 +598,14 @@ void MenuBar::move_child_notify(Node *p_child) {
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);

int global_start = _find_global_start_index();
if (menu.global_index >= 0) {
nmenu->remove_item(main_menu, menu.global_index);
if (menu.submenu_rid.is_valid()) {
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu.submenu_rid);
if (item_idx >= 0) {
nmenu->remove_item(main_menu, item_idx);
}
}
if (new_idx != -1) {
RID submenu_rid = pm->bind_global_menu();
int index = nmenu->add_submenu_item(main_menu, atr(menu.name), submenu_rid, global_menu_tag + "#" + itos(new_idx), global_start + new_idx);
menu_cache.write[new_idx].global_index = index;
nmenu->add_submenu_item(main_menu, atr(menu.name), menu.submenu_rid, global_menu_tag + "#" + itos(new_idx), global_start + new_idx);
}
}
}
Expand All @@ -611,20 +621,22 @@ void MenuBar::remove_child_notify(Node *p_child) {

int idx = get_menu_idx_from_control(pm);

menu_cache.remove_at(idx);

if (!global_menu_tag.is_empty()) {
if (!pm->is_system_menu()) {
pm->unbind_global_menu();
if (menu_cache[idx].global_index >= 0) {
if (menu_cache[idx].submenu_rid.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->remove_item(main_menu, menu_cache[idx].global_index);
menu_cache.write[idx].global_index = -1;
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[idx].submenu_rid);
if (item_idx >= 0) {
nmenu->remove_item(main_menu, item_idx);
}
}
pm->unbind_global_menu();
}
}

menu_cache.remove_at(idx);

p_child->remove_meta("_menu_name");
p_child->remove_meta("_menu_tooltip");

Expand Down Expand Up @@ -817,10 +829,13 @@ void MenuBar::set_menu_title(int p_menu, const String &p_title) {
}
menu_cache.write[p_menu].name = p_title;
shape(menu_cache.write[p_menu]);
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
if (!global_menu_tag.is_empty() && menu_cache[p_menu].submenu_rid.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_text(main_menu, menu_cache[p_menu].global_index, atr(menu_cache[p_menu].name));
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[p_menu].submenu_rid);
if (item_idx >= 0) {
nmenu->set_item_text(main_menu, item_idx, atr(menu_cache[p_menu].name));
}
}
update_minimum_size();
}
Expand All @@ -835,10 +850,13 @@ void MenuBar::set_menu_tooltip(int p_menu, const String &p_tooltip) {
PopupMenu *pm = get_menu_popup(p_menu);
pm->set_meta("_menu_tooltip", p_tooltip);
menu_cache.write[p_menu].tooltip = p_tooltip;
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
if (!global_menu_tag.is_empty() && menu_cache[p_menu].submenu_rid.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_tooltip(main_menu, menu_cache[p_menu].global_index, p_tooltip);
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[p_menu].submenu_rid);
if (item_idx >= 0) {
nmenu->set_item_tooltip(main_menu, item_idx, p_tooltip);
}
}
}

Expand All @@ -850,10 +868,13 @@ String MenuBar::get_menu_tooltip(int p_menu) const {
void MenuBar::set_menu_disabled(int p_menu, bool p_disabled) {
ERR_FAIL_INDEX(p_menu, menu_cache.size());
menu_cache.write[p_menu].disabled = p_disabled;
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
if (!global_menu_tag.is_empty() && menu_cache[p_menu].submenu_rid.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_disabled(main_menu, menu_cache[p_menu].global_index, p_disabled);
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[p_menu].submenu_rid);
if (item_idx >= 0) {
nmenu->set_item_disabled(main_menu, item_idx, p_disabled);
}
}
}

Expand All @@ -865,10 +886,13 @@ bool MenuBar::is_menu_disabled(int p_menu) const {
void MenuBar::set_menu_hidden(int p_menu, bool p_hidden) {
ERR_FAIL_INDEX(p_menu, menu_cache.size());
menu_cache.write[p_menu].hidden = p_hidden;
if (!global_menu_tag.is_empty() && menu_cache[p_menu].global_index >= 0) {
if (!global_menu_tag.is_empty() && menu_cache[p_menu].submenu_rid.is_valid()) {
NativeMenu *nmenu = NativeMenu::get_singleton();
RID main_menu = nmenu->get_system_menu(NativeMenu::MAIN_MENU_ID);
nmenu->set_item_hidden(main_menu, menu_cache[p_menu].global_index, p_hidden);
int item_idx = nmenu->find_item_index_with_submenu(main_menu, menu_cache[p_menu].submenu_rid);
if (item_idx >= 0) {
nmenu->set_item_hidden(main_menu, item_idx, p_hidden);
}
}
update_minimum_size();
}
Expand Down
2 changes: 1 addition & 1 deletion scene/gui/menu_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class MenuBar : public Control {
Ref<TextLine> text_buf;
bool hidden = false;
bool disabled = false;
int global_index = -1;
RID submenu_rid;

Menu(const String &p_name) {
name = p_name;
Expand Down
14 changes: 14 additions & 0 deletions servers/native_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void NativeMenu::_bind_methods() {

ClassDB::bind_method(D_METHOD("find_item_index_with_text", "rid", "text"), &NativeMenu::find_item_index_with_text);
ClassDB::bind_method(D_METHOD("find_item_index_with_tag", "rid", "tag"), &NativeMenu::find_item_index_with_tag);
ClassDB::bind_method(D_METHOD("find_item_index_with_submenu", "rid", "submenu_rid"), &NativeMenu::find_item_index_with_submenu);

ClassDB::bind_method(D_METHOD("is_item_checked", "rid", "idx"), &NativeMenu::is_item_checked);
ClassDB::bind_method(D_METHOD("is_item_checkable", "rid", "idx"), &NativeMenu::is_item_checkable);
Expand Down Expand Up @@ -263,6 +264,19 @@ int NativeMenu::find_item_index_with_tag(const RID &p_rid, const Variant &p_tag)
return -1;
}

int NativeMenu::find_item_index_with_submenu(const RID &p_rid, const RID &p_submenu_rid) const {
if (!has_menu(p_rid) || !has_menu(p_submenu_rid)) {
return -1;
}
int count = get_item_count(p_rid);
for (int i = 0; i < count; i++) {
if (p_submenu_rid == get_item_submenu(p_rid, i)) {
return i;
}
}
return -1;
}

bool NativeMenu::is_item_checked(const RID &p_rid, int p_idx) const {
WARN_PRINT("Global menus are not supported on this platform.");
return false;
Expand Down
1 change: 1 addition & 0 deletions servers/native_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class NativeMenu : public Object {

virtual int find_item_index_with_text(const RID &p_rid, const String &p_text) const;
virtual int find_item_index_with_tag(const RID &p_rid, const Variant &p_tag) const;
virtual int find_item_index_with_submenu(const RID &p_rid, const RID &p_submenu_rid) const;

virtual bool is_item_checked(const RID &p_rid, int p_idx) const;
virtual bool is_item_checkable(const RID &p_rid, int p_idx) const;
Expand Down
Loading