188 lines
7.6 KiB
C#
188 lines
7.6 KiB
C#
using JetBrains.Annotations;
|
|
using NEG.UI.Area;
|
|
using NEG.UI.Popup;
|
|
using NEG.UI.Window;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace NEG.UI
|
|
{
|
|
[PublicAPI]
|
|
public abstract class UiManager
|
|
{
|
|
public static UiManager Instance { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Current area shown on screen.
|
|
/// </summary>
|
|
public IArea CurrentArea
|
|
{
|
|
get => currentArea;
|
|
set
|
|
{
|
|
currentArea?.SetEnabled(false);
|
|
|
|
currentArea = value;
|
|
|
|
currentArea?.SetEnabled(true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Current window that is considered main (focused, lastly opened). Can be null.
|
|
/// </summary>
|
|
public IWindow CurrentMainWindow { get; protected set; }
|
|
|
|
public PopupData CurrentPopup => currentShownPopup.data;
|
|
|
|
private IArea currentArea;
|
|
private (PopupData data, int priority) currentShownPopup;
|
|
protected IDefaultPopup currentDefaultPopup;
|
|
|
|
private PriorityQueue<PopupData, int> popupsToShow = new();
|
|
|
|
//TODO: localize
|
|
private string localizedYes = "Yes", localizedNo = "No", localizedOk = "Ok";
|
|
|
|
protected UiManager(IArea startArea)
|
|
{
|
|
if (Instance != null)
|
|
{
|
|
Debug.LogError("Only one instance od UiManager is allowed");
|
|
return;
|
|
}
|
|
|
|
Instance = this;
|
|
|
|
CurrentArea = startArea;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later. It will be closed after pressing ok button.
|
|
/// </summary>
|
|
/// <param name="title">popup title</param>
|
|
/// <param name="content">popup content</param>
|
|
/// <param name="okText">text to show on ok button, empty for localized "Ok"</param>
|
|
/// <param name="okPressed">additional action on ok pressed</param>
|
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
|
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
|
public PopupData ShowOkPopup(string title, string content, string okText = null, Action okPressed = null, int priority = 0, bool forceShow = false)
|
|
{
|
|
var data = new DefaultPopupData(currentDefaultPopup, title, content,
|
|
new List<(string, Action)>() { (okText ?? localizedOk, okPressed) });
|
|
ShowPopup(data, priority, forceShow);
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later. It will be closed after pressing yes or no button.
|
|
/// </summary>
|
|
/// <param name="title">popup title</param>
|
|
/// <param name="content">popup content</param>
|
|
/// <param name="yesText">text to show on yes button, empty for localized "Yes"</param>
|
|
/// <param name="noText">text to show on no button, empty for localized "No"</param>
|
|
/// <param name="yesPressed">additional action on yes pressed</param>
|
|
/// <param name="noPressed">additional action on no pressed</param>
|
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
|
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
|
public PopupData ShowYesNoPopup(string title, string content, string yesText = null, string noText = null, Action yesPressed = null, Action noPressed = null, int priority = 0, bool forceShow = false)
|
|
{
|
|
var data = new DefaultPopupData(currentDefaultPopup, title, content,
|
|
new List<(string, Action)>() { (yesText ?? localizedYes, yesPressed), (noText ?? localizedNo, noPressed) });
|
|
ShowPopup(data, priority, forceShow);
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later. It will be closed after pressing any button.
|
|
/// </summary>
|
|
/// <param name="title">popup title</param>
|
|
/// <param name="content">popup content</param>
|
|
/// <param name="actions">list of actions</param>
|
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
|
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
|
public PopupData ShowPopup(string title, string content, List<(string, Action)> actions, int priority = 0, bool forceShow = false)
|
|
{
|
|
var data = new DefaultPopupData(currentDefaultPopup, title, content, actions);
|
|
ShowPopup(data, priority, forceShow);
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later.
|
|
/// </summary>
|
|
/// <param name="data">popup data object</param>
|
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
|
public void ShowPopup(PopupData data, int priority = 0, bool forceShow = false)
|
|
{
|
|
popupsToShow.Enqueue(data, priority);
|
|
UpdatePopupsState(forceShow, priority, data);
|
|
}
|
|
|
|
public void RefreshPopups()
|
|
{
|
|
if(currentShownPopup.data is { IsValid: true })
|
|
return;
|
|
UpdatePopupsState(false);
|
|
}
|
|
|
|
protected void PopupClosed(PopupData data)
|
|
{
|
|
if (currentShownPopup.data != data)
|
|
{
|
|
//Debug.LogError("Popup was not shown");
|
|
return;
|
|
}
|
|
UpdatePopupsState(false);
|
|
}
|
|
|
|
protected void SetDefaultPopup(IDefaultPopup popup) => currentDefaultPopup = popup;
|
|
|
|
private void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
|
|
{
|
|
if (forceShow)
|
|
{
|
|
if(currentShownPopup.priority <= priority)
|
|
return;
|
|
|
|
popupsToShow.Enqueue(currentShownPopup.data, currentShownPopup.priority);
|
|
ShowPopup(data, priority);
|
|
return;
|
|
}
|
|
|
|
while (popupsToShow.TryDequeue(out var d, out int p))
|
|
{
|
|
if(!d.IsValid)
|
|
continue;
|
|
ShowPopup(d, p);
|
|
return;
|
|
}
|
|
|
|
if (currentShownPopup.data == null)
|
|
return;
|
|
currentShownPopup.data.PopupClosedEvent -= PopupClosed;
|
|
currentShownPopup.data.Hide();
|
|
currentShownPopup.data = null;
|
|
}
|
|
|
|
private void ShowPopup(PopupData data, int priority)
|
|
{
|
|
if (currentShownPopup.data != null)
|
|
{
|
|
currentShownPopup.data.PopupClosedEvent -= PopupClosed;
|
|
currentShownPopup.data.Hide();
|
|
}
|
|
currentShownPopup = (data, priority);
|
|
data.Show();
|
|
data.PopupClosedEvent += PopupClosed;
|
|
}
|
|
}
|
|
}
|
|
|
|
|