Files
aibis-dream/Assets/Scripts/UI/Terminal/TerminalPanel.cs
T

253 lines
6.7 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace AibisDream.UI.Terminal
{
public enum TerminalPage
{
None,
Start,
Setting,
Chapter,
Record
}
public enum TerminalOpenSource
{
None,
MainMenu,
InGame
}
public class TerminalPanel : MonoBehaviour, IUIPanel
{
[SerializeField] private TerminalHeaderView header;
[SerializeField] private TerminalStartPanel startPage;
[SerializeField] private TerminalSettingPanel settingPage;
[SerializeField] private TerminalChapterPanel chapterPage;
[SerializeField] private TerminalRecordPanel recordPage;
private readonly Stack<TerminalPage> _backStack = new();
private TerminalPage _currentPage = TerminalPage.None;
private TerminalOpenSource _source = TerminalOpenSource.None;
private bool _pausedByTerminal;
public bool IsOpen => gameObject.activeSelf && _currentPage != TerminalPage.None;
public bool IsCloseable => _source == TerminalOpenSource.InGame;
public TerminalPage CurrentPage => _currentPage;
public TerminalOpenSource Source => _source;
public void Initialize(RectTransform searchRoot)
{
startPage ??= searchRoot.GetComponentInChildren<TerminalStartPanel>(true);
settingPage ??= searchRoot.GetComponentInChildren<TerminalSettingPanel>(true);
chapterPage ??= searchRoot.GetComponentInChildren<TerminalChapterPanel>(true);
recordPage ??= searchRoot.GetComponentInChildren<TerminalRecordPanel>(true);
startPage?.SetOwner(this);
settingPage?.SetOwner(this);
chapterPage?.SetOwner(this);
recordPage?.SetOwner(this);
Close();
}
public bool HasRequiredPages()
{
return startPage != null && settingPage != null && chapterPage != null && recordPage != null;
}
public void Show()
{
Open(TerminalPage.Start, TerminalOpenSource.MainMenu);
}
public void Hide()
{
Close();
}
public void Open(TerminalPage page, TerminalOpenSource source)
{
if (!HasRequiredPages())
{
return;
}
if (!IsOpen || _source != source)
{
_backStack.Clear();
}
gameObject.SetActive(true);
_source = source;
PauseIfNeeded(page, source);
SwitchTo(page, pushCurrent: false);
}
public void SwitchTo(TerminalPage page, bool pushCurrent = true)
{
if (page == TerminalPage.None || page == _currentPage)
{
return;
}
if (pushCurrent && _currentPage != TerminalPage.None)
{
_backStack.Push(_currentPage);
}
HidePage(_currentPage);
_currentPage = page;
ShowPage(_currentPage);
}
public void Back()
{
if (_source == TerminalOpenSource.InGame)
{
Close();
return;
}
if (_backStack.Count > 0)
{
var previous = _backStack.Pop();
HidePage(_currentPage);
_currentPage = previous;
ShowPage(_currentPage);
return;
}
if (_currentPage != TerminalPage.Start)
{
SwitchTo(TerminalPage.Start, pushCurrent: false);
}
}
public bool HandleEscape()
{
if (!IsOpen)
{
return false;
}
if (_currentPage == TerminalPage.Start)
{
return true;
}
Back();
return true;
}
public void CloseThen(Action action)
{
Close();
action?.Invoke();
}
public void Close()
{
HideAllPages();
_backStack.Clear();
_currentPage = TerminalPage.None;
_source = TerminalOpenSource.None;
ContinueIfPaused();
gameObject.SetActive(false);
}
public void CloseToMainMenu()
{
Close();
GameManager.Instance.QuitGame();
}
public void AppendDialogLine(LineInfo lineInfo)
{
recordPage?.AppendDialogLine(lineInfo);
}
public void ClearDialog()
{
recordPage?.ClearDialog();
}
public void SetHeader(string title, string status = "")
{
header?.SetText(title, status);
}
private void PauseIfNeeded(TerminalPage page, TerminalOpenSource source)
{
if (source != TerminalOpenSource.InGame || page is not (TerminalPage.Setting or TerminalPage.Record))
{
return;
}
if (!_pausedByTerminal)
{
GameManager.Instance.PauseGame();
_pausedByTerminal = true;
}
}
private void ContinueIfPaused()
{
if (!_pausedByTerminal)
{
return;
}
GameManager.Instance.ContinueGame();
_pausedByTerminal = false;
}
private void ShowPage(TerminalPage page)
{
switch (page)
{
case TerminalPage.Start:
startPage?.Show();
break;
case TerminalPage.Setting:
settingPage?.Show();
break;
case TerminalPage.Chapter:
chapterPage?.Show();
break;
case TerminalPage.Record:
recordPage?.Show();
break;
}
}
private void HidePage(TerminalPage page)
{
switch (page)
{
case TerminalPage.Start:
startPage?.Hide();
break;
case TerminalPage.Setting:
settingPage?.Hide();
break;
case TerminalPage.Chapter:
chapterPage?.Hide();
break;
case TerminalPage.Record:
recordPage?.Hide();
break;
}
}
private void HideAllPages()
{
startPage?.Hide();
settingPage?.Hide();
chapterPage?.Hide();
recordPage?.Hide();
}
}
}