Add manual overrides for focus_next and focus_previous on controls similar to what can already be done with focus neighbours.

This commit is contained in:
Saracen 2017-11-16 09:45:52 +00:00
parent 35e7f99299
commit e4201734df
3 changed files with 108 additions and 3 deletions

View file

@ -228,7 +228,14 @@
<argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
Return the forced neighbour for moving the input focus to. When pressing TAB or directional/joypad directions focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function.
Return the forced neighbour for moving the input focus to. When pressing directional/joypad directions, focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function.
</description>
</method>
<method name="get_focus_next" qualifiers="const">
<return type="NodePath">
</return>
<description>
Return the 'focus_next' for moving input focus to. When pressing TAB, focus is moved to the next control in the tree. However, the control to move to can be forced with this function.
</description>
</method>
<method name="get_focus_owner" qualifiers="const">
@ -238,6 +245,13 @@
Return which control is owning the keyboard focus, or null if no one.
</description>
</method>
<method name="get_focus_previous" qualifiers="const">
<return type="NodePath">
</return>
<description>
Return the 'focus_previous' for moving input focus to. When pressing Shift+TAB focus is moved to the previous control in the tree. However, the control to move to can be forced with this function.
</description>
</method>
<method name="get_font" qualifiers="const">
<return type="Font">
</return>
@ -676,7 +690,25 @@
<argument index="1" name="neighbour" type="NodePath">
</argument>
<description>
Force a neighbour for moving the input focus to. When pressing TAB or directional/joypad directions focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function.
Force a neighbour for moving the input focus to. When pressing directional/joypad directions, focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function.
</description>
</method>
<method name="set_focus_next">
<return type="void">
</return>
<argument index="0" name="next" type="NodePath">
</argument>
<description>
Force the 'focus_next' for moving input focus to. When pressing TAB, focus is moved to the next control in the tree. However, the control to move to can be forced with this function.
</description>
</method>
<method name="set_focus_previous">
<return type="void">
</return>
<argument index="0" name="previous" type="NodePath">
</argument>
<description>
Force the 'focus_previous' for moving input focus to. When pressing Shift+TAB, focus is moved to the previous control in the tree. However, the control to move to can be forced with this function.
</description>
</method>
<method name="set_global_position">

View file

@ -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<Control>(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<Control>(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");

View file

@ -191,6 +191,8 @@ private:
ObjectID modal_prev_focus_owner;
NodePath focus_neighbour[4];
NodePath focus_next;
NodePath focus_prev;
HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override;
HashMap<StringName, Ref<Shader>, 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);