signalis-eb/godot/src/h_item_list.gd
2025-06-12 00:32:17 -04:00

77 lines
2 KiB
GDScript

class_name HItemList extends HBoxContainer
@export var item_scene: PackedScene
@export var max_items: int = 4
@export var buffered_items: int = 1
@onready var buffer_size = max_items + (buffered_items * 2)
var items: Array = []
var create_item: Callable = _create_item
var bind_item: Callable = _bind_item
var ring_buffer: RingBuffer
func _ready() -> void:
ring_buffer = RingBuffer.new(items.size(), buffer_size, buffer_size - 1)
ring_buffer.rotated.connect(_on_rotated)
for _i in range(buffer_size):
add_child(create_item.call())
_hide_buffered_items()
func _hide_buffered_items():
for i in range(buffered_items):
get_child(i).hide()
var length = buffer_size - 1
for i in range(length, length - buffered_items, -1):
get_child(i).hide()
func _create_item() -> Node:
return item_scene.instantiate()
func _bind_item(node: Node, item: Option):
if node.has_method('bind'):
node.call('bind', item)
func _on_rotated(_direction: int):
_update_display()
func _get_item(index: int) -> Option:
if index < 0 or index >= len(items):
return Option.none
return Option.from(items[index])
func _update_display():
var iter = ring_buffer.iter()
var indices = iter.collect()
for i in range(buffer_size):
var node = get_child(i)
var item_index_from_ring_buffer = indices[i]
var item_option = _get_item(item_index_from_ring_buffer)
bind_item.call(node, item_option)
#if item_option.is_none():
# node.hide() # Hide if no item available
#else:
# if i >= buffered_items and i < (buffer_size - buffered_items):
# node.show()
# else:
# node.hide()
func add_item(item: Variant):
items.append(item)
ring_buffer.source_size = items.size()
_update_display()
func add_items(new_items: Array):
items.append_array(new_items)
ring_buffer.source_size = items.size()
_update_display()
func move_right():
ring_buffer.move_right()
func move_left():
ring_buffer.move_left()