Files
2026-07-07 16:43:51 +02:00

129 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using Ashwild.UI;
namespace Ashwild.Building
{
/// <summary>
/// The construction menu window — a pure view driven by the GameUIManager panel stack (its
/// Build kind locks input and shows the cursor while the world keeps running, like the
/// inventory). It has no knowledge of the buildable data: a manager pushes a card payload in
/// through <see cref="Populate"/> and the menu renders exactly that, reporting a pick back by
/// index. The controller object stays active so Show/Hide only toggle the visible window,
/// mirroring InventoryUI.
/// </summary>
public class BuildMenuUI : UIPanel
{
/// <summary>
/// Marks this panel as the construction menu: input is locked and the cursor shows, but
/// the world keeps running (unlike the pause menu).
/// </summary>
public override PanelKind Kind => PanelKind.Build;
#region Serialized Fields
[Header("References")]
[SerializeField] private GameObject menuRoot;
[SerializeField] private Transform cardContainer;
[SerializeField] private BuildMenuCardUI cardPrefab;
#endregion
#region State
/// <summary>
/// The card views currently spawned in the grid, destroyed and rebuilt on each populate.
/// </summary>
private readonly List<BuildMenuCardUI> cards = new List<BuildMenuCardUI>();
#endregion
#region Unity Lifecycle
/// <summary>
/// Parks the window closed; the grid is filled later by the manager through Populate.
/// </summary>
private void Start()
{
if (menuRoot != null)
menuRoot.SetActive(false);
}
#endregion
#region Public API
/// <summary>
/// Rebuilds the card grid from the payload a manager pushes in. The menu is a pure view:
/// it renders exactly these cards and reports a pick back by index through the callback,
/// never resolving what a card represents itself.
/// </summary>
public void Populate(IReadOnlyList<BuildCardView> views, Action<int> onSelected)
{
ClearCards();
if (cardPrefab == null || cardContainer == null)
{
Debug.LogError("[BuildMenuUI] Card prefab or container not assigned — cannot build the menu.", this);
return;
}
if (views == null) return;
for (int i = 0; i < views.Count; i++)
{
BuildMenuCardUI card = Instantiate(cardPrefab, cardContainer);
card.Initialize(views[i], i, onSelected);
cards.Add(card);
}
}
#endregion
#region Grid
/// <summary>
/// Destroys the previously spawned cards so a re-populate never stacks duplicates.
/// </summary>
private void ClearCards()
{
foreach (BuildMenuCardUI card in cards)
if (card != null) Destroy(card.gameObject);
cards.Clear();
}
#endregion
#region Panel Show/Hide
/// <summary>
/// Opens the menu window (called by the GameUIManager panel stack).
/// </summary>
public override void Show()
{
if (menuRoot != null)
menuRoot.SetActive(true);
}
/// <summary>
/// Closes the menu window.
/// </summary>
public override void Hide()
{
if (menuRoot != null)
menuRoot.SetActive(false);
}
/// <summary>
/// Instant close used when the manager initializes panels — just parks the window closed.
/// </summary>
public override void HideInstant()
{
if (menuRoot != null)
menuRoot.SetActive(false);
}
#endregion
}
}