class_name ChipBar extends Control # The value to represent in filled chips. In the future chips may be colored differently above certain thresholds to stop drawing too many @export var value: int: set(v): value = v if is_node_ready(): _refresh() # The total number of chips. If value is less than this, those chips should be empty. @export var max_value: int: set(v): max_value = v if is_node_ready(): _refresh() # Configures the size of the hflow based on the chip texture size. @export var max_chips_per_row: int # The texture for an empty chip @export var empty_chip_texture: Texture2D # The texture for a filled chip @export var filled_chip_texture: Texture2D @onready var _container: VBoxContainer = $VBoxContainer func _ready() -> void: _refresh() func _refresh() -> void: for child in _container.get_children(): child.queue_free() if max_chips_per_row <= 0 or not filled_chip_texture: return var chip_width := filled_chip_texture.get_width() var effective_per_row := max_chips_per_row if chip_width > 0 and _container.size.x > 0: effective_per_row = mini(effective_per_row, int(_container.size.x / chip_width)) var filled_remaining := value var chips_laid_out := 0 while chips_laid_out < max_value: var row := HBoxContainer.new() row.alignment = BoxContainer.ALIGNMENT_END row.size_flags_horizontal = Control.SIZE_EXPAND_FILL row.add_theme_constant_override("separation", 0) var chips_in_row := mini(effective_per_row, max_value - chips_laid_out) var filled_in_row := mini(filled_remaining, chips_in_row) var empty_in_row := chips_in_row - filled_in_row for i in empty_in_row: var tex_rect := TextureRect.new() tex_rect.texture = empty_chip_texture row.add_child(tex_rect) for i in filled_in_row: var tex_rect := TextureRect.new() tex_rect.texture = filled_chip_texture row.add_child(tex_rect) filled_remaining -= filled_in_row chips_laid_out += chips_in_row _container.add_child(row)