TinyAdventure/ui/item_grid.gd

122 lines
3.0 KiB
GDScript

@tool
class_name ItemGrid
extends GridContainer
signal item_selected
@export var slot_scene:PackedScene
@export var allow_selection:bool = false
@export var allow_drag_drop:bool = false
@export var rows:int:
get:
return rows
set(value):
if value == rows:
return
rows = value
if slot_scene == null or not is_node_ready():
return
resize_grid()
var _slots:Array = []
var _item_slot_to_index:Dictionary = {}
var _highlighted_slot_index = -1
var _highlighted_slot:ItemSlot = null
var selected_slot:ItemSlot = null
var _selected_slot_index:int = -1
func _ready() -> void:
resize_grid()
func resize_grid() -> void:
_item_slot_to_index.clear()
for child in get_children():
child.get_parent().remove_child(child)
child.queue_free()
_slots.clear()
while get_child_count() < rows * columns:
var slot_instance = slot_scene.instantiate() as ItemSlot
if allow_drag_drop:
slot_instance.set_drag_drop_flags(ItemSlot.ALLOW_DRAG | ItemSlot.ALLOW_DROP)
add_child(slot_instance)
_slots.append(slot_instance)
if allow_selection and not Engine.is_editor_hint():
slot_instance.connect("mouse_entered_slot", _on_slot_mouse_entered)
slot_instance.connect("mouse_left_pressed", _on_slot_mouse_left_pressed)
_item_slot_to_index[slot_instance] = _item_slot_to_index.size()
func clear_slots() -> void:
for slot:ItemSlot in _slots:
slot.display(ItemStack.new())
func get_slot_index(slot:ItemSlot) -> int:
if _item_slot_to_index.has(slot):
return _item_slot_to_index[slot]
return -1
func _on_slot_mouse_entered(slot:ItemSlot):
if _highlighted_slot != null:
_highlighted_slot.highlighted = false
_highlighted_slot_index = -1
_highlighted_slot = null
if _item_slot_to_index.has(slot):
_highlighted_slot_index = _item_slot_to_index[slot]
_highlighted_slot = slot
_highlighted_slot.highlighted = true
func select_slot(index:int) -> void:
if index < 0 or index > _slots.size():
item_selected.emit(null)
return
_selected_slot_index = index
selected_slot = _slots[_selected_slot_index]
selected_slot.selected = true
item_selected.emit(selected_slot)
func _on_slot_mouse_left_pressed(slot:ItemSlot):
if selected_slot:
selected_slot.selected = false
if slot == _highlighted_slot:
_highlighted_slot.highlighted = false
select_slot(get_slot_index(slot))
func displayStacks(item_stacks:Array[ItemStack]):
var item_stack_index = 0
for slot:ItemSlot in _slots:
if item_stack_index < item_stacks.size():
slot.display(item_stacks[item_stack_index])
else:
var item_stack:ItemStack = ItemStack.new()
item_stack.item = null
slot.display(item_stack)
item_stack_index = item_stack_index + 1
func display(item_stacks:Array[ItemResource]):
var item_stack_index = 0
for slot:ItemSlot in _slots:
var item_stack:ItemStack = ItemStack.new()
if item_stack_index < item_stacks.size():
item_stack.item = item_stacks[item_stack_index]
item_stack.count = 1
else:
item_stack.item = null
item_stack_index = item_stack_index + 1
slot.display(item_stack)