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

Added allow_echo parameter to accept echo events for popup menu item shortcut #64317

Closed
wants to merge 1 commit into from
Closed
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
3 changes: 3 additions & 0 deletions doc/classes/PopupMenu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
<param index="1" name="shortcut" type="Shortcut" />
<param index="2" name="id" type="int" default="-1" />
<param index="3" name="global" type="bool" default="false" />
<param index="4" name="p_allow_echo" type="bool" default="false" />
<description>
Adds a new item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
Expand Down Expand Up @@ -161,6 +162,7 @@
<param index="0" name="shortcut" type="Shortcut" />
<param index="1" name="id" type="int" default="-1" />
<param index="2" name="global" type="bool" default="false" />
<param index="3" name="p_allow_echo" type="bool" default="false" />
<description>
Adds a [Shortcut].
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
Expand Down Expand Up @@ -442,6 +444,7 @@
<param index="0" name="index" type="int" />
<param index="1" name="shortcut" type="Shortcut" />
<param index="2" name="global" type="bool" default="false" />
<param index="3" name="allow_echo" type="bool" default="false" />
<description>
Sets a [Shortcut] for the item at the given [code]index[/code].
</description>
Expand Down
4 changes: 2 additions & 2 deletions scene/gui/menu_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ void MenuButton::shortcut_input(const Ref<InputEvent> &p_event) {
return;
}

if (p_event->is_pressed() && !p_event->is_echo() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event) || Object::cast_to<InputEventShortcut>(*p_event))) {
if (p_event->is_pressed() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event) || Object::cast_to<InputEventShortcut>(*p_event))) {
if (!get_parent() || !is_visible_in_tree() || is_disabled()) {
return;
}

if (popup->activate_item_by_event(p_event, false)) {
if (popup->activate_item_by_event(p_event, false, p_event->is_echo())) {
accept_event();
}
}
Expand Down
46 changes: 26 additions & 20 deletions scene/gui/popup_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,27 +955,28 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
child_controls_changed();
}

#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global) \
#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo) \
ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid Shortcut."); \
_ref_shortcut(p_shortcut); \
item.text = p_shortcut->get_name(); \
item.xl_text = atr(item.text); \
item.id = p_id == -1 ? items.size() : p_id; \
item.shortcut = p_shortcut; \
item.shortcut_is_global = p_global;
item.shortcut_is_global = p_global; \
item.shortcut_allow_echo = p_allow_echo;

void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global, bool p_allow_echo) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo);
items.push_back(item);
_shape_item(items.size() - 1);
control->update();
child_controls_changed();
}

void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global, bool p_allow_echo) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo);
item.icon = p_icon;
items.push_back(item);
_shape_item(items.size() - 1);
Expand All @@ -985,7 +986,7 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortc

void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
items.push_back(item);
_shape_item(items.size() - 1);
Expand All @@ -995,7 +996,7 @@ void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bo

void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
item.icon = p_icon;
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
items.push_back(item);
Expand All @@ -1006,7 +1007,7 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<

void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
items.push_back(item);
_shape_item(items.size() - 1);
Expand All @@ -1016,7 +1017,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_

void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
item.icon = p_icon;
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
items.push_back(item);
Expand Down Expand Up @@ -1298,7 +1299,7 @@ void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
control->update();
}

void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global) {
void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global, bool p_allow_echo) {
if (p_idx < 0) {
p_idx += get_item_count();
}
Expand All @@ -1308,6 +1309,7 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bo
}
items.write[p_idx].shortcut = p_shortcut;
items.write[p_idx].shortcut_is_global = p_global;
items.write[p_idx].shortcut_allow_echo = p_allow_echo;
items.write[p_idx].dirty = true;

if (items[p_idx].shortcut.is_valid()) {
Expand Down Expand Up @@ -1419,7 +1421,7 @@ void PopupMenu::scroll_to_item(int p_item) {
}
}

bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only) {
bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only, bool p_is_echo) {
Key code = Key::NONE;
Ref<InputEventKey> k = p_event;

Expand Down Expand Up @@ -1448,13 +1450,17 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
}

