diff options
author | Eric M <itsjusteza@gmail.com> | 2020-09-17 11:40:00 +1000 |
---|---|---|
committer | Eric M <itsjusteza@gmail.com> | 2020-11-23 21:14:26 +1000 |
commit | efe5c250d5c0f749ed594ddd04fa76ca20abe4a4 (patch) | |
tree | 4f646765d7c89472d5d516bc84803e6c7af5e964 /scene/gui/base_button.cpp | |
parent | fc806409f491f7585eecd0f01bd50609dfc93729 (diff) | |
download | redot-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.cpp | 39 |
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() { |