tool class_name RadioButtons extends HBoxContainer signal selected(selection) export var condense: bool = false export var default_selection: int = 0 setget _set_default_selection export (Array, String) var options: Array = [] setget _set_options onready var selection: int = default_selection setget _set_selection var _buttons: Array = [] func _init() -> void: focus_mode = FOCUS_ALL connect("focus_entered", self, "_on_focus_entered") func _set_default_selection(value: int) -> void: if value < 0: value = 0 elif value >= options.size() and value != 0: value = options.size() - 1 default_selection = value if not _buttons.empty(): _buttons[default_selection].pressed = true func _set_options(value: Array) -> void: options = value _init_buttons() func _set_selection(value: int) -> void: selection = value _buttons[selection].pressed = true func update_focus_targets() -> void: for b in _buttons: b.focus_neighbour_top = "../%s" % focus_neighbour_top b.focus_neighbour_bottom = "../%s" % focus_neighbour_bottom func _init_buttons() -> void: # initialize buttons array for child in get_children(): remove_child(child) child.queue_free() _buttons.clear() _buttons.resize(options.size()) # set up new buttons var group := ButtonGroup.new() for i in options.size(): # create new button var b := Button.new() b.text = options[i] b.toggle_mode = true b.group = group # size flags if condense: b.size_flags_horizontal = 0 else: b.size_flags_horizontal = SIZE_EXPAND | SIZE_SHRINK_CENTER b.size_flags_vertical = 0 # connect signal with index as payload b.connect("focus_entered", self, "_on_button_selected", [i]) # add button to children and array _buttons[i] = b add_child(b) # sync top/bottom focus to self b.focus_neighbour_top = "../%s" % focus_neighbour_top b.focus_neighbour_bottom = "../%s" % focus_neighbour_bottom # set up focus between buttons if i > 0: var prev_b: Button = _buttons[i - 1] b.focus_neighbour_left = b.get_path_to(prev_b) prev_b.focus_neighbour_right = prev_b.get_path_to(b) elif i == 0: b.focus_neighbour_left = @"." elif i == options.size() - 1: b.focus_neighbour_right = @"." _buttons[default_selection].pressed = true func _on_focus_entered() -> void: _buttons[selection].grab_focus() func _on_button_selected(i: int) -> void: if i != selection: selection = i emit_signal("selected", i) _buttons[i].pressed = true