if (items[i].shortcut.is_valid() && items[i].shortcut->matches_event(p_event) && (items[i].shortcut_is_global || !p_for_global_only)) {
activate_item(i);
return true;
if (!p_is_echo || items[i].shortcut_allow_echo) {
activate_item(i);
return true;
}
}

if (code != Key::NONE && items[i].accel == code) {
activate_item(i);
return true;
if (!p_is_echo) {
activate_item(i);
return true;
}
}

if (!items[i].submenu.is_empty()) {
Expand All @@ -1468,7 +1474,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
continue;
}

if (pm->activate_item_by_event(p_event, p_for_global_only)) {
if (pm->activate_item_by_event(p_event, p_for_global_only, p_is_echo)) {
return true;
}
}
Expand Down Expand Up @@ -1815,8 +1821,8 @@ void PopupMenu::_bind_methods() {

ClassDB::bind_method(D_METHOD("add_multistate_item", "label", "max_states", "default_state", "id", "accel"), &PopupMenu::add_multistate_item, DEFVAL(0), DEFVAL(-1), DEFVAL(0));

ClassDB::bind_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::add_shortcut, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_shortcut", "shortcut", "id", "global", "p_allow_echo"), &PopupMenu::add_shortcut, DEFVAL(-1), DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global", "p_allow_echo"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_check_shortcut, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_icon_check_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_check_shortcut, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_radio_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_radio_check_shortcut, DEFVAL(-1), DEFVAL(false));
Expand All @@ -1838,7 +1844,7 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_item_as_checkable", "index", "enable"), &PopupMenu::set_item_as_checkable);
ClassDB::bind_method(D_METHOD("set_item_as_radio_checkable", "index", "enable"), &PopupMenu::set_item_as_radio_checkable);
ClassDB::bind_method(D_METHOD("set_item_tooltip", "index", "tooltip"), &PopupMenu::set_item_tooltip);
ClassDB::bind_method(D_METHOD("set_item_shortcut", "index", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_item_shortcut", "index", "shortcut", "global", "allow_echo"), &PopupMenu::set_item_shortcut, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_item_horizontal_offset", "index", "offset"), &PopupMenu::set_item_horizontal_offset);
ClassDB::bind_method(D_METHOD("set_item_multistate", "index", "state"), &PopupMenu::set_item_multistate);
ClassDB::bind_method(D_METHOD("set_item_shortcut_disabled", "index", "disabled"), &PopupMenu::set_item_shortcut_disabled);
Expand Down
9 changes: 5 additions & 4 deletions scene/gui/popup_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class PopupMenu : public Popup {
Ref<Shortcut> shortcut;
bool shortcut_is_global = false;
bool shortcut_is_disabled = false;
bool shortcut_allow_echo = false;

// Returns (0,0) if icon is null.
Size2 get_icon_size() const {
Expand Down Expand Up @@ -158,8 +159,8 @@ class PopupMenu : public Popup {

void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, Key p_accel = Key::NONE);

void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false, bool p_allow_echo = false);
void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false, bool p_allow_echo = false);
void add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
Expand All @@ -182,7 +183,7 @@ class PopupMenu : public Popup {
void set_item_as_checkable(int p_idx, bool p_checkable);
void set_item_as_radio_checkable(int p_idx, bool p_radio_checkable);
void set_item_tooltip(int p_idx, const String &p_tooltip);
void set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global = false);
void set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global = false, bool p_allow_echo = false);
void set_item_horizontal_offset(int p_idx, int p_offset);
void set_item_multistate(int p_idx, int p_state);
void toggle_item_multistate(int p_idx);
Expand Down Expand Up @@ -219,7 +220,7 @@ class PopupMenu : public Popup {

void scroll_to_item(int p_item);

bool activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only = false);
bool activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only = false, bool p_is_echo = false);
void activate_item(int p_item);

void remove_item(int p_idx);
Expand Down