Foco de teclado

Nove botões ligados em anel pelo focus_neighbor, percorridos com tab e as setas. Interface que funciona sem mouse.

O editor acima está rodando este projeto. Mude uma linha e ele recarrega.

Classes do Godot usadas

ButtonGridContainer

O código

scripts/main.gd
extends Node

var status: Label
var first: Button


func _ready() -> void:
	var column: VBoxContainer = _root()

	var title: Label = Label.new()
	title.text = 'Focus without a mouse'
	title.add_theme_font_size_override('font_size', 26)
	column.add_child(title)

	var hint: Label = Label.new()
	hint.text = 'tab walks the ring, arrows follow focus_neighbor and wrap at the edges, enter presses'
	hint.add_theme_color_override('font_color', Color('#999999'))
	column.add_child(hint)

	var grid: GridContainer = GridContainer.new()
	grid.columns = 3
	grid.add_theme_constant_override('h_separation', 12)
	grid.add_theme_constant_override('v_separation', 12)
	column.add_child(grid)

	var buttons: Array[Button] = []

	for i in 9:
		var button: Button = Button.new()
		button.text = 'cell %d' % i
		button.custom_minimum_size = Vector2(130, 60)
		button.focus_entered.connect(func(): _say('focus on cell %d' % i))
		button.pressed.connect(func(): _say('pressed cell %d' % i))
		grid.add_child(button)
		buttons.append(button)

	# the modulo closes the grid into a ring, so leaving on the right enters on the left
	for i in buttons.size():
		buttons[i].focus_neighbor_left = buttons[(i + 8) % 9].get_path()
		buttons[i].focus_neighbor_right = buttons[(i + 1) % 9].get_path()
		buttons[i].focus_neighbor_top = buttons[(i + 6) % 9].get_path()
		buttons[i].focus_neighbor_bottom = buttons[(i + 3) % 9].get_path()

	status = Label.new()
	status.add_theme_color_override('font_color', Color('#8eef97'))
	column.add_child(status)

	first = buttons[0]
	first.grab_focus()


func _say(message: String) -> void:
	status.text = message


func _root() -> VBoxContainer:
	var background: ColorRect = ColorRect.new()
	background.color = Color('#12141a')
	add_child(background)
	background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

	var center: CenterContainer = CenterContainer.new()
	add_child(center)
	center.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

	var column: VBoxContainer = VBoxContainer.new()
	column.add_theme_constant_override('separation', 16)
	center.add_child(column)

	return column

Mais exemplos de Interface