Skip to content

Commit 4b11bc2

Browse files
committed
Merge pull request #36493 from KoBeWi/echo_menus
Add option to allow echo events in menu shortcuts
2 parents a278c1b + 3dd881b commit 4b11bc2

8 files changed

Lines changed: 86 additions & 19 deletions

File tree

doc/classes/PopupMenu.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@
9696
<param index="1" name="shortcut" type="Shortcut" />
9797
<param index="2" name="id" type="int" default="-1" />
9898
<param index="3" name="global" type="bool" default="false" />
99+
<param index="4" name="allow_echo" type="bool" default="false" />
99100
<description>
100101
Adds a new item and assigns the specified [Shortcut] and icon [param texture] to it. Sets the label of the checkbox to the [Shortcut]'s name.
101102
An [param id] can optionally be provided. If no [param id] is provided, one will be created from the index.
103+
If [param allow_echo] is [code]true[/code], the shortcut can be activated with echo events.
102104
</description>
103105
</method>
104106
<method name="add_item">
@@ -161,9 +163,11 @@
161163
<param index="0" name="shortcut" type="Shortcut" />
162164
<param index="1" name="id" type="int" default="-1" />
163165
<param index="2" name="global" type="bool" default="false" />
166+
<param index="3" name="allow_echo" type="bool" default="false" />
164167
<description>
165168
Adds a [Shortcut].
166169
An [param id] can optionally be provided. If no [param id] is provided, one will be created from the index.
170+
If [param allow_echo] is [code]true[/code], the shortcut can be activated with echo events.
167171
</description>
168172
</method>
169173
<method name="add_submenu_item">

editor/editor_node.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7472,8 +7472,8 @@ EditorNode::EditorNode() {
74727472
export_as_menu->connect("index_pressed", callable_mp(this, &EditorNode::_export_as_menu_option));
74737473

74747474
file_menu->add_separator();
7475-
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO, true);
7476-
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO, true);
7475+
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO, true, true);
7476+
file_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO, true, true);
74777477

74787478
file_menu->add_separator();
74797479
file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reload_saved_scene", TTR("Reload Saved Scene")), EDIT_RELOAD_SAVED_SCENE);

misc/extension_api_validation/4.0-stable.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,3 +443,11 @@ Validate extension JSON: API was removed: classes/SystemFont/properties/fallback
443443

444444
The property was moved to their common base class Font.
445445
The setters and getters were already in Font, so this shouldn't affect compatibility.
446+
447+
448+
GH-36493
449+
--------
450+
Validate extension JSON: Error: Field 'classes/PopupMenu/methods/add_icon_shortcut/arguments': size changed value in new API, from 4 to 5.
451+
Validate extension JSON: Error: Field 'classes/PopupMenu/methods/add_shortcut/arguments': size changed value in new API, from 3 to 4.
452+
453+
Added optional argument. Compatibility methods registered.

scene/gui/menu_bar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void MenuBar::shortcut_input(const Ref<InputEvent> &p_event) {
152152
return;
153153
}
154154

155-
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))) {
155+
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))) {
156156
if (!get_parent() || !is_visible_in_tree()) {
157157
return;
158158
}

scene/gui/menu_button.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void MenuButton::shortcut_input(const Ref<InputEvent> &p_event) {
4040
return;
4141
}
4242

43-
if (p_event->is_pressed() && !p_event->is_echo() && !is_disabled() && is_visible_in_tree() && popup->activate_item_by_event(p_event, false)) {
43+
if (p_event->is_pressed() && !is_disabled() && is_visible_in_tree() && popup->activate_item_by_event(p_event, false)) {
4444
accept_event();
4545
return;
4646
}

scene/gui/popup_menu.compat.inc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**************************************************************************/
2+
/* popup_menu.compat.inc */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#ifndef DISABLE_DEPRECATED
32+
33+
void PopupMenu::_add_shortcut_bind_compat_36493(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
34+
return add_shortcut(p_shortcut, p_id, p_global, false);
35+
}
36+
37+
void PopupMenu::_add_icon_shortcut_bind_compat_36493(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
38+
return add_icon_shortcut(p_icon, p_shortcut, p_id, p_global, false);
39+
}
40+
41+
void PopupMenu::_bind_compatibility_methods() {
42+
ClassDB::bind_compatibility_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::_add_shortcut_bind_compat_36493, DEFVAL(-1), DEFVAL(false));
43+
ClassDB::bind_compatibility_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::_add_icon_shortcut_bind_compat_36493, DEFVAL(-1), DEFVAL(false));
44+
}
45+
46+
#endif

scene/gui/popup_menu.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
/**************************************************************************/
3030

3131
#include "popup_menu.h"
32+
#include "popup_menu.compat.inc"
3233

