Files
VOIDRPG/Assets/92 - UserInterface/Generic/Game/ContainerUI.cs
T
2026-07-09 21:33:33 +02:00

164 lines
7.1 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using VOID.Generic.Dict;
using VOID.Generic.Objects.Container;
using VOID.Generic.Objects.Container.Events;
using VOID.Generic.Objects.Item;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Objects.Unit.Actions;
using VOID.UserInterface.Game.Interfaces;
using VOID.UserInterface.Game.Util;
namespace VOID.UserInterface.Game
{
public class ContainerUI : MonoBehaviour, IHasWindow
{
public static List<ContainerUI> currentList { get; } = new();
// WindowUI
public WindowUI windowUI { get; private set; }
// ContainerObject, its content to which this UI is connected and also unit who opened it
public ContainerObject container { get; private set; }
private ContainerObjectContent _content;
private UnitObject _unit;
// Visual Elements
private VisualElement _rootElement;
private VisualElement _slotsElement;
private SlotUI[] _slots;
// Sort buttons
private Button _sortButton;
private void Awake() {
currentList.Add(this);
var uiDocument = gameObject.GetComponent<UIDocument>();
var template = uiDocument.rootVisualElement;
// Find all important elements
_rootElement = template.Q("root-container");
_slotsElement = template.Q("slots");
windowUI = gameObject.GetComponent<WindowUI>();
// Sort buttons
_sortButton = template.Q<Button>("Sort");
// Remove place holders
_slotsElement.Clear();
windowUI.OnClose += Close;
_rootElement.dataSource = this;
_rootElement.pickingMode = PickingMode.Position;
// Sort buttons
_sortButton.clicked += () => {
var worldBound = _sortButton.worldBound;
var positionToDisplayDropdown = new Vector2(worldBound.x, worldBound.y + worldBound.height);
DropdownUI.current.Prepare(positionToDisplayDropdown);
DropdownUI.current.AddOption("Name ↑", () => _content.Sort(item => item.basicData.finalName, SortDirectionType.Ascending, _unit));
DropdownUI.current.AddOption("Name ↓", () => _content.Sort(item => item.basicData.finalName, SortDirectionType.Descending, _unit));
DropdownUI.current.AddOption("Price ↑", () => _content.Sort(item => item.itemData.finalValue, SortDirectionType.Ascending, _unit));
DropdownUI.current.AddOption("Price ↓", () => _content.Sort(item => item.itemData.finalValue, SortDirectionType.Descending, _unit));
DropdownUI.current.AddOption("Weight ↑", () => _content.Sort(item => item.itemData.finalWeight, SortDirectionType.Ascending, _unit));
DropdownUI.current.AddOption("Weight ↓", () => _content.Sort(item => item.itemData.finalWeight, SortDirectionType.Descending, _unit));
DropdownUI.current.AddOption("Quality ↑", () => _content.Sort(item => item.itemData.quality.index, SortDirectionType.Ascending, _unit));
DropdownUI.current.AddOption("Quality ↓", () => _content.Sort(item => item.itemData.quality.index, SortDirectionType.Descending, _unit));
DropdownUI.current.Open();
};
}
public void Open(ContainerObject container, UnitObject unit) {
this.container = container;
_content = container.containerContent;
_unit = unit;
_slots = new SlotUI[_content.items.Length];
for (var i = 0; i < _content.items.Length; i++)
SetSlot(i, _content.items[i]);
container.containerEvents.onClose.AddListener(OnClose);
container.containerEvents.onResize.AddListener(OnResize);
container.containerEvents.onSwap.AddListener(OnSwap);
container.containerEvents.onMoveIn.AddListener(OnMoveIn);
container.containerEvents.onMoveOut.AddListener(OnMoveOut);
container.containerEvents.onSort.AddListener(OnSort);
windowUI.SetTitle(container.basicData.finalName);
// Make sure it is visible
_rootElement.style.display = DisplayStyle.Flex;
}
public void Close() {
_unit.OrderInstantly(new CloseContainerAction(_unit, container));
}
private void OnClose(ContainerCloseEvent containerCloseEvent) {
container.containerEvents.onClose.RemoveListener(OnClose);
container.containerEvents.onResize.RemoveListener(OnResize);
container.containerEvents.onSwap.RemoveListener(OnSwap);
container.containerEvents.onMoveIn.RemoveListener(OnMoveIn);
container.containerEvents.onMoveOut.RemoveListener(OnMoveOut);
container.containerEvents.onSort.RemoveListener(OnSort);
windowUI.OnClose -= Close;
_rootElement.parent.parent.Remove(_rootElement.parent);
currentList.Remove(this);
Destroy(this);
}
private void OnResize(ContainerResizeEvent containerResizeEvent) {
// Before resizing - remove all unused slots
if (containerResizeEvent.beforeSlotCount > containerResizeEvent.afterSlotCount)
for (var i = containerResizeEvent.afterSlotCount; i < containerResizeEvent.beforeSlotCount; i++)
RemoveSlot(i);
Array.Resize(ref _slots, containerResizeEvent.afterSlotCount);
// After resizing - insert empty slots
if (containerResizeEvent.beforeSlotCount < containerResizeEvent.afterSlotCount)
for (var i = containerResizeEvent.beforeSlotCount; i < containerResizeEvent.afterSlotCount; i++)
SetSlot(i, null);
}
private void OnSwap(ContainerSwapEvent containerSwapEvent) {
SetSlot(containerSwapEvent.firstSlotIndex, containerSwapEvent.firstItem);
SetSlot(containerSwapEvent.secondSlotIndex, containerSwapEvent.secondItem);
}
private void OnMoveIn(ContainerMoveInEvent containerMoveInEvent) {
SetSlot(containerMoveInEvent.slotIndex, containerMoveInEvent.item);
}
private void OnMoveOut(ContainerMoveOutEvent containerMoveOutEvent) {
SetSlot(containerMoveOutEvent.slotIndex, null);
}
private void OnSort(ContainerSortEvent containerSortEvent) {
var containerItems = containerSortEvent.container.containerContent.items;
for (var i = 0; i < containerItems.Length; i++)
SetSlot(i, containerItems[i]);
}
private void SetSlot(int slotIndex, ItemObject item) {
// Create new VisualElement if not exists
if (_slots[slotIndex] is null) {
_slots[slotIndex] = new SlotUI();
_slots[slotIndex].InitNew(_slotsElement, SlotType.ContainerSlot, slotIndex, "Slot-" + slotIndex);
}
// Put item's icon or else remain default
_slots[slotIndex].Set(item);
}
private void RemoveSlot(int slotIndex) {
_slots[slotIndex].Destroy();
}
}
}