Refine UI stack and add Ashwick keypad puzzle
This commit is contained in:
@@ -5,6 +5,7 @@ using BriarQueen.Framework.Events.Gameplay;
|
||||
using BriarQueen.Framework.Events.Input;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using BriarQueen.Framework.Managers.UI.Base;
|
||||
using BriarQueen.Framework.Services.Game;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
@@ -109,7 +110,7 @@ namespace BriarQueen.Framework.Managers.Input
|
||||
if (_eventCoordinator != null)
|
||||
{
|
||||
_eventCoordinator.Unsubscribe<UIToggleHudEvent>(OnHudStateChanged);
|
||||
_eventCoordinator.Unsubscribe<ToggleCodexEvent>(OnCodexStateChanged);
|
||||
_eventCoordinator.Unsubscribe<UIWindowStateChangedEvent>(OnWindowStateChanged);
|
||||
_eventCoordinator.Unsubscribe<ToggleToolScreenEvent>(OnToolScreenStateChanged);
|
||||
_eventCoordinator.Unsubscribe<UIStackChangedEvent>(OnUIStackChanged);
|
||||
}
|
||||
@@ -158,7 +159,7 @@ namespace BriarQueen.Framework.Managers.Input
|
||||
ApplyCursorModeForCurrentScheme();
|
||||
|
||||
_eventCoordinator.Subscribe<UIToggleHudEvent>(OnHudStateChanged);
|
||||
_eventCoordinator.Subscribe<ToggleCodexEvent>(OnCodexStateChanged);
|
||||
_eventCoordinator.Subscribe<UIWindowStateChangedEvent>(OnWindowStateChanged);
|
||||
_eventCoordinator.Subscribe<ToggleToolScreenEvent>(OnToolScreenStateChanged);
|
||||
_eventCoordinator.Subscribe<UIStackChangedEvent>(OnUIStackChanged);
|
||||
|
||||
@@ -422,9 +423,10 @@ namespace BriarQueen.Framework.Managers.Input
|
||||
_hudHidden = !evt.Show;
|
||||
}
|
||||
|
||||
private void OnCodexStateChanged(ToggleCodexEvent evt)
|
||||
private void OnWindowStateChanged(UIWindowStateChangedEvent evt)
|
||||
{
|
||||
_codexShown = evt.Shown;
|
||||
if (evt.WindowType == WindowType.CodexWindow)
|
||||
_codexShown = evt.IsOpen;
|
||||
}
|
||||
|
||||
private void OnToolScreenStateChanged(ToggleToolScreenEvent evt)
|
||||
@@ -461,8 +463,8 @@ namespace BriarQueen.Framework.Managers.Input
|
||||
{
|
||||
if(_gameService.IsMainMenuSceneLoaded)
|
||||
return;
|
||||
_codexShown = !_codexShown;
|
||||
_eventCoordinator?.Publish(new ToggleCodexEvent(_codexShown));
|
||||
|
||||
_eventCoordinator?.Publish(new ToggleCodexEvent(!_codexShown));
|
||||
}
|
||||
|
||||
private void OnClick(InputAction.CallbackContext ctx)
|
||||
|
||||
@@ -323,7 +323,7 @@ namespace BriarQueen.Framework.Managers.Interaction
|
||||
|
||||
if (candidate.sortingOrder != currentBest.sortingOrder)
|
||||
return candidate.sortingOrder > currentBest.sortingOrder;
|
||||
|
||||
|
||||
if (candidate.depth != currentBest.depth)
|
||||
return candidate.depth > currentBest.depth;
|
||||
|
||||
|
||||
10
Assets/Scripts/Framework/Managers/UI/Base/IUIOverlayHost.cs
Normal file
10
Assets/Scripts/Framework/Managers/UI/Base/IUIOverlayHost.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Base
|
||||
{
|
||||
public interface IUIOverlayHost
|
||||
{
|
||||
UniTask SuspendForOverlay();
|
||||
UniTask ResumeFromOverlay();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4424bf26f2b764c1ca63bc73d75470d6
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace BriarQueen.Framework.Managers.UI.Events
|
||||
{
|
||||
public enum SettingsOpenSource
|
||||
{
|
||||
Unknown,
|
||||
PauseMenu,
|
||||
MainMenu
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed020edca638d4f1cbdf9b3468316efa
|
||||
@@ -2,5 +2,5 @@ using BriarQueen.Framework.Events.System;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Events
|
||||
{
|
||||
public record UIToggleSettingsWindow(bool Show) : IEvent;
|
||||
}
|
||||
public record UIToggleSettingsWindow(bool Show, SettingsOpenSource Source = SettingsOpenSource.Unknown) : IEvent;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
@@ -34,6 +35,7 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
private readonly Dictionary<WindowType, IUIWindow> _windows = new();
|
||||
private readonly Stack<IUIWindow> _windowStack = new();
|
||||
private readonly SemaphoreSlim _windowTransitionGate = new(1, 1);
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
@@ -43,6 +45,8 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
private IPopup _infoPopup;
|
||||
private IPopup _tutorialPopup;
|
||||
private IScreenFader _screenFader;
|
||||
private IUIOverlayHost _mainMenuOverlayHost;
|
||||
private IUIOverlayHost _activeSettingsOverlayHost;
|
||||
|
||||
[Inject]
|
||||
public UIManager(
|
||||
@@ -155,11 +159,33 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
_screenFader = screenFader;
|
||||
}
|
||||
|
||||
public void RegisterMainMenuOverlayHost(IUIOverlayHost host)
|
||||
{
|
||||
_mainMenuOverlayHost = host;
|
||||
}
|
||||
|
||||
public void UnregisterMainMenuOverlayHost(IUIOverlayHost host)
|
||||
{
|
||||
if (!ReferenceEquals(_mainMenuOverlayHost, host))
|
||||
return;
|
||||
|
||||
if (ReferenceEquals(_activeSettingsOverlayHost, host))
|
||||
_activeSettingsOverlayHost = null;
|
||||
|
||||
_mainMenuOverlayHost = null;
|
||||
}
|
||||
|
||||
private IUIWindow GetWindow(WindowType windowType)
|
||||
{
|
||||
return _windows.TryGetValue(windowType, out var window) ? window : null;
|
||||
}
|
||||
|
||||
public bool IsWindowOpen(WindowType windowType)
|
||||
{
|
||||
var target = GetWindow(windowType);
|
||||
return target != null && _windowStack.Contains(target);
|
||||
}
|
||||
|
||||
private async UniTask ApplyHudVisibility(bool visible)
|
||||
{
|
||||
if (_disposed || _hudContainer == null)
|
||||
@@ -197,7 +223,7 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
private void ToggleSettingsWindow(UIToggleSettingsWindow eventData)
|
||||
{
|
||||
if (eventData.Show)
|
||||
OpenWindow(WindowType.SettingsWindow);
|
||||
OpenSettingsWindow(eventData.Source).Forget();
|
||||
else
|
||||
CloseWindow(WindowType.SettingsWindow);
|
||||
}
|
||||
@@ -208,9 +234,15 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
return;
|
||||
|
||||
if (eventData.Shown)
|
||||
OpenWindow(WindowType.CodexWindow);
|
||||
{
|
||||
if (!IsWindowOpen(WindowType.CodexWindow))
|
||||
OpenWindow(WindowType.CodexWindow);
|
||||
}
|
||||
else
|
||||
CloseWindow(WindowType.CodexWindow);
|
||||
{
|
||||
if (IsWindowOpen(WindowType.CodexWindow))
|
||||
CloseWindow(WindowType.CodexWindow);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCodexChangedEvent(CodexChangedEvent eventData)
|
||||
@@ -300,32 +332,94 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
OpenWindowInternal(windowType).Forget();
|
||||
}
|
||||
|
||||
private async UniTask OpenSettingsWindow(SettingsOpenSource source)
|
||||
{
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
var window = GetWindow(WindowType.SettingsWindow);
|
||||
if (window == null)
|
||||
{
|
||||
Debug.LogError("[UIManager] Window of type SettingsWindow not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_windowStack.Contains(window))
|
||||
return;
|
||||
|
||||
_activeSettingsOverlayHost = null;
|
||||
|
||||
var openingSettingsOverPause =
|
||||
source == SettingsOpenSource.PauseMenu &&
|
||||
ActiveWindow?.WindowType == WindowType.PauseMenuWindow &&
|
||||
ActiveWindow is IUIOverlayHost;
|
||||
|
||||
var openingSettingsOverMainMenu =
|
||||
source == SettingsOpenSource.MainMenu &&
|
||||
_mainMenuOverlayHost != null;
|
||||
|
||||
if (openingSettingsOverPause)
|
||||
{
|
||||
_activeSettingsOverlayHost = (IUIOverlayHost)ActiveWindow;
|
||||
await _activeSettingsOverlayHost.SuspendForOverlay();
|
||||
}
|
||||
else if (openingSettingsOverMainMenu)
|
||||
{
|
||||
_activeSettingsOverlayHost = _mainMenuOverlayHost;
|
||||
await _activeSettingsOverlayHost.SuspendForOverlay();
|
||||
}
|
||||
else if (ActiveWindow != null)
|
||||
{
|
||||
await ActiveWindow.Hide();
|
||||
}
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyWindowStateChanged(window.WindowType, true);
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask OpenWindowInternal(WindowType windowType)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
var window = GetWindow(windowType);
|
||||
|
||||
if (window == null)
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
Debug.LogError($"[UIManager] Window of type {windowType} not registered.");
|
||||
return;
|
||||
}
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (ActiveWindow == window)
|
||||
return;
|
||||
|
||||
if (ActiveWindow != null)
|
||||
{
|
||||
var window = GetWindow(windowType);
|
||||
|
||||
await ActiveWindow.Hide();
|
||||
if (window == null)
|
||||
{
|
||||
Debug.LogError($"[UIManager] Window of type {windowType} not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_windowStack.Contains(window))
|
||||
return;
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Hide();
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyWindowStateChanged(window.WindowType, true);
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void CloseWindow(WindowType windowType)
|
||||
@@ -335,27 +429,45 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
private async UniTask CloseWindowInternal(WindowType windowType)
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
var target = GetWindow(windowType);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
while (_windowStack.Count > 0)
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
var current = _windowStack.Pop();
|
||||
if (current != null)
|
||||
await current.Hide();
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
if (current == target)
|
||||
break;
|
||||
var target = GetWindow(windowType);
|
||||
if (target == null || !_windowStack.Contains(target))
|
||||
return;
|
||||
|
||||
while (_windowStack.Count > 0)
|
||||
{
|
||||
var current = _windowStack.Pop();
|
||||
if (current != null)
|
||||
{
|
||||
await current.Hide();
|
||||
NotifyWindowStateChanged(current.WindowType, false);
|
||||
}
|
||||
|
||||
if (current == target)
|
||||
break;
|
||||
}
|
||||
|
||||
if (target.WindowType == WindowType.SettingsWindow && _activeSettingsOverlayHost != null)
|
||||
{
|
||||
await _activeSettingsOverlayHost.ResumeFromOverlay();
|
||||
_activeSettingsOverlayHost = null;
|
||||
}
|
||||
else if (ActiveWindow != null)
|
||||
{
|
||||
await ActiveWindow.Show();
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void CloseTopWindow()
|
||||
@@ -380,18 +492,38 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
private async UniTask CloseTopWindowInternal()
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
var top = _windowStack.Pop();
|
||||
var top = _windowStack.Pop();
|
||||
|
||||
if (top != null)
|
||||
await top.Hide();
|
||||
if (top != null)
|
||||
{
|
||||
await top.Hide();
|
||||
NotifyWindowStateChanged(top.WindowType, false);
|
||||
}
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Show();
|
||||
if (top != null &&
|
||||
top.WindowType == WindowType.SettingsWindow &&
|
||||
_activeSettingsOverlayHost != null)
|
||||
{
|
||||
await _activeSettingsOverlayHost.ResumeFromOverlay();
|
||||
_activeSettingsOverlayHost = null;
|
||||
}
|
||||
else if (ActiveWindow != null)
|
||||
{
|
||||
await ActiveWindow.Show();
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetUIState()
|
||||
@@ -401,44 +533,71 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
|
||||
public async UniTask ResetUIStateAsync()
|
||||
{
|
||||
while (_windowStack.Count > 0)
|
||||
await _windowTransitionGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
var window = _windowStack.Pop();
|
||||
if (window != null)
|
||||
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();
|
||||
NotifyWindowStateChanged(window.WindowType, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tutorialPopup != null)
|
||||
if (shouldResumeSettingsHost)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _activeSettingsOverlayHost.ResumeFromOverlay();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
_activeSettingsOverlayHost = null;
|
||||
|
||||
if (_tutorialPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tutorialPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (_infoPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _infoPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tutorialPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_windowTransitionGate.Release();
|
||||
}
|
||||
|
||||
if (_infoPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _infoPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
private void ResetUIStateHard()
|
||||
@@ -462,11 +621,18 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
faderComponent.gameObject.SetActive(false);
|
||||
|
||||
_windowStack.Clear();
|
||||
_activeSettingsOverlayHost = null;
|
||||
_mainMenuOverlayHost = null;
|
||||
}
|
||||
|
||||
private void NotifyUIStackChanged()
|
||||
{
|
||||
_eventCoordinator.Publish(new UIStackChangedEvent(_windowStack.Count > 0));
|
||||
}
|
||||
|
||||
private void NotifyWindowStateChanged(WindowType windowType, bool isOpen)
|
||||
{
|
||||
_eventCoordinator.Publish(new UIWindowStateChangedEvent(windowType, isOpen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user