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 onSwapRequested; private Action 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 swapCallback, Action 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); } } }