Skip to content

Commit

Permalink
Add Control::grab_focus_no_signal
Browse files Browse the repository at this point in the history
  • Loading branch information
juliohq committed Sep 27, 2023
1 parent ec62b8a commit da5b972
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 4 deletions.
7 changes: 7 additions & 0 deletions doc/classes/Control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,13 @@
<description>
Steal the focus from another control and become the focused control (see [member focus_mode]).
[b]Note:[/b] Using this method together with [method Callable.call_deferred] makes it more reliable, especially when called inside [method Node._ready].
[b]Note:[/b] This method emits [signal Control.focus_entered]. See [method Control.grab_focus_no_signal] if you need to grab the focus without emitting the signal.
</description>
</method>
<method name="grab_focus_no_signal">
<return type="void" />
<description>
Steal the focus from another control and become the focused control without notifying. See also [method grab_focus].
</description>
</method>
<method name="has_focus" qualifiers="const">
Expand Down
14 changes: 13 additions & 1 deletion scene/gui/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2003,7 +2003,7 @@ void Control::grab_focus() {
return;
}

get_viewport()->_gui_control_grab_focus(this);
get_viewport()->_gui_control_grab_focus(this, true);
}

void Control::grab_click_focus() {
Expand All @@ -2024,6 +2024,17 @@ void Control::release_focus() {
get_viewport()->gui_release_focus();
}

void Control::grab_focus_no_signal() {
ERR_FAIL_COND(!is_inside_tree());

if (data.focus_mode == FOCUS_NONE) {
WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus.");
return;
}

get_viewport()->_gui_control_grab_focus(this, false);
}

static Control *_next_control(Control *p_from) {
if (p_from->is_set_as_top_level()) {
return nullptr; // Can't go above.
Expand Down Expand Up @@ -3466,6 +3477,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_clipping_contents"), &Control::is_clipping_contents);

ClassDB::bind_method(D_METHOD("grab_click_focus"), &Control::grab_click_focus);
ClassDB::bind_method(D_METHOD("grab_focus_no_signal"), &Control::grab_focus_no_signal);

ClassDB::bind_method(D_METHOD("set_drag_forwarding", "drag_func", "can_drop_func", "drop_func"), &Control::set_drag_forwarding);
ClassDB::bind_method(D_METHOD("set_drag_preview", "control"), &Control::set_drag_preview);
Expand Down
1 change: 1 addition & 0 deletions scene/gui/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ class Control : public CanvasItem {
void grab_focus();
void grab_click_focus();
void release_focus();
void grab_focus_no_signal();

Control *find_next_valid_focus() const;
Control *find_prev_valid_focus() const;
Expand Down
6 changes: 4 additions & 2 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2466,7 +2466,7 @@ bool Viewport::_gui_control_has_focus(const Control *p_control) {
return gui.key_focus == p_control;
}

void Viewport::_gui_control_grab_focus(Control *p_control) {
void Viewport::_gui_control_grab_focus(Control *p_control, bool p_emit_signal) {
if (gui.key_focus && gui.key_focus == p_control) {
// No need for change.
return;
Expand All @@ -2475,7 +2475,9 @@ void Viewport::_gui_control_grab_focus(Control *p_control) {
if (p_control->is_inside_tree() && p_control->get_viewport() == this) {
gui.key_focus = p_control;
emit_signal(SNAME("gui_focus_changed"), p_control);
p_control->notification(Control::NOTIFICATION_FOCUS_ENTER);
if (p_emit_signal) {
p_control->notification(Control::NOTIFICATION_FOCUS_ENTER);
}
p_control->queue_redraw();
}
}
Expand Down
2 changes: 1 addition & 1 deletion scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ class Viewport : public Node {
void _gui_remove_focus_for_window(Node *p_window);
void _gui_unfocus_control(Control *p_control);
bool _gui_control_has_focus(const Control *p_control);
void _gui_control_grab_focus(Control *p_control);
void _gui_control_grab_focus(Control *p_control, bool p_emit_signal);
void _gui_grab_click_focus(Control *p_control);
void _post_gui_grab_click_focus();
void _gui_accept_event();
Expand Down

0 comments on commit da5b972

Please sign in to comment.