From e4201734df8c835a12b39276692987d6e2f5c267 Mon Sep 17 00:00:00 2001 From: Saracen Date: Thu, 16 Nov 2017 09:45:52 +0000 Subject: Add manual overrides for focus_next and focus_previous on controls similar to what can already be done with focus neighbours. --- scene/gui/control.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++- scene/gui/control.h | 7 ++++++ 2 files changed, 74 insertions(+), 1 deletion(-) (limited to 'scene/gui') diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index e73ada9f31..3976a2ad48 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1847,6 +1847,25 @@ Control *Control::find_next_valid_focus() const { while (true) { + // If the focus property is manually overwritten, attempt to use it. + + if (!data.focus_next.is_empty()) { + Node *n = get_node(data.focus_next); + if (n) { + from = Object::cast_to(n); + + if (!from) { + + ERR_EXPLAIN("Next focus node is not a control: " + n->get_name()); + ERR_FAIL_V(NULL); + } + } else { + return NULL; + } + if (from->is_visible() && from->get_focus_mode() != FOCUS_NONE) + return from; + } + // find next child Control *next_child = NULL; @@ -1926,6 +1945,25 @@ Control *Control::find_prev_valid_focus() const { while (true) { + // If the focus property is manually overwritten, attempt to use it. + + if (!data.focus_prev.is_empty()) { + Node *n = get_node(data.focus_prev); + if (n) { + from = Object::cast_to(n); + + if (!from) { + + ERR_EXPLAIN("Prev focus node is not a control: " + n->get_name()); + ERR_FAIL_V(NULL); + } + } else { + return NULL; + } + if (from->is_visible() && from->get_focus_mode() != FOCUS_NONE) + return from; + } + // find prev child Control *prev_child = NULL; @@ -2157,6 +2195,26 @@ NodePath Control::get_focus_neighbour(Margin p_margin) const { return data.focus_neighbour[p_margin]; } +void Control::set_focus_next(const NodePath &p_next) { + + data.focus_next = p_next; +} + +NodePath Control::get_focus_next() const { + + return data.focus_next; +} + +void Control::set_focus_previous(const NodePath &p_prev) { + + data.focus_prev = p_prev; +} + +NodePath Control::get_focus_previous() const { + + return data.focus_prev; +} + #define MAX_NEIGHBOUR_SEARCH_COUNT 512 Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) { @@ -2172,7 +2230,7 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) { if (!c) { - ERR_EXPLAIN("Next focus node is not a control: " + n->get_name()); + ERR_EXPLAIN("Neighbour focus node is not a control: " + n->get_name()); ERR_FAIL_V(NULL); } } else { @@ -2677,6 +2735,12 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_focus_neighbour", "margin", "neighbour"), &Control::set_focus_neighbour); ClassDB::bind_method(D_METHOD("get_focus_neighbour", "margin"), &Control::get_focus_neighbour); + ClassDB::bind_method(D_METHOD("set_focus_next", "next"), &Control::set_focus_next); + ClassDB::bind_method(D_METHOD("get_focus_next"), &Control::get_focus_next); + + ClassDB::bind_method(D_METHOD("set_focus_previous", "previous"), &Control::set_focus_previous); + ClassDB::bind_method(D_METHOD("get_focus_previous"), &Control::get_focus_previous); + ClassDB::bind_method(D_METHOD("force_drag", "data", "preview"), &Control::force_drag); ClassDB::bind_method(D_METHOD("set_mouse_filter", "filter"), &Control::set_mouse_filter); @@ -2737,6 +2801,8 @@ void Control::_bind_methods() { ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP); ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT); ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM); + ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next"), "set_focus_next", "get_focus_next"); + ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous"), "set_focus_previous", "get_focus_previous"); ADD_GROUP("Mouse", "mouse_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter"); diff --git a/scene/gui/control.h b/scene/gui/control.h index 4d0e3934ad..94c484ca50 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -191,6 +191,8 @@ private: ObjectID modal_prev_focus_owner; NodePath focus_neighbour[4]; + NodePath focus_next; + NodePath focus_prev; HashMap, StringNameHasher> icon_override; HashMap, StringNameHasher> shader_override; @@ -374,6 +376,11 @@ public: void set_focus_neighbour(Margin p_margin, const NodePath &p_neighbour); NodePath get_focus_neighbour(Margin p_margin) const; + void set_focus_next(const NodePath &p_next); + NodePath get_focus_next() const; + void set_focus_previous(const NodePath &p_prev); + NodePath get_focus_previous() const; + Control *get_focus_owner() const; void set_mouse_filter(MouseFilter p_filter); -- cgit v1.2.3