You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

50 lines
1.4 KiB
GDScript

3 months ago
class_name CaptureFocus
extends Container
## Node that captures UI focus for joypad users.
##
## This script assists with capturing UI focus for joypad users when
## opening, closing, or switching between menus.
## When attached to a node, it will check if it was changed to visible
## and a joypad is being used. If both are true, it will capture focus
## on the first eligible node in its scene tree.
## Hierarchical depth to search in the scene tree.
@export var search_depth : int = 1
@export var lock : bool = false :
set(value):
lock = value
if not lock:
update_focus()
func _focus_first_search(control_node : Control, levels : int = 1):
if control_node == null or !control_node.is_visible_in_tree():
return false
if control_node.focus_mode == FOCUS_ALL:
control_node.grab_focus()
return true
if levels < 1:
return false
var children = control_node.get_children()
for child in children:
if _focus_first_search(child, levels - 1):
return true
func focus_first():
_focus_first_search(self, search_depth)
func update_focus():
if lock : return
if _is_visible_and_joypad():
focus_first()
func _is_visible_and_joypad():
return is_visible_in_tree() and Input.get_connected_joypads().size() > 0
func _on_visibility_changed():
call_deferred("update_focus")
func _ready():
if is_inside_tree():
update_focus()
connect("visibility_changed", _on_visibility_changed)