summaryrefslogtreecommitdiffstats
path: root/scene/gui/base_button.cpp
diff options
context:
space:
mode:
authorEric M <itsjusteza@gmail.com>2020-09-17 11:40:00 +1000
committerEric M <itsjusteza@gmail.com>2020-11-23 21:14:26 +1000
commitefe5c250d5c0f749ed594ddd04fa76ca20abe4a4 (patch)
tree4f646765d7c89472d5d516bc84803e6c7af5e964 /scene/gui/base_button.cpp
parentfc806409f491f7585eecd0f01bd50609dfc93729 (diff)
downloadredot-engine-efe5c250d5c0f749ed594ddd04fa76ca20abe4a4.tar.gz
Implement new shortcuts system.
unhandled_key_input changed to unhandled_button_input. Controls can set a 'shortcut_context' which they can then use to determine if their shortcuts should be triggered or not, based on if the viewport's focused GUI control is a child of their 'shortcut context'.
Diffstat (limited to 'scene/gui/base_button.cpp')
-rw-r--r--scene/gui/base_button.cpp39
1 files changed, 36 insertions, 3 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 84e9fc187c..fab0dea804 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -317,14 +317,18 @@ bool BaseButton::is_keep_pressed_outside() const {
void BaseButton::set_shortcut(const Ref<Shortcut> &p_shortcut) {
shortcut = p_shortcut;
- set_process_unhandled_input(shortcut.is_valid());
+ set_process_unhandled_key_input(shortcut.is_valid());
}
Ref<Shortcut> BaseButton::get_shortcut() const {
return shortcut;
}
-void BaseButton::_unhandled_input(Ref<InputEvent> p_event) {
+void BaseButton::_unhandled_key_input(Ref<InputEvent> p_event) {
+ if (!_is_focus_owner_in_shorcut_context()) {
+ return;
+ }
+
if (!is_disabled() && is_visible_in_tree() && !p_event->is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
on_action_event(p_event);
accept_event();
@@ -361,9 +365,34 @@ Ref<ButtonGroup> BaseButton::get_button_group() const {
return button_group;
}
+void BaseButton::set_shortcut_context(Node *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "Shortcut context node can't be null.");
+ shortcut_context = p_node->get_instance_id();
+}
+
+Node *BaseButton::get_shortcut_context() const {
+ Object *ctx_obj = ObjectDB::get_instance(shortcut_context);
+ Node *ctx_node = Object::cast_to<Node>(ctx_obj);
+
+ return ctx_node;
+}
+
+bool BaseButton::_is_focus_owner_in_shorcut_context() const {
+ if (shortcut_context == ObjectID()) {
+ // No context, therefore global - always "in" context.
+ return true;
+ }
+
+ Node *ctx_node = get_shortcut_context();
+ Control *vp_focus = get_focus_owner();
+
+ // If the context is valid and the viewport focus is valid, check if the context is the focus or is a parent of it.
+ return ctx_node && vp_focus && (ctx_node == vp_focus || ctx_node->is_a_parent_of(vp_focus));
+}
+
void BaseButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &BaseButton::_gui_input);
- ClassDB::bind_method(D_METHOD("_unhandled_input"), &BaseButton::_unhandled_input);
+ ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &BaseButton::_unhandled_key_input);
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &BaseButton::set_pressed);
ClassDB::bind_method(D_METHOD("is_pressed"), &BaseButton::is_pressed);
ClassDB::bind_method(D_METHOD("is_hovered"), &BaseButton::is_hovered);
@@ -387,6 +416,9 @@ void BaseButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_button_group", "button_group"), &BaseButton::set_button_group);
ClassDB::bind_method(D_METHOD("get_button_group"), &BaseButton::get_button_group);
+ ClassDB::bind_method(D_METHOD("set_shortcut_context", "node"), &BaseButton::set_shortcut_context);
+ ClassDB::bind_method(D_METHOD("get_shortcut_context"), &BaseButton::get_shortcut_context);
+
BIND_VMETHOD(MethodInfo("_pressed"));
BIND_VMETHOD(MethodInfo("_toggled", PropertyInfo(Variant::BOOL, "button_pressed")));
@@ -426,6 +458,7 @@ BaseButton::BaseButton() {
set_focus_mode(FOCUS_ALL);
action_mode = ACTION_MODE_BUTTON_RELEASE;
button_mask = BUTTON_MASK_LEFT;
+ shortcut_context = ObjectID();
}
BaseButton::~BaseButton() {