Add subtitle UI for voice playback

This commit is contained in:
2026-05-16 21:33:00 +01:00
parent 58050abded
commit 3174079e37
81 changed files with 8657 additions and 1231 deletions

View File

@@ -41,12 +41,14 @@ namespace BriarQueen.Framework.Managers.UI
public bool Initialized { get; private set; }
private sealed record OverlayResumeContext(WindowType OverlayWindowType, IUIOverlayHost Host);
private IHud _hudContainer;
private IPopup _infoPopup;
private IPopup _tutorialPopup;
private IScreenFader _screenFader;
private IUIOverlayHost _mainMenuOverlayHost;
private IUIOverlayHost _activeSettingsOverlayHost;
private readonly Stack<OverlayResumeContext> _overlayResumeStack = new();
[Inject]
public UIManager(
@@ -127,6 +129,18 @@ namespace BriarQueen.Framework.Managers.UI
window.Hide().Forget();
}
public void UnregisterWindow(IUIWindow window)
{
if (window == null)
return;
if (_windows.TryGetValue(window.WindowType, out var registered) && ReferenceEquals(registered, window))
_windows.Remove(window.WindowType);
if (window is IUIOverlayHost overlayHost)
RemoveOverlayResumeContextsForHost(overlayHost);
}
public void RegisterHUD(IHud hudContainer)
{
_hudContainer = hudContainer;
@@ -169,9 +183,7 @@ namespace BriarQueen.Framework.Managers.UI
if (!ReferenceEquals(_mainMenuOverlayHost, host))
return;
if (ReferenceEquals(_activeSettingsOverlayHost, host))
_activeSettingsOverlayHost = null;
RemoveOverlayResumeContextsForHost(host);
_mainMenuOverlayHost = null;
}
@@ -186,6 +198,51 @@ namespace BriarQueen.Framework.Managers.UI
return target != null && _windowStack.Contains(target);
}
private void RemoveOverlayResumeContextsForHost(IUIOverlayHost host)
{
if (host == null || _overlayResumeStack.Count == 0)
return;
var contextsToKeep = new List<OverlayResumeContext>();
foreach (var context in _overlayResumeStack)
{
if (!ReferenceEquals(context.Host, host))
contextsToKeep.Add(context);
}
_overlayResumeStack.Clear();
for (var i = contextsToKeep.Count - 1; i >= 0; i--)
_overlayResumeStack.Push(contextsToKeep[i]);
}
private async UniTask<bool> TrySuspendActiveWindowFor(WindowType incomingWindowType)
{
if (ActiveWindow is IUIOverlayHost overlayHost &&
overlayHost.CanSuspendFor(incomingWindowType))
{
await overlayHost.SuspendForOverlay();
_overlayResumeStack.Push(new OverlayResumeContext(incomingWindowType, overlayHost));
return true;
}
return false;
}
private async UniTask RestoreUnderlyingUi(WindowType closedWindowType)
{
if (_overlayResumeStack.Count > 0 &&
_overlayResumeStack.Peek().OverlayWindowType == closedWindowType)
{
var resumeContext = _overlayResumeStack.Pop();
await resumeContext.Host.ResumeFromOverlay();
return;
}
if (ActiveWindow != null)
await ActiveWindow.Show();
}
private async UniTask ApplyHudVisibility(bool visible)
{
if (_disposed || _hudContainer == null)
@@ -206,13 +263,25 @@ namespace BriarQueen.Framework.Managers.UI
private void OnPauseClickReceived(PauseButtonClickedEvent _)
{
if (_windowStack.Count > 0)
if (ActiveWindow == null)
{
OpenWindow(WindowType.PauseMenuWindow);
return;
}
if (ActiveWindow.WindowType == WindowType.PauseMenuWindow)
{
TryHandleBackRequest();
return;
}
OpenWindow(WindowType.PauseMenuWindow);
if (ActiveWindow.PauseBehavior == UIPauseBehavior.OpenPauseOverlay)
{
OpenWindow(WindowType.PauseMenuWindow);
return;
}
TryHandleBackRequest();
}
private void OnBackRequested(UIBackRequestedEvent _)
@@ -350,28 +419,22 @@ namespace BriarQueen.Framework.Managers.UI
if (_windowStack.Contains(window))
return;
_activeSettingsOverlayHost = null;
var suspended = false;
var openingSettingsOverPause =
source == SettingsOpenSource.PauseMenu &&
ActiveWindow?.WindowType == WindowType.PauseMenuWindow &&
ActiveWindow is IUIOverlayHost;
var openingSettingsOverMainMenu =
source == SettingsOpenSource.MainMenu &&
_mainMenuOverlayHost != null;
if (openingSettingsOverPause)
if (source == SettingsOpenSource.MainMenu &&
_mainMenuOverlayHost != null &&
_mainMenuOverlayHost.CanSuspendFor(WindowType.SettingsWindow))
{
_activeSettingsOverlayHost = (IUIOverlayHost)ActiveWindow;
await _activeSettingsOverlayHost.SuspendForOverlay();
await _mainMenuOverlayHost.SuspendForOverlay();
_overlayResumeStack.Push(new OverlayResumeContext(WindowType.SettingsWindow, _mainMenuOverlayHost));
suspended = true;
}
else if (openingSettingsOverMainMenu)
else
{
_activeSettingsOverlayHost = _mainMenuOverlayHost;
await _activeSettingsOverlayHost.SuspendForOverlay();
suspended = await TrySuspendActiveWindowFor(WindowType.SettingsWindow);
}
else if (ActiveWindow != null)
if (!suspended && ActiveWindow != null)
{
await ActiveWindow.Hide();
}
@@ -407,7 +470,9 @@ namespace BriarQueen.Framework.Managers.UI
if (_windowStack.Contains(window))
return;
if (ActiveWindow != null)
var suspended = await TrySuspendActiveWindowFor(windowType);
if (!suspended && ActiveWindow != null)
await ActiveWindow.Hide();
_windowStack.Push(window);
@@ -452,15 +517,7 @@ namespace BriarQueen.Framework.Managers.UI
break;
}
if (target.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null)
{
await _activeSettingsOverlayHost.ResumeFromOverlay();
_activeSettingsOverlayHost = null;
}
else if (ActiveWindow != null)
{
await ActiveWindow.Show();
}
await RestoreUnderlyingUi(target.WindowType);
NotifyUIStackChanged();
}
@@ -506,17 +563,8 @@ namespace BriarQueen.Framework.Managers.UI
NotifyWindowStateChanged(top.WindowType, false);
}
if (top != null &&
top.WindowType == WindowType.SettingsWindow &&
_activeSettingsOverlayHost != null)
{
await _activeSettingsOverlayHost.ResumeFromOverlay();
_activeSettingsOverlayHost = null;
}
else if (ActiveWindow != null)
{
await ActiveWindow.Show();
}
if (top != null)
await RestoreUnderlyingUi(top.WindowType);
NotifyUIStackChanged();
}
@@ -536,17 +584,12 @@ namespace BriarQueen.Framework.Managers.UI
await _windowTransitionGate.WaitAsync();
try
{
var shouldResumeSettingsHost = false;
while (_windowStack.Count > 0)
{
var window = _windowStack.Pop();
if (window == null)
continue;
if (window.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null)
shouldResumeSettingsHost = true;
try
{
await window.Hide();
@@ -557,18 +600,7 @@ namespace BriarQueen.Framework.Managers.UI
}
}
if (shouldResumeSettingsHost)
{
try
{
await _activeSettingsOverlayHost.ResumeFromOverlay();
}
catch
{
}
}
_activeSettingsOverlayHost = null;
_overlayResumeStack.Clear();
if (_tutorialPopup != null)
{
@@ -621,7 +653,7 @@ namespace BriarQueen.Framework.Managers.UI
faderComponent.gameObject.SetActive(false);
_windowStack.Clear();
_activeSettingsOverlayHost = null;
_overlayResumeStack.Clear();
_mainMenuOverlayHost = null;
}