Skip to content

Commit

Permalink
Merge pull request #54533 from rafallus/menubutton_items
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored Nov 3, 2021
2 parents a2803f3 + 4554892 commit f00ba79
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 87 deletions.
3 changes: 3 additions & 0 deletions doc/classes/MenuButton.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" override="true" enum="BaseButton.ActionMode" default="0" />
<member name="flat" type="bool" setter="set_flat" getter="is_flat" override="true" default="true" />
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="0" />
<member name="items_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
The number of items currently in the list.
</member>
<member name="switch_on_hover" type="bool" setter="set_switch_on_hover" getter="is_switch_on_hover" default="false">
If [code]true[/code], when the cursor hovers above another [MenuButton] within the same parent which also has [code]switch_on_hover[/code] enabled, it will close the current [MenuButton] and open the other one.
</member>
Expand Down
9 changes: 3 additions & 6 deletions doc/classes/PopupMenu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,6 @@
Returns the accelerator of the item at index [code]idx[/code]. Accelerators are special combinations of keys that activate the item, no matter which control is focused.
</description>
</method>
<method name="get_item_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of items in the [PopupMenu].
</description>
</method>
<method name="get_item_icon" qualifiers="const">
<return type="Texture2D" />
<argument index="0" name="idx" type="int" />
Expand Down Expand Up @@ -511,6 +505,9 @@
<member name="hide_on_state_item_selection" type="bool" setter="set_hide_on_state_item_selection" getter="is_hide_on_state_item_selection" default="false">
If [code]true[/code], hides the [PopupMenu] when a state item is selected.
</member>
<member name="items_count" type="int" setter="set_item_count" getter="get_item_count" default="0">
The number of items currently in the list.
</member>
<member name="submenu_popup_delay" type="float" setter="set_submenu_popup_delay" getter="get_submenu_popup_delay" default="0.3">
Sets the delay time in seconds for the submenu item to popup on mouse hovering. If the popup menu is added as a child of another (acting as a submenu), it will inherit the delay time of the parent menu item.
</member>
Expand Down
74 changes: 63 additions & 11 deletions scene/gui/menu_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,6 @@ PopupMenu *MenuButton::get_popup() const {
return popup;
}

void MenuButton::_set_items(const Array &p_items) {
popup->set("items", p_items);
}

Array MenuButton::_get_items() const {
return popup->get("items");
}

void MenuButton::set_switch_on_hover(bool p_enabled) {
switch_on_hover = p_enabled;
}
Expand All @@ -126,6 +118,16 @@ bool MenuButton::is_switch_on_hover() {
return switch_on_hover;
}

void MenuButton::set_item_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
popup->set_item_count(p_count);
notify_property_list_changed();
}

int MenuButton::get_item_count() const {
return popup->get_item_count();
}

void MenuButton::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
Expand All @@ -146,16 +148,66 @@ void MenuButton::_notification(int p_what) {
}
}

bool MenuButton::_set(const StringName &p_name, const Variant &p_value) {
Vector<String> components = String(p_name).split("/", true, 2);
if (components.size() >= 2 && components[0] == "popup") {
bool valid;
popup->set(String(p_name).trim_prefix("popup/"), p_value, &valid);
return valid;
}
return false;
}

bool MenuButton::_get(const StringName &p_name, Variant &r_ret) const {
Vector<String> components = String(p_name).split("/", true, 2);
if (components.size() >= 2 && components[0] == "popup") {
bool valid;
r_ret = popup->get(String(p_name).trim_prefix("popup/"), &valid);
return valid;
}
return false;
}

void MenuButton::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < popup->get_item_count(); i++) {
p_list->push_back(PropertyInfo(Variant::STRING, vformat("popup/item_%d/text", i)));

PropertyInfo pi = PropertyInfo(Variant::OBJECT, vformat("popup/item_%d/icon", i), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D");
pi.usage &= ~(popup->get_item_icon(i).is_null() ? PROPERTY_USAGE_STORAGE : 0);
p_list->push_back(pi);

pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/checkable", i), PROPERTY_HINT_ENUM, "No,As checkbox,As radio button");
pi.usage &= ~(!popup->is_item_checkable(i) ? PROPERTY_USAGE_STORAGE : 0);
p_list->push_back(pi);

pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/checked", i));
pi.usage &= ~(!popup->is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0);
p_list->push_back(pi);

pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "1,10,1,or_greater");
p_list->push_back(pi);

pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i));
pi.usage &= ~(!popup->is_item_disabled(i) ? PROPERTY_USAGE_STORAGE : 0);
p_list->push_back(pi);

pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/separator", i));
pi.usage &= ~(!popup->is_item_separator(i) ? PROPERTY_USAGE_STORAGE : 0);
p_list->push_back(pi);
}
}

void MenuButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_popup"), &MenuButton::get_popup);
ClassDB::bind_method(D_METHOD("_set_items"), &MenuButton::_set_items);
ClassDB::bind_method(D_METHOD("_get_items"), &MenuButton::_get_items);
ClassDB::bind_method(D_METHOD("set_switch_on_hover", "enable"), &MenuButton::set_switch_on_hover);
ClassDB::bind_method(D_METHOD("is_switch_on_hover"), &MenuButton::is_switch_on_hover);
ClassDB::bind_method(D_METHOD("set_disable_shortcuts", "disabled"), &MenuButton::set_disable_shortcuts);

ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items");
ClassDB::bind_method(D_METHOD("set_item_count"), &MenuButton::set_item_count);
ClassDB::bind_method(D_METHOD("get_item_count"), &MenuButton::get_item_count);

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "switch_on_hover"), "set_switch_on_hover", "is_switch_on_hover");
ADD_ARRAY_COUNT("Items", "items_count", "set_item_count", "get_item_count", "popup/item_");

ADD_SIGNAL(MethodInfo("about_to_popup"));
}
Expand Down
9 changes: 6 additions & 3 deletions scene/gui/menu_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ class MenuButton : public Button {

Vector2i mouse_pos_adjusted;

Array _get_items() const;
void _set_items(const Array &p_items);

virtual void gui_input(const Ref<InputEvent> &p_event) override;

void _popup_visibility_changed(bool p_visible);

protected:
void _notification(int p_what);
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;

Expand All @@ -64,6 +64,9 @@ class MenuButton : public Button {
bool is_switch_on_hover();
void set_disable_shortcuts(bool p_disabled);

void set_item_count(int p_count);
int get_item_count() const;

MenuButton();
~MenuButton();
};
Expand Down
Loading

0 comments on commit f00ba79

Please sign in to comment.