From e70b83c7a0920b5390ceaf21c92872836a147bd4 Mon Sep 17 00:00:00 2001
From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Date: Wed, 16 Aug 2023 14:02:22 +0200
Subject: [PATCH] Expose finding valid focus neighbors of a `Control` by side
Exposes the functionality used for ui navigation
---
doc/classes/Control.xml | 9 +++++++++
scene/gui/control.cpp | 5 +++++
scene/gui/control.h | 1 +
3 files changed, 15 insertions(+)
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index a870aa129a6..d665084469e 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -343,6 +343,14 @@
Finds the previous (above in the tree) [Control] that can receive the focus.
+
+
+
+
+ Finds the next [Control] that can receive the focus on the specified [enum Side].
+ [b]Note:[/b] This is different from [method get_focus_neighbor], which returns the path of a specified focus neighbor.
+
+
@@ -389,6 +397,7 @@
Returns the focus neighbor for the specified [enum Side]. A getter method for [member focus_neighbor_bottom], [member focus_neighbor_left], [member focus_neighbor_right] and [member focus_neighbor_top].
+ [b]Note:[/b] To find the next [Control] on the specific [enum Side], even if a neighbor is not assigned, use [method find_valid_focus_neighbor].
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 0ca04faf9b1..171c1c0a666 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2303,6 +2303,10 @@ Control *Control::_get_focus_neighbor(Side p_side, int p_count) {
return result;
}
+Control *Control::find_valid_focus_neighbor(Side p_side) const {
+ return const_cast(this)->_get_focus_neighbor(p_side);
+}
+
void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest) {
if (Object::cast_to(p_at)) {
return; //bye
@@ -3326,6 +3330,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("release_focus"), &Control::release_focus);
ClassDB::bind_method(D_METHOD("find_prev_valid_focus"), &Control::find_prev_valid_focus);
ClassDB::bind_method(D_METHOD("find_next_valid_focus"), &Control::find_next_valid_focus);
+ ClassDB::bind_method(D_METHOD("find_valid_focus_neighbor", "side"), &Control::find_valid_focus_neighbor);
ClassDB::bind_method(D_METHOD("set_h_size_flags", "flags"), &Control::set_h_size_flags);
ClassDB::bind_method(D_METHOD("get_h_size_flags"), &Control::get_h_size_flags);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 7cb8fc5bf6a..a8fd3b3e877 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -526,6 +526,7 @@ public:
Control *find_next_valid_focus() const;
Control *find_prev_valid_focus() const;
+ Control *find_valid_focus_neighbor(Side p_size) const;
void set_focus_neighbor(Side p_side, const NodePath &p_neighbor);
NodePath get_focus_neighbor(Side p_side) const;