using System; using System.Collections.Generic; using UnityEngine; using Ashwild.UI; namespace Ashwild.Building { /// /// 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 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. /// public class BuildMenuUI : UIPanel { /// /// Marks this panel as the construction menu: input is locked and the cursor shows, but /// the world keeps running (unlike the pause menu). /// 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 /// /// The card views currently spawned in the grid, destroyed and rebuilt on each populate. /// private readonly List cards = new List(); #endregion #region Unity Lifecycle /// /// Parks the window closed; the grid is filled later by the manager through Populate. /// private void Start() { if (menuRoot != null) menuRoot.SetActive(false); } #endregion #region Public API /// /// 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. /// public void Populate(IReadOnlyList views, Action 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 /// /// Destroys the previously spawned cards so a re-populate never stacks duplicates. /// private void ClearCards() { foreach (BuildMenuCardUI card in cards) if (card != null) Destroy(card.gameObject); cards.Clear(); } #endregion #region Panel Show/Hide /// /// Opens the menu window (called by the GameUIManager panel stack). /// public override void Show() { if (menuRoot != null) menuRoot.SetActive(true); } /// /// Closes the menu window. /// public override void Hide() { if (menuRoot != null) menuRoot.SetActive(false); } /// /// Instant close used when the manager initializes panels — just parks the window closed. /// public override void HideInstant() { if (menuRoot != null) menuRoot.SetActive(false); } #endregion } }