diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index 8cb160ee9e..d5f1c7fbbd 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -45,6 +45,7 @@ If [code]true[/code], the item at [code]index[/code] is checked. [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. + [b]Note:[/b] An item cannot be both in a checked and indeterminate state, so if [code]checked[/code] is set to [code]true[/code], [member popup/item_{index}/indeterminate] will be set to [code]false[/code]. If [code]true[/code], the item at [code]index[/code] is disabled. @@ -58,6 +59,11 @@ The ID of the item at [code]index[/code]. [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. + + If [code]true[/code], the item at [code]index[/code] is in an indeterminate state. + [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. + [b]Note:[/b] An item cannot be both in a checked and indeterminate state, so if [code]indeterminate[/code] is set to [code]true[/code], [member popup/item_{index}/checked] will be set to [code]false[/code]. + If [code]true[/code], the item at [code]index[/code] is a separator. [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. diff --git a/doc/classes/NativeMenu.xml b/doc/classes/NativeMenu.xml index 078d4bad60..1a89ec1201 100644 --- a/doc/classes/NativeMenu.xml +++ b/doc/classes/NativeMenu.xml @@ -471,6 +471,16 @@ [b]Note:[/b] This method is implemented only on macOS. + + + + + + Returns [code]true[/code] if the item at index [param idx] is indeterminate. + See [method set_item_indeterminate] for more info on how to set an item. + [b]Note:[/b] This method is implemented only on macOS. + + @@ -618,6 +628,16 @@ [b]Note:[/b] This method is implemented only on macOS. + + + + + + + Sets the indeterminate status of the item at index [param idx]. + [b]Note:[/b] This method is implemented only on macOS. + + diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 9ecb2a02b0..9b5d41939e 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -380,6 +380,15 @@ See [method set_item_disabled] for more info on how to disable an item. + + + + + Returns [code]true[/code] if the item at the given [param index] is in an indeterminate state. This only applies to checkable items and is represented visually by a horizontal line instead of a checkmark or radio button. + See [method set_item_indeterminate] for more info on how to set an item as indeterminate. + [b]Note:[/b] Indeterminate items just display a horizontal line, but don't have any built-in behavior and must be set as indeterminate manually. + + @@ -536,6 +545,15 @@ Sets the horizontal offset of the item at the given [param index]. + + + + + + Sets the indeterminate status of the item at the given [param index]. This only applies to checkable items and is represented visually by a horizontal line instead of a checkmark or radio button. + [b]Note:[/b] Indeterminate items just display a horizontal line, but don't have any built-in behavior and must be set as indeterminate manually. + + @@ -687,6 +705,10 @@ The ID of the item at [code]index[/code]. [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. + + If [code]true[/code], the item at [code]index[/code] is in an indeterminate state. + [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. + If [code]true[/code], the item at [code]index[/code] is a separator. [b]Note:[/b] [code]index[/code] is a value in the [code]0 .. item_count - 1[/code] range. @@ -826,6 +848,12 @@ [Texture2D] icon for the checked checkbox items when they are disabled. + + [Texture2D] icon for the indeterminate checkbox items. + + + [Texture2D] icon for the indeterminate checkbox items when they are disabled. + [Texture2D] icon for the checked radio button items. diff --git a/editor/themes/theme_classic.cpp b/editor/themes/theme_classic.cpp index f8b7632b7b..faffdafeed 100644 --- a/editor/themes/theme_classic.cpp +++ b/editor/themes/theme_classic.cpp @@ -1121,10 +1121,12 @@ void ThemeClassic::populate_standard_styles(const Ref &p_theme, Edi p_theme->set_icon("checked", "PopupMenu", p_theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); p_theme->set_icon("unchecked", "PopupMenu", p_theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("indeterminate", "PopupMenu", p_theme->get_icon(SNAME("GuiIndeterminate"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_checked", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_unchecked", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons))); p_theme->set_icon("checked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("unchecked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("indeterminate_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiIndeterminateDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_checked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_unchecked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("submenu", "PopupMenu", p_theme->get_icon(SNAME("ArrowRight"), EditorStringName(EditorIcons))); diff --git a/editor/themes/theme_modern.cpp b/editor/themes/theme_modern.cpp index cc030f7724..0ab32aea76 100644 --- a/editor/themes/theme_modern.cpp +++ b/editor/themes/theme_modern.cpp @@ -1096,10 +1096,12 @@ void ThemeModern::populate_standard_styles(const Ref &p_theme, Edit p_theme->set_icon("checked", "PopupMenu", p_theme->get_icon(SNAME("GuiChecked"), EditorStringName(EditorIcons))); p_theme->set_icon("unchecked", "PopupMenu", p_theme->get_icon(SNAME("GuiUnchecked"), EditorStringName(EditorIcons))); + p_theme->set_icon("indeterminate", "PopupMenu", p_theme->get_icon(SNAME("GuiIndeterminate"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_checked", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioChecked"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_unchecked", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioUnchecked"), EditorStringName(EditorIcons))); p_theme->set_icon("checked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiCheckedDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("unchecked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiUncheckedDisabled"), EditorStringName(EditorIcons))); + p_theme->set_icon("indeterminate_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiIndeterminateDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_checked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioCheckedDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("radio_unchecked_disabled", "PopupMenu", p_theme->get_icon(SNAME("GuiRadioUncheckedDisabled"), EditorStringName(EditorIcons))); p_theme->set_icon("submenu", "PopupMenu", p_theme->get_icon(SNAME("ArrowRight"), EditorStringName(EditorIcons))); diff --git a/platform/macos/godot_menu_item.h b/platform/macos/godot_menu_item.h index ad2006297c..73b9c2496f 100644 --- a/platform/macos/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h @@ -58,6 +58,7 @@ enum GlobalMenuCheckType { GlobalMenuCheckType checkable_type; bool checked; bool enabled; + bool indeterminate; int max_states; int state; Ref img; diff --git a/platform/macos/godot_menu_item.mm b/platform/macos/godot_menu_item.mm index 1450d2fccd..21bcfbf789 100644 --- a/platform/macos/godot_menu_item.mm +++ b/platform/macos/godot_menu_item.mm @@ -40,6 +40,7 @@ self->checkable_type = GlobalMenuCheckType::CHECKABLE_TYPE_NONE; self->enabled = true; self->checked = false; + self->indeterminate = false; self->max_states = 0; self->state = 0; self->accel = Key::NONE; diff --git a/platform/macos/native_menu_macos.h b/platform/macos/native_menu_macos.h index bf5dde4c49..9d671dc9ce 100644 --- a/platform/macos/native_menu_macos.h +++ b/platform/macos/native_menu_macos.h @@ -119,6 +119,7 @@ public: virtual int find_item_index_with_tag(const RID &p_rid, const Variant &p_tag) const override; virtual bool is_item_checked(const RID &p_rid, int p_idx) const override; + virtual bool is_item_indeterminate(const RID &p_rid, int p_idx) const override; virtual bool is_item_checkable(const RID &p_rid, int p_idx) const override; virtual bool is_item_radio_checkable(const RID &p_rid, int p_idx) const override; virtual Callable get_item_callback(const RID &p_rid, int p_idx) const override; @@ -136,6 +137,7 @@ public: virtual int get_item_indentation_level(const RID &p_rid, int p_idx) const override; virtual void set_item_checked(const RID &p_rid, int p_idx, bool p_checked) override; + virtual void set_item_indeterminate(const RID &p_rid, int p_idx, bool p_cindeterminate) override; virtual void set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable) override; virtual void set_item_radio_checkable(const RID &p_rid, int p_idx, bool p_checkable) override; virtual void set_item_callback(const RID &p_rid, int p_idx, const Callable &p_callback) override; diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm index 74d94b9737..d3ff761481 100644 --- a/platform/macos/native_menu_macos.mm +++ b/platform/macos/native_menu_macos.mm @@ -680,6 +680,26 @@ bool NativeMenuMacOS::is_item_checked(const RID &p_rid, int p_idx) const { return false; } +bool NativeMenuMacOS::is_item_indeterminate(const RID &p_rid, int p_idx) const { + ERR_FAIL_COND_V(p_idx < 0, false); + + const MenuData *md = menus.get_or_null(p_rid); + ERR_FAIL_NULL_V(md, false); + + int item_start = _get_system_menu_start(md->menu); + int item_count = _get_system_menu_count(md->menu); + p_idx += item_start; + ERR_FAIL_COND_V(p_idx >= item_start + item_count, false); + const NSMenuItem *menu_item = [md->menu itemAtIndex:p_idx]; + if (menu_item) { + const GodotMenuItem *obj = [menu_item representedObject]; + if (obj) { + return obj->indeterminate; + } + } + return false; +} + bool NativeMenuMacOS::is_item_checkable(const RID &p_rid, int p_idx) const { ERR_FAIL_COND_V(p_idx < 0, false); @@ -996,6 +1016,7 @@ void NativeMenuMacOS::set_item_checked(const RID &p_rid, int p_idx, bool p_check GodotMenuItem *obj = [menu_item representedObject]; if (obj) { obj->checked = p_checked; + obj->indeterminate = false; if (p_checked) { [menu_item setState:NSControlStateValueOn]; } else { @@ -1005,6 +1026,30 @@ void NativeMenuMacOS::set_item_checked(const RID &p_rid, int p_idx, bool p_check } } +void NativeMenuMacOS::set_item_indeterminate(const RID &p_rid, int p_idx, bool p_indeterminate) { + ERR_FAIL_COND(p_idx < 0); + + MenuData *md = menus.get_or_null(p_rid); + ERR_FAIL_NULL(md); + int item_start = _get_system_menu_start(md->menu); + int item_count = _get_system_menu_count(md->menu); + p_idx += item_start; + ERR_FAIL_COND(p_idx >= item_start + item_count); + NSMenuItem *menu_item = [md->menu itemAtIndex:p_idx]; + if (menu_item) { + GodotMenuItem *obj = [menu_item representedObject]; + if (obj) { + obj->indeterminate = p_indeterminate; + obj->checked = false; + if (p_indeterminate) { + [menu_item setState:NSControlStateValueMixed]; + } else { + [menu_item setState:NSControlStateValueOff]; + } + } + } +} + void NativeMenuMacOS::set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable) { ERR_FAIL_COND(p_idx < 0); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index bd657b6fe6..02f316b801 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -221,6 +221,7 @@ void MenuButton::_bind_methods() { base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, Texture2D::get_class_static()), defaults.icon); base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As Checkbox,As Radio Button"), defaults.checkable_type); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "checked"), defaults.checked); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "indeterminate"), defaults.indeterminate); base_property_helper.register_property(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0,10,1,or_greater", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL), defaults.id); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "disabled"), defaults.disabled); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "separator"), defaults.separator); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 8bdeb4673e..7a5dda89e4 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -888,6 +888,7 @@ void PopupMenu::_draw_items() { // In Item::checkable_type enum order (less the non-checkable member), with disabled repeated at the end. Ref check[] = { theme_cache.checked, theme_cache.radio_checked, theme_cache.checked_disabled, theme_cache.radio_checked_disabled }; Ref uncheck[] = { theme_cache.unchecked, theme_cache.radio_unchecked, theme_cache.unchecked_disabled, theme_cache.radio_unchecked_disabled }; + Ref indeterminate[] = { theme_cache.indeterminate, theme_cache.indeterminate_disabled }; Ref submenu; if (rtl) { submenu = theme_cache.submenu_mirrored; @@ -986,7 +987,13 @@ void PopupMenu::_draw_items() { // Checkboxes if (items[i].checkable_type && !items[i].separator) { int disabled = int(items[i].disabled) * 2; - Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1 + disabled] : uncheck[items[i].checkable_type - 1 + disabled]).ptr(); + Texture2D *icon; + if (items[i].indeterminate) { + icon = indeterminate[disabled].ptr(); + } else { + icon = (items[i].checked ? check[items[i].checkable_type - 1 + disabled] : uncheck[items[i].checkable_type - 1 + disabled]).ptr(); + } + if (rtl) { icon->draw(ci, Size2(control->get_size().width - item_ofs.x - icon->get_width(), item_ofs.y) + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color); } else { @@ -2272,6 +2279,7 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) { items.write[p_idx].checked = p_checked; items.write[p_idx].accessibility_item_dirty = true; + items.write[p_idx].indeterminate = false; if (global_menu.is_valid()) { NativeMenu::get_singleton()->set_item_checked(global_menu, p_idx, p_checked); @@ -2283,6 +2291,30 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) { _menu_changed(); } +void PopupMenu::set_item_indeterminate(int p_idx, bool p_indeterminate) { + if (p_idx < 0) { + p_idx += get_item_count(); + } + ERR_FAIL_INDEX(p_idx, items.size()); + + if (items[p_idx].indeterminate == p_indeterminate) { + return; + } + + items.write[p_idx].indeterminate = p_indeterminate; + items.write[p_idx].accessibility_item_dirty = true; + items.write[p_idx].checked = false; + + if (global_menu.is_valid()) { + NativeMenu::get_singleton()->set_item_indeterminate(global_menu, p_idx, p_indeterminate); + } + + queue_accessibility_update(); + control->queue_redraw(); + child_controls_changed(); + _menu_changed(); +} + void PopupMenu::set_item_id(int p_idx, int p_id) { if (p_idx < 0) { p_idx += get_item_count(); @@ -2542,6 +2574,11 @@ bool PopupMenu::is_item_checked(int p_idx) const { return items[p_idx].checked; } +bool PopupMenu::is_item_indeterminate(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), false); + return items[p_idx].indeterminate; +} + int PopupMenu::get_item_id(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, items.size(), 0); return items[p_idx].id; @@ -3420,6 +3457,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_icon_max_width", "index", "width"), &PopupMenu::set_item_icon_max_width); ClassDB::bind_method(D_METHOD("set_item_icon_modulate", "index", "modulate"), &PopupMenu::set_item_icon_modulate); ClassDB::bind_method(D_METHOD("set_item_checked", "index", "checked"), &PopupMenu::set_item_checked); + ClassDB::bind_method(D_METHOD("set_item_indeterminate", "index", "indeterminate"), &PopupMenu::set_item_indeterminate); ClassDB::bind_method(D_METHOD("set_item_id", "index", "id"), &PopupMenu::set_item_id); ClassDB::bind_method(D_METHOD("set_item_accelerator", "index", "accel"), &PopupMenu::set_item_accelerator); ClassDB::bind_method(D_METHOD("set_item_metadata", "index", "metadata"), &PopupMenu::set_item_metadata); @@ -3448,6 +3486,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_icon_max_width", "index"), &PopupMenu::get_item_icon_max_width); ClassDB::bind_method(D_METHOD("get_item_icon_modulate", "index"), &PopupMenu::get_item_icon_modulate); ClassDB::bind_method(D_METHOD("is_item_checked", "index"), &PopupMenu::is_item_checked); + ClassDB::bind_method(D_METHOD("is_item_indeterminate", "index"), &PopupMenu::is_item_indeterminate); ClassDB::bind_method(D_METHOD("get_item_id", "index"), &PopupMenu::get_item_id); ClassDB::bind_method(D_METHOD("get_item_index", "id"), &PopupMenu::get_item_index); ClassDB::bind_method(D_METHOD("get_item_accelerator", "index"), &PopupMenu::get_item_accelerator); @@ -3553,6 +3592,8 @@ void PopupMenu::_bind_methods() { BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, checked); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, checked_disabled); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, indeterminate); + BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, indeterminate_disabled); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, unchecked); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, unchecked_disabled); BIND_THEME_ITEM(Theme::DATA_TYPE_ICON, PopupMenu, radio_checked); @@ -3588,6 +3629,7 @@ void PopupMenu::_bind_methods() { base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, Texture2D::get_class_static()), defaults.icon, &PopupMenu::set_item_icon, &PopupMenu::get_item_icon); base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As checkbox,As radio button"), defaults.checkable_type, &PopupMenu::_set_item_checkable_type, &PopupMenu::_get_item_checkable_type); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "checked"), defaults.checked, &PopupMenu::set_item_checked, &PopupMenu::is_item_checked); + base_property_helper.register_property(PropertyInfo(Variant::BOOL, "indeterminate"), defaults.indeterminate, &PopupMenu::set_item_indeterminate, &PopupMenu::is_item_indeterminate); base_property_helper.register_property(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0,10,1,or_greater", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL), defaults.id, &PopupMenu::set_item_id, &PopupMenu::get_item_id); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "disabled"), defaults.disabled, &PopupMenu::set_item_disabled, &PopupMenu::is_item_disabled); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "separator"), defaults.separator, &PopupMenu::set_item_as_separator, &PopupMenu::is_item_separator); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index ee9f490501..2e0774a951 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -77,6 +77,7 @@ class PopupMenu : public Popup { int state = 0; bool separator = false; bool disabled = false; + bool indeterminate = false; bool dirty = true; int id = 0; Variant metadata; @@ -218,6 +219,8 @@ class PopupMenu : public Popup { Ref checked_disabled; Ref unchecked; Ref unchecked_disabled; + Ref indeterminate; + Ref indeterminate_disabled; Ref radio_checked; Ref radio_checked_disabled; Ref radio_unchecked; @@ -338,6 +341,7 @@ public: void set_item_icon_max_width(int p_idx, int p_width); void set_item_icon_modulate(int p_idx, const Color &p_modulate); void set_item_checked(int p_idx, bool p_checked); + void set_item_indeterminate(int p_idx, bool p_indeterminate); void set_item_id(int p_idx, int p_id); void set_item_accelerator(int p_idx, Key p_accel); void set_item_metadata(int p_idx, const Variant &p_meta); @@ -368,6 +372,7 @@ public: int get_item_icon_max_width(int p_idx) const; Color get_item_icon_modulate(int p_idx) const; bool is_item_checked(int p_idx) const; + bool is_item_indeterminate(int p_idx) const; int get_item_id(int p_idx) const; int get_item_index(int p_id) const; Key get_item_accelerator(int p_idx) const; diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index 3de32c443a..76615eea61 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -766,6 +766,8 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const theme->set_icon("checked_disabled", "PopupMenu", icons["checked_disabled"]); theme->set_icon("unchecked", "PopupMenu", icons["unchecked"]); theme->set_icon("unchecked_disabled", "PopupMenu", icons["unchecked_disabled"]); + theme->set_icon("indeterminate", "PopupMenu", icons["indeterminate"]); + theme->set_icon("indeterminate_disabled", "PopupMenu", icons["indeterminate_disabled"]); theme->set_icon("radio_checked", "PopupMenu", icons["radio_checked"]); theme->set_icon("radio_checked_disabled", "PopupMenu", icons["radio_checked_disabled"]); theme->set_icon("radio_unchecked", "PopupMenu", icons["radio_unchecked"]); diff --git a/servers/display/native_menu.cpp b/servers/display/native_menu.cpp index e906288d9c..b5eb96abcd 100644 --- a/servers/display/native_menu.cpp +++ b/servers/display/native_menu.cpp @@ -77,6 +77,7 @@ void NativeMenu::_bind_methods() { 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_indeterminate", "rid", "idx"), &NativeMenu::is_item_indeterminate); ClassDB::bind_method(D_METHOD("is_item_checkable", "rid", "idx"), &NativeMenu::is_item_checkable); ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "rid", "idx"), &NativeMenu::is_item_radio_checkable); ClassDB::bind_method(D_METHOD("get_item_callback", "rid", "idx"), &NativeMenu::get_item_callback); @@ -94,6 +95,7 @@ void NativeMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_indentation_level", "rid", "idx"), &NativeMenu::get_item_indentation_level); ClassDB::bind_method(D_METHOD("set_item_checked", "rid", "idx", "checked"), &NativeMenu::set_item_checked); + ClassDB::bind_method(D_METHOD("set_item_indeterminate", "rid", "idx", "indeterminate"), &NativeMenu::set_item_indeterminate); ClassDB::bind_method(D_METHOD("set_item_checkable", "rid", "idx", "checkable"), &NativeMenu::set_item_checkable); ClassDB::bind_method(D_METHOD("set_item_radio_checkable", "rid", "idx", "checkable"), &NativeMenu::set_item_radio_checkable); ClassDB::bind_method(D_METHOD("set_item_callback", "rid", "idx", "callback"), &NativeMenu::set_item_callback); @@ -303,6 +305,11 @@ bool NativeMenu::is_item_checked(const RID &p_rid, int p_idx) const { return false; } +bool NativeMenu::is_item_indeterminate(const RID &p_rid, int p_idx) const { + WARN_PRINT("Global menus are not supported on this platform."); + return false; +} + bool NativeMenu::is_item_checkable(const RID &p_rid, int p_idx) const { WARN_PRINT("Global menus are not supported on this platform."); return false; @@ -382,6 +389,10 @@ void NativeMenu::set_item_checked(const RID &p_rid, int p_idx, bool p_checked) { WARN_PRINT("Global menus are not supported on this platform."); } +void NativeMenu::set_item_indeterminate(const RID &p_rid, int p_idx, bool p_indeterminate) { + WARN_PRINT("Global menus are not supported on this platform."); +} + void NativeMenu::set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable) { WARN_PRINT("Global menus are not supported on this platform."); } diff --git a/servers/display/native_menu.h b/servers/display/native_menu.h index 3adf829941..b6bb19a153 100644 --- a/servers/display/native_menu.h +++ b/servers/display/native_menu.h @@ -109,6 +109,7 @@ public: 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_indeterminate(const RID &p_rid, int p_idx) const; virtual bool is_item_checkable(const RID &p_rid, int p_idx) const; virtual bool is_item_radio_checkable(const RID &p_rid, int p_idx) const; virtual Callable get_item_callback(const RID &p_rid, int p_idx) const; @@ -126,6 +127,7 @@ public: virtual int get_item_indentation_level(const RID &p_rid, int p_idx) const; virtual void set_item_checked(const RID &p_rid, int p_idx, bool p_checked); + virtual void set_item_indeterminate(const RID &p_rid, int p_idx, bool p_indeterminate); virtual void set_item_checkable(const RID &p_rid, int p_idx, bool p_checkable); virtual void set_item_radio_checkable(const RID &p_rid, int p_idx, bool p_checkable); virtual void set_item_callback(const RID &p_rid, int p_idx, const Callable &p_callback);