3334
#include "core/config/project_settings.h"
3435
#include "core/input/input.h"
@@ -1164,18 +1165,19 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
11641165
_menu_changed();
11651166
}
11661167

1167-
#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global) \
1168+
#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo) \
11681169
ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid Shortcut."); \
11691170
_ref_shortcut(p_shortcut); \
11701171
item.text = p_shortcut->get_name(); \
11711172
item.xl_text = atr(item.text); \
11721173
item.id = p_id == -1 ? items.size() : p_id; \
11731174
item.shortcut = p_shortcut; \
1174-
item.shortcut_is_global = p_global;
1175+
item.shortcut_is_global = p_global; \
1176+
item.allow_echo = p_allow_echo;
11751177

1176-
void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
1178+
void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global, bool p_allow_echo) {
11771179
Item item;
1178-
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
1180+
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo);
11791181
items.push_back(item);
11801182

11811183
_shape_item(items.size() - 1);
@@ -1185,9 +1187,9 @@ void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_g
11851187
_menu_changed();
11861188
}
11871189

1188-
void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
1190+
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) {
11891191
Item item;
1190-
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
1192+
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, p_allow_echo);
11911193
item.icon = p_icon;
11921194
items.push_back(item);
11931195

@@ -1200,7 +1202,7 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortc
12001202

12011203
void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
12021204
Item item;
1203-
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
1205+
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false); // Echo for check shortcuts doesn't make sense.
12041206
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
12051207
items.push_back(item);
12061208

@@ -1213,7 +1215,7 @@ void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bo
12131215

12141216
void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
12151217
Item item;
1216-
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
1218+
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
12171219
item.icon = p_icon;
12181220
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
12191221
items.push_back(item);
@@ -1227,7 +1229,7 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<
12271229

12281230
void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
12291231
Item item;
1230-
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
1232+
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
12311233
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
12321234
items.push_back(item);
12331235

@@ -1240,7 +1242,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_
12401242

12411243
void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
12421244
Item item;
1243-
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
1245+
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global, false);
12441246
item.icon = p_icon;
12451247
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
12461248
items.push_back(item);
@@ -1838,7 +1840,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
18381840
}
18391841

18401842
for (int i = 0; i < items.size(); i++) {
1841-
if (is_item_disabled(i) || items[i].shortcut_is_disabled) {
1843+
if (is_item_disabled(i) || items[i].shortcut_is_disabled || (!items[i].allow_echo && p_event->is_echo())) {
18421844
continue;
18431845
}
18441846

@@ -2213,8 +2215,8 @@ void PopupMenu::_bind_methods() {
22132215

22142216
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));
22152217

2216-
ClassDB::bind_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::add_shortcut, DEFVAL(-1), DEFVAL(false));
2217-
ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false));
2218+
ClassDB::bind_method(D_METHOD("add_shortcut", "shortcut", "id", "global", "allow_echo"), &PopupMenu::add_shortcut, DEFVAL(-1), DEFVAL(false), DEFVAL(false));
2219+
ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global", "allow_echo"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false), DEFVAL(false));
22182220
ClassDB::bind_method(D_METHOD("add_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_check_shortcut, DEFVAL(-1), DEFVAL(false));
22192221
ClassDB::bind_method(D_METHOD("add_icon_check_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_check_shortcut, DEFVAL(-1), DEFVAL(false));
22202222
ClassDB::bind_method(D_METHOD("add_radio_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_radio_check_shortcut, DEFVAL(-1), DEFVAL(false));

scene/gui/popup_menu.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class PopupMenu : public Popup {
7474
Ref<Shortcut> shortcut;
7575
bool shortcut_is_global = false;
7676
bool shortcut_is_disabled = false;
77+
bool allow_echo = false;
7778

7879
// Returns (0,0) if icon is null.
7980
Size2 get_icon_size() const {
@@ -199,6 +200,12 @@ class PopupMenu : public Popup {
199200
void _get_property_list(List<PropertyInfo> *p_list) const;
200201
static void _bind_methods();
201202

203+
#ifndef DISABLE_DEPRECATED
204+
void _add_shortcut_bind_compat_36493(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
205+
void _add_icon_shortcut_bind_compat_36493(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
206+
static void _bind_compatibility_methods();
207+
#endif
208+
202209
public:
203210
// ATTENTION: This is used by the POT generator's scene parser. If the number of properties returned by `_get_items()` ever changes,
204211
// this value should be updated to reflect the new size.
@@ -215,8 +222,8 @@ class PopupMenu : public Popup {
215222

216223
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);
217224

218-
void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
219-
void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
225+
void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false, bool p_allow_echo = false);
226+
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);
220227
void add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
221228
void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
222229
void add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);

0 commit comments

Comments
 (0)