Initial Unity project commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI.PanelStack
|
||||
{
|
||||
public class UIPanelStack : MonoBehaviour
|
||||
{
|
||||
public static UIPanelStack Instance { get; private set; }
|
||||
|
||||
private readonly List<Entry> stack = new List<Entry>();
|
||||
private Func<bool> escapeOpenHandler;
|
||||
[SerializeField] private bool debugLogs = true;
|
||||
|
||||
private sealed class Entry
|
||||
{
|
||||
public UIPanelKind kind;
|
||||
public GameObject root;
|
||||
public Action closeAction;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(UIPanelKind kind, GameObject root, Action closeAction)
|
||||
{
|
||||
if (root == null) { return; }
|
||||
|
||||
Remove(root);
|
||||
|
||||
stack.Add(new Entry
|
||||
{
|
||||
kind = kind,
|
||||
root = root,
|
||||
closeAction = closeAction
|
||||
});
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] Push kind={kind} root={root.name} count={stack.Count}");
|
||||
}
|
||||
|
||||
public bool Remove(GameObject root)
|
||||
{
|
||||
if (root == null) { return false; }
|
||||
|
||||
for (int i = stack.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (stack[i].root == root)
|
||||
{
|
||||
stack.RemoveAt(i);
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] Remove root={root.name} count={stack.Count}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CloseTop()
|
||||
{
|
||||
CleanupInactive();
|
||||
|
||||
if (stack.Count == 0) { return false; }
|
||||
|
||||
Entry top = stack[stack.Count - 1];
|
||||
stack.RemoveAt(stack.Count - 1);
|
||||
|
||||
if (top.root == null) { return false; }
|
||||
|
||||
if (top.closeAction != null)
|
||||
{
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] CloseTop via action kind={top.kind} root={top.root.name} remain={stack.Count}");
|
||||
top.closeAction.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] CloseTop via SetActive(false) kind={top.kind} root={top.root.name} remain={stack.Count}");
|
||||
top.root.SetActive(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetEscapeOpenHandler(Func<bool> handler)
|
||||
{
|
||||
escapeOpenHandler = handler;
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] SetEscapeOpenHandler set={(handler!=null)}");
|
||||
}
|
||||
|
||||
public void ClearEscapeOpenHandler(Func<bool> handler)
|
||||
{
|
||||
if (handler == null) { return; }
|
||||
if (escapeOpenHandler == handler)
|
||||
{
|
||||
escapeOpenHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryOpenOnEscapeWhenEmpty()
|
||||
{
|
||||
if (escapeOpenHandler == null) { return false; }
|
||||
bool result = escapeOpenHandler.Invoke();
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] TryOpenOnEscapeWhenEmpty result={result}");
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsAnyOpen()
|
||||
{
|
||||
CleanupInactive();
|
||||
return stack.Count > 0;
|
||||
}
|
||||
|
||||
private void CleanupInactive()
|
||||
{
|
||||
for (int i = stack.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (stack[i].root == null || !stack[i].root.activeInHierarchy)
|
||||
{
|
||||
stack.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user