Files
2026-06-22 16:18:34 +02:00

139 lines
4.2 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;
using System;
namespace Ashwild.Inventory
{
public class SlotUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerClickHandler
{
[Header("References")]
[SerializeField] private Image iconImage;
[SerializeField] private TextMeshProUGUI quantityText;
[SerializeField] private Image highlightImage;
private int slotIndex;
private Action<int, int> onSwapRequested;
private Action<int, bool> onClicked;
public int SlotIndex => slotIndex;
// Static drag state shared across all slots
private static SlotUI draggedSlot;
private static GameObject ghostObject;
private static Image ghostIcon;
private static TextMeshProUGUI ghostQuantity;
public static void SetupGhost(GameObject ghost, Image icon, TextMeshProUGUI qty)
{
ghostObject = ghost;
ghostIcon = icon;
ghostQuantity = qty;
ghostObject.SetActive(false);
}
public void Initialize(int index, Action<int, int> swapCallback, Action<int, bool> clickCallback)
{
slotIndex = index;
onSwapRequested = swapCallback;
onClicked = clickCallback;
}
public void UpdateVisual(InventorySlot slot)
{
if (slot == null || slot.IsEmpty)
{
iconImage.gameObject.SetActive(false);
quantityText.gameObject.SetActive(false);
}
else
{
iconImage.gameObject.SetActive(true);
iconImage.sprite = slot.ItemData.Icon;
bool showQty = slot.Quantity > 1;
quantityText.gameObject.SetActive(showQty);
if (showQty)
quantityText.text = slot.Quantity.ToString();
}
}
public void SetSelected(bool selected)
{
if (highlightImage != null)
highlightImage.gameObject.SetActive(selected);
}
// Drag & Drop
public void OnBeginDrag(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left) return;
InventorySlot slot = PlayerInventory.Instance.GetSlot(slotIndex);
if (slot == null || slot.IsEmpty) return;
draggedSlot = this;
// Show ghost
if (ghostObject != null)
{
ghostObject.SetActive(true);
ghostIcon.sprite = slot.ItemData.Icon;
ghostIcon.gameObject.SetActive(true);
bool showQty = slot.Quantity > 1;
ghostQuantity.gameObject.SetActive(showQty);
if (showQty)
ghostQuantity.text = slot.Quantity.ToString();
ghostObject.transform.position = eventData.position;
}
// Make source icon semi-transparent
Color c = iconImage.color;
c.a = 0.4f;
iconImage.color = c;
}
public void OnDrag(PointerEventData eventData)
{
if (draggedSlot != this) return;
if (ghostObject != null)
ghostObject.transform.position = eventData.position;
}
public void OnEndDrag(PointerEventData eventData)
{
if (draggedSlot != this) return;
// Hide ghost
if (ghostObject != null)
ghostObject.SetActive(false);
// Restore icon opacity
Color c = iconImage.color;
c.a = 1f;
iconImage.color = c;
draggedSlot = null;
}
public void OnDrop(PointerEventData eventData)
{
if (draggedSlot == null || draggedSlot == this) return;
onSwapRequested?.Invoke(draggedSlot.SlotIndex, slotIndex);
}
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.dragging) return;
if (eventData.button == PointerEventData.InputButton.Right)
onClicked?.Invoke(slotIndex, true);
}
}
}