using System; using System.Collections.Generic; using UnityEngine; namespace AibisDream.UI { public enum InGameTerminalPage { None, Setting, Record, } /// /// 局内终端 Panel 壳:管理 Setting / Record 两个 Page。 /// Setting / Record 需在场景中分别挂独立的 Prefab 实例,并在 Inspector 中绑定。 /// public class InGameTerminalPanel : MonoBehaviour, IUIPanel, ITerminalPanelHost { [SerializeField] private TerminalHeaderView header; [SerializeField] private TerminalSettingPanel settingPage; [SerializeField] private TerminalRecordPanel recordPage; private readonly Stack _backStack = new(); private InGameTerminalPage _currentPage = InGameTerminalPage.None; private bool _pausedByPanel; public bool IsOpen => gameObject.activeSelf && _currentPage != InGameTerminalPage.None; public bool IsCloseable => true; public InGameTerminalPage CurrentPage => _currentPage; public bool IsInGameContext => true; public void Initialize() { var root = transform; settingPage ??= root.GetComponentInChildren(true); recordPage ??= root.GetComponentInChildren(true); settingPage?.SetOwner(this); recordPage?.SetOwner(this); Close(); } public bool HasRequiredPages() { return settingPage != null && recordPage != null; } public void Show() { Open(InGameTerminalPage.Setting); } public void Hide() { Close(); } public void Open(InGameTerminalPage page) { if (!HasRequiredPages() || page == InGameTerminalPage.None) { return; } if (!IsOpen) { _backStack.Clear(); } gameObject.SetActive(true); PauseIfNeeded(); SwitchTo(page, pushCurrent: false); } public void SwitchTo(InGameTerminalPage page, bool pushCurrent = true) { if (page == InGameTerminalPage.None || page == _currentPage) { return; } if (pushCurrent && _currentPage != InGameTerminalPage.None) { _backStack.Push(_currentPage); } var previous = _currentPage; _currentPage = page; if (previous == InGameTerminalPage.None) { ShowPage(_currentPage); return; } HidePage(previous, () => ShowPage(_currentPage)); } public void Back() { if (_backStack.Count > 0) { var previous = _backStack.Pop(); var current = _currentPage; _currentPage = previous; HidePage(current, () => ShowPage(_currentPage)); return; } Close(); } public bool HandleEscape() { if (!IsOpen) { return false; } Back(); return true; } public void Close() { HideAllPages(); _backStack.Clear(); _currentPage = InGameTerminalPage.None; ContinueIfPaused(); gameObject.SetActive(false); } public void CloseToMainMenu() { Close(); GameManager.Instance.QuitGame(); } public void SetHeader(string title, string status = "") { header?.SetText(title, status); } public void AppendDialogLine(LineInfo lineInfo) { recordPage?.AppendDialogLine(lineInfo); } public void ClearDialog() { recordPage?.ClearDialog(); } private void PauseIfNeeded() { if (GameManager.Instance == null || !GameManager.Instance.state.isInGame || _pausedByPanel) { return; } GameManager.Instance.PauseGame(); _pausedByPanel = true; } private void ContinueIfPaused() { if (!_pausedByPanel) { return; } GameManager.Instance.ContinueGame(); _pausedByPanel = false; } private void ShowPage(InGameTerminalPage page) { switch (page) { case InGameTerminalPage.Setting: settingPage?.Show(); break; case InGameTerminalPage.Record: recordPage?.Show(); break; } } private void HidePage(InGameTerminalPage page, Action onComplete = null) { switch (page) { case InGameTerminalPage.Setting: settingPage?.Hide(onComplete); break; case InGameTerminalPage.Record: recordPage?.Hide(onComplete); break; default: onComplete?.Invoke(); break; } } private void HideAllPages() { settingPage?.Hide(); recordPage?.Hide(); } } }