game/user_interface/button_selection.gd

83 lines
2.2 KiB
GDScript

@tool
class_name ItemSelection extends HFlowContainer
##
## An item has been selected via GUI selection or [method select_item].
##
signal item_selected(index: int)
var _button_group := ButtonGroup.new()
##
## Number of items in the selection.
##
var item_count: int:
get:
return _button_group.get_buttons().size()
func _get_configuration_warnings() -> PackedStringArray:
var warnings := PackedStringArray()
for child in get_children():
warnings.append(
"ItemSelection can only have children of type Button, but {0} is of type {1}".format(
[child.name, child.get_class()]))
return warnings
##
## Adds a new item with no text and only [code]icon[/code] as the icon to the selection.
##
func add_icon_item(icon: Texture2D) -> void:
var child_count := get_child_count()
var button := Button.new()
button.icon = icon
button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
button.toggle_mode = true
button.button_group = _button_group
button.button_pressed = child_count == 0
button.pressed.connect(func () -> void: select_item(child_count))
add_child(button)
##
## Returns the icon used by the item at [code]index[/code].
##
## An assertion is raised if [code]index[/code] is out of bounds from the item count.
##
func get_item_icon(index: int) -> Texture2D:
var buttons := _button_group.get_buttons()
assert(index < buttons.size(), "index out of range")
var button := buttons[index] as Button
return null if (button == null) else button.icon
##
## Returns the currently selected item index or [code]-1[/code] if no item is selected.
##
func get_selected_item() -> int:
var pressed_button := _button_group.get_pressed_button()
return -1 if (pressed_button == null) else pressed_button.get_index()
##
## Selects the item at [code]index[/code], emitting [signal item_selected] at the end.
##
## An assertion is raised if [code]index[/code] is out of bounds from the item count.
##
func select_item(index: int) -> void:
var buttons := _button_group.get_buttons()
assert(index < buttons.size(), "index out of range")
var pressed_button := _button_group.get_pressed_button()
if pressed_button != null:
pressed_button.set_pressed_no_signal(false)
buttons[index].set_pressed_no_signal(true)
item_selected.emit(index)