From c9bdccf7f276744630ac0dff36a284f457871f9f Mon Sep 17 00:00:00 2001 From: mrcdk Date: Sat, 20 Jan 2024 07:10:28 +0100 Subject: [PATCH] Expose PopupMenu get_item_multistate(), get_item_multistate_max() and set_item_multistate_max() --- doc/classes/PopupMenu.xml | 41 ++++++++++++++++++++++++++++++++++++++- scene/gui/popup_menu.cpp | 24 +++++++++++++++++++++++ scene/gui/popup_menu.h | 1 + 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 40d5a9f4a245..8f6507eabf96 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -133,8 +133,25 @@ Adds a new multistate item with text [param label]. - Contrarily to normal binary items, multistate items can have more than two states, as defined by [param max_states]. Each press or activate of the item will increase the state by one. The default value is defined by [param default_state]. + Contrarily to normal binary items, multistate items can have more than two states, as defined by [param max_states]. The default value is defined by [param default_state]. An [param id] can optionally be provided, as well as an accelerator ([param accel]). If no [param id] is provided, one will be created from the index. If no [param accel] is provided, then the default value of 0 (corresponding to [constant @GlobalScope.KEY_NONE]) will be assigned to the item (which means it won't have any accelerator). See [method get_item_accelerator] for more info on accelerators. + [b]Note:[/b] Multistate items don't update their state automatically and must be done manually. See [method toggle_item_multistate], [method set_item_multistate] and [method get_item_multistate] for more info on how to control it. + Example usage: + [codeblock] + func _ready(): + add_multistate_item("Item", 3, 0) + + index_pressed.connect(func(index: int): + toggle_item_multistate(index) + match get_item_multistate(index): + 0: + print("First state") + 1: + print("Second state") + 2: + print("Third state") + ) + [/codeblock] @@ -266,6 +283,20 @@ Returns the metadata of the specified item, which might be of any type. You can set it with [method set_item_metadata], which provides a simple way of assigning context data to items. + + + + + Returns the state of the item at the given [param index]. + + + + + + + Returns the max states of the item at the given [param index]. + + @@ -489,6 +520,14 @@ Sets the state of a multistate item. See [method add_multistate_item] for details. + + + + + + Sets the max states of a multistate item. See [method add_multistate_item] for details. + + diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 2414278e528c..dc586e86c931 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -2086,6 +2086,26 @@ void PopupMenu::set_item_indent(int p_idx, int p_indent) { _menu_changed(); } +void PopupMenu::set_item_max_states(int p_idx, int p_max_states) { + if (p_idx < 0) { + p_idx += get_item_count(); + } + ERR_FAIL_INDEX(p_idx, items.size()); + + if (items[p_idx].max_states == p_max_states) { + return; + } + + items.write[p_idx].max_states = p_max_states; + + if (!global_menu_name.is_empty()) { + DisplayServer::get_singleton()->global_menu_set_item_max_states(global_menu_name, p_idx, p_max_states); + } + + control->queue_redraw(); + _menu_changed(); +} + void PopupMenu::set_item_multistate(int p_idx, int p_state) { if (p_idx < 0) { p_idx += get_item_count(); @@ -2724,6 +2744,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_shortcut", "index", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_item_indent", "index", "indent"), &PopupMenu::set_item_indent); ClassDB::bind_method(D_METHOD("set_item_multistate", "index", "state"), &PopupMenu::set_item_multistate); + ClassDB::bind_method(D_METHOD("set_item_multistate_max", "index", "max_states"), &PopupMenu::set_item_max_states); ClassDB::bind_method(D_METHOD("set_item_shortcut_disabled", "index", "disabled"), &PopupMenu::set_item_shortcut_disabled); ClassDB::bind_method(D_METHOD("toggle_item_checked", "index"), &PopupMenu::toggle_item_checked); @@ -2750,6 +2771,9 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_shortcut", "index"), &PopupMenu::get_item_shortcut); ClassDB::bind_method(D_METHOD("get_item_indent", "index"), &PopupMenu::get_item_indent); + ClassDB::bind_method(D_METHOD("get_item_multistate_max", "index"), &PopupMenu::get_item_max_states); + ClassDB::bind_method(D_METHOD("get_item_multistate", "index"), &PopupMenu::get_item_state); + ClassDB::bind_method(D_METHOD("set_focused_item", "index"), &PopupMenu::set_focused_item); ClassDB::bind_method(D_METHOD("get_focused_item"), &PopupMenu::get_focused_item); ClassDB::bind_method(D_METHOD("set_item_count", "count"), &PopupMenu::set_item_count); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 9783f9d57b24..35ababd913f6 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -264,6 +264,7 @@ class PopupMenu : public Popup { void set_item_tooltip(int p_idx, const String &p_tooltip); void set_item_shortcut(int p_idx, const Ref &p_shortcut, bool p_global = false); void set_item_indent(int p_idx, int p_indent); + void set_item_max_states(int p_idx, int p_max_states); void set_item_multistate(int p_idx, int p_state); void toggle_item_multistate(int p_idx); void set_item_shortcut_disabled(int p_idx, bool p_disabled);