src / helpers / focus_helper.gd

Attached Scenes

Note
No attached scenes.

Code

extends Node
class_name FocusHelper

enum Direction { HORIZONTAL, VERTICAL }


static func set_neighbors_h(nodes: Array[Node]) -> void:
	_set_neighbors(nodes, Direction.HORIZONTAL)


static func set_neighbors_v(nodes: Array[Node]) -> void:
	_set_neighbors(nodes, Direction.VERTICAL)


static func grab_first(parent: Node, val) -> void:
	if val:
		var child = parent.get_child(0)
		if child.is_inside_tree(): child.grab_focus()
	else:
		for chapter in parent.get_children():
			chapter.release_focus()


static func is_focuesed(target: Node) -> bool:
	return target.get_viewport().gui_get_focus_owner() == target


static func _set_neighbors(nodes: Array[Node], direction: Direction) -> void:
	for i in nodes.size():
		if i == 0:
			_set_neighbor_between(nodes[i],   nodes[i], nodes[i+1], direction)
		elif i+1 < nodes.size():
			_set_neighbor_between(nodes[i-1], nodes[i], nodes[i+1], direction)
		else:
			_set_neighbor_between(nodes[i-1], nodes[i], nodes[i],   direction)


static func _set_neighbor_between(
	prev: Node, current: Node, next: Node, direction: Direction
) -> void:
	var dir = ['left', 'right'] if direction == Direction.HORIZONTAL \
			else ['top', 'bottom']
	var opp = ['left', 'right'] if direction != Direction.HORIZONTAL \
			else ['top', 'bottom']
	current.set('focus_neighbor_%s'%dir[0], prev.get_path())
	current.set('focus_neighbor_%s'%dir[1], next.get_path())
	current.set('focus_neighbor_next',      prev.get_path())
	current.set('focus_neighbor_previous',  next.get_path())
	current.set('focus_neighbor_%s'%opp[0], current.get_path())
	current.set('focus_neighbor_%s'%opp[1], current.get_path())