Compare commits

..

1 Commits

Author SHA1 Message Date
7c4c98ede8 Working popups 2025-10-06 17:31:41 +02:00
24 changed files with 498 additions and 297 deletions

45
Debug.cs Normal file
View File

@ -0,0 +1,45 @@

using System;
using System.Diagnostics;
using Object = UnityEngine.Object;
namespace NegUtils
{
public static class Debug
{
private const string LogDefine = "LOG_INFO";
private const string WarningDefine = "LOG_WARNING";
private const string ErrorDefine = "LOG_ERRORS";
private const string AssertDefine = "UNITY_ASSERTIONS";
private const string Editor = "UNITY_EDITOR";
[Conditional(LogDefine), Conditional(Editor)]
public static void Log(object message) => UnityEngine.Debug.Log(message);
[Conditional(LogDefine), Conditional(Editor)]
public static void Log(object message, Object context) => UnityEngine.Debug.Log(message, context);
[Conditional(WarningDefine), Conditional(Editor)]
public static void LogWarning(object message) => UnityEngine.Debug.LogWarning(message);
[Conditional(WarningDefine), Conditional(Editor)]
public static void LogWarning(object message, Object context) => UnityEngine.Debug.LogWarning(message, context);
[Conditional(ErrorDefine), Conditional(Editor)]
public static void LogError(object message) => UnityEngine.Debug.LogError(message);
[Conditional(ErrorDefine), Conditional(Editor)]
public static void LogError(object message, Object context) => UnityEngine.Debug.LogError(message, context);
public static void LogException(Exception e) => UnityEngine.Debug.LogException(e);
[Conditional(AssertDefine)]
public static void Assert(bool state) => UnityEngine.Debug.Assert(state);
[Conditional(AssertDefine)]
public static void Assert(bool state, Object context) => UnityEngine.Debug.Assert(state, context);
[Conditional(AssertDefine)]
public static void Assert(bool state, object message) => UnityEngine.Debug.Assert(state, message);
[Conditional(AssertDefine)]
public static void Assert(bool state, object message, Object context) => UnityEngine.Debug.Assert(state, message, context);
}
}

3
Debug.cs.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: df1918e04df74ff8bc0e5aef1fce3437
timeCreated: 1752327272

11
NEG/UI/Abstraction.cs Normal file
View File

@ -0,0 +1,11 @@
using NEG.UI.Popup;
namespace NegUtils.NEG.UI;
internal interface IPopupsHandler
{
internal static IPopupsHandler Instance => instance;
protected static IPopupsHandler instance;
void RefreshPopups();
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d28e117dd3d544a18cf1654c71e5bb00
timeCreated: 1759328259

View File

@ -5,25 +5,14 @@ namespace NEG.UI.Popup
{
public class DefaultPopupData : PopupData
{
private readonly string content;
private readonly IDefaultPopup defaultPopup;
private readonly List<(string, Action)> options;
public string Title;
public string Content;
public readonly List<(string, Action)> Options = new(5);
private readonly string title;
public DefaultPopupData(IDefaultPopup popup, string title, string content, List<(string, Action)> options) :
base(popup)
public override void OnRelease()
{
defaultPopup = popup;
this.title = title;
this.content = content;
this.options = options;
}
public override void Show()
{
defaultPopup.SetContent(title, content, options);
base.Show();
base.OnRelease();
Options.Clear();
}
}
}

View File

@ -1,54 +1,79 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using NEG.Utils;
using NegUtils;
using NegUtils.NEG.UI;
namespace NEG.UI.Popup
{
[PublicAPI]
public class PopupData
public struct PopupDataHook
{
private readonly IPopup popup;
private uint version;
private PopupData data;
/// <summary>
/// PopupData constructor.
/// </summary>
/// <param name="popup">attached to this data, can be used by different data instances</param>
public PopupData(IPopup popup)
public bool IsValid => version == data.CurrentVersion;
public PopupDataHook(PopupData data)
{
this.popup = popup;
IsValid = true;
this.data = data;
version = data.CurrentVersion;
}
public void Invalidate()
{
if (!IsValid)
return;
data.Dispose();
}
}
[PublicAPI]
public class PopupData : IPoolable
{
private static readonly Dictionary<Type, Action<PopupData>> ReturnDelegates = new();
/// <summary>
/// Is this data is still valid. If set to false, popup will not show.
/// Is this data is still valid. If set to false, popup will not show.
/// </summary>
public bool IsValid { get; protected set; }
/// <summary>
/// Event that is fired on closing popup.
/// </summary>
public event Action<PopupData> PopupClosedEvent
{
add => popup.OnPopupClosed += value;
remove => popup.OnPopupClosed -= value;
}
internal uint CurrentVersion { get; private set; }
/// <summary>
/// Show popup and pass needed data.
/// </summary>
public virtual void Show() => popup.Show(this);
/// <summary>
/// Hide popup. Close visuals without firing events;
/// </summary>
public virtual void Hide() => popup.Close(true);
/// <summary>
/// Invalidate popup, <see cref="UiManager" /> will automatically skip this popup
/// </summary>
public virtual void Invalidate()
internal void Dispose()
{
IsValid = false;
UiManager.Instance.RefreshPopups();
IPopupsHandler.Instance.RefreshPopups();
var type = GetType();
if (!ReturnDelegates.TryGetValue(GetType(), out var returnDelegate))
ReturnDelegates[type] = CreateReturnDelegate(type);
returnDelegate?.Invoke(this);
}
private static Action<PopupData> CreateReturnDelegate(Type type)
{
var returnMethod = typeof(NativePool<>)
.MakeGenericType(type)
.GetMethod(nameof(NativePool<PopupData>.Return), new[] { type });
return (Action<PopupData>)Delegate.CreateDelegate(
typeof(Action<PopupData>),
returnMethod);
}
public virtual void OnGet()
{
IsValid = true;
}
public virtual void OnRelease()
{
CurrentVersion++;
}
}
}

View File

@ -6,39 +6,17 @@ using NegUtils.NEG.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System.Runtime.CompilerServices;
using NegUtils;
using UnityEngine.Pool;
using Debug = UnityEngine.Debug;
namespace NEG.UI
{
[PublicAPI]
public abstract class UiManager : IDisposable
public abstract class UiManager<TWindow, TPopup> : IDisposable, IPopupsHandler where TWindow : Enum where TPopup : Enum
{
private IArea currentArea;
protected IDefaultPopup currentDefaultPopup;
private (PopupData data, int priority) currentShownPopup;
//TODO: localize
private string localizedYes = "Yes", localizedNo = "No", localizedOk = "Ok";
private List<IWindow> mainWindows;
private PriorityQueue<PopupData, int> popupsToShow = new();
protected UiManager(IArea startArea)
{
if (Instance != null)
{
Debug.LogError("Only one instance od UiManager is allowed");
return;
}
Instance = this;
CurrentArea = startArea;
mainWindows = new List<IWindow>();
}
public static UiManager Instance { get; protected set; }
public static UiManager<TWindow, TPopup> Instance { get; protected set; }
/// <summary>
/// Current area shown on screen.
@ -59,38 +37,69 @@ namespace NEG.UI
/// <summary>
/// Current window that is considered main (focused, lastly opened). Can be null.
/// </summary>
public IWindow CurrentMainWindow => mainWindows.LastOrDefault();
// public IWindow CurrentMainWindow => mainWindows.LastOrDefault();
public PopupData CurrentPopup => currentShownPopup.data;
// public PopupData CurrentPopup => currentShownPopup.Data;
private IArea currentArea;
private PopupDataExtended currentShownPopupData;
private IPopup currentShownPopup;
private readonly List<PopupDataExtended> popupsToShow = new();
protected abstract string OkLocalizationKey { get; }
protected abstract string YesLocalizationKey { get; }
protected abstract string NoLocalizationKey { get; }
protected abstract TPopup DefaultPopup { get; }
protected UiManager(IArea startArea)
{
if (Instance != null)
{
Debug.LogError("Only one instance od UiManager is allowed");
return;
}
Instance = this;
IPopupsHandler.instance = this;
CurrentArea = startArea;
}
public virtual void Dispose() => Instance = null;
#region Popups
private Dictionary<TPopup, IPopup> registeredPopups = new();
/// <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="title">popup title key</param>
/// <param name="content">popup content key</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,
public PopupDataHook 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;
var data = NativePool<DefaultPopupData>.Get();
data.Title = title;
data.Content = content;
data.Options.Add((okText ?? OkLocalizationKey, okPressed));
return ShowPopup(DefaultPopup, data, priority, forceShow);
}
/// <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="title">popup title key</param>
/// <param name="content">popup content key</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>
@ -98,126 +107,186 @@ namespace NEG.UI
/// <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,
public PopupDataHook 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;
var data = NativePool<DefaultPopupData>.Get();
data.Title = title;
data.Content = content;
data.Options.Add((yesText ?? YesLocalizationKey, yesPressed));
data.Options.Add((noText ?? NoLocalizationKey, noPressed));
return ShowPopup(DefaultPopup, data, priority, forceShow);
}
/// <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="title">popup title key</param>
/// <param name="content">popup content key</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)
public PopupDataHook ShowPopup(string title, string content, ReadOnlySpan<(string, Action)> actions, int priority = 0, bool forceShow = false)
{
var data = new DefaultPopupData(currentDefaultPopup, title, content, actions);
ShowPopup(data, priority, forceShow);
return data;
var data = NativePool<DefaultPopupData>.Get();
data.Title = title;
data.Content = content;
foreach (var action in actions)
{
data.Options.Add(action);
}
return ShowPopup(DefaultPopup, data, priority, forceShow);
}
/// <summary>
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later.
/// </summary>
/// <param name="popupType">popup type to show</param>
/// <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)
public PopupDataHook ShowPopup(TPopup popupType, PopupData data, int priority = 0, bool forceShow = false)
{
popupsToShow.Enqueue(data, priority);
UpdatePopupsState(forceShow, priority, data);
var dataExtended = new PopupDataExtended(priority, popupType, data);
if (forceShow)
{
if (currentShownPopupData.Data != null && currentShownPopupData.Priority >= priority)
{
EnqueuePopup(dataExtended);
return new PopupDataHook(data);
}
if (currentShownPopupData.Data != null)
EnqueuePopup(currentShownPopupData, false);
ShowPopup(dataExtended);
return new PopupDataHook(data);
}
popupsToShow.Add(dataExtended);
RefreshPopups();
return new PopupDataHook(data);
}
public void RegisterPopup(TPopup popupType, IPopup popup)
{
registeredPopups.Add(popupType, popup);
}
public void RefreshPopups()
{
for (int i = popupsToShow.Count - 1; i >= 0; i--)
{
if(!popupsToShow[i].Data.IsValid)
popupsToShow.RemoveAt(i);
}
if(currentShownPopupData.Data?.IsValid == true)
return;
ClosePopupSilently();
if (popupsToShow.Count == 0)
return;
var data = popupsToShow[0];
popupsToShow.RemoveAt(0);
ShowPopup(data);
}
private void ShowPopup(PopupDataExtended data)
{
if (currentShownPopup != null)
ClosePopupSilently();
if (!registeredPopups.TryGetValue(data.PopupType, out var popup))
{
Debug.LogError($"Popup {data.PopupType} does not exist");
data.Data.Dispose();
return;
}
popup.Show(data.Data);
currentShownPopup = popup;
currentShownPopupData = data;
}
private void ClosePopupSilently()
{
currentShownPopup?.Close(true);
currentShownPopupData = default;
currentShownPopup = null;
}
private void EnqueuePopup(PopupDataExtended data, bool asLast = true)
{
for (int i = 0; i < popupsToShow.Count; i++)
{
var popup = popupsToShow[i];
if(popup.Priority > data.Priority || (asLast && popup.Priority == data.Priority))
continue;
popupsToShow.Insert(i, data);
return;
}
popupsToShow.Add(data);
}
private readonly struct PopupDataExtended
{
public readonly int Priority;
public readonly TPopup PopupType;
public readonly PopupData Data;
public PopupDataExtended(int priority, TPopup popupType, PopupData data)
{
Priority = priority;
PopupType = popupType;
Data = data;
}
}
#endregion
public void UseBack()
{
//Remove this ugly alocation
IControllable.BackUsed backUsed = new();
CurrentMainWindow?.TryUseBack(ref backUsed);
if (backUsed.Used)
//CurrentMainWindow?.TryUseBack(ref backUsed);
if(backUsed.Used)
return;
CurrentArea.TryUseBack(ref backUsed);
}
#region Windows
private Dictionary<TWindow, IWindow> registeredWindows = new();
public void RefreshPopups()
{
if (currentShownPopup.data is { IsValid: true })
return;
UpdatePopupsState(false);
}
#endregion
public void SetMainWindow(IWindow window) => mainWindows.Add(window);
// public void SetMainWindow(IWindow window) => mainWindows.Add(window);
//
// public void MainWindowClosed(IWindow window) => mainWindows.Remove(window);
//
// public void OnWindowClosed(IWindow window) => MainWindowClosed(window);
public void MainWindowClosed(IWindow window) => mainWindows.Remove(window);
// //TODO: select new main window
// protected void PopupClosed(PopupData data)
// {
// if (currentShownPopup.data != data)
// {
// //Debug.LogError("Popup was not shown");
// return;
// }
// UpdatePopupsState(false);
// }
public void OnWindowClosed(IWindow window) => MainWindowClosed(window);
//TODO: select new main window
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;
protected virtual void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
{
if (forceShow)
{
if (currentShownPopup.data != null && 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 == null)
continue;
if (!d.IsValid)
continue;
if (d == currentShownPopup.data)
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;
}
}
}

View File

@ -10,8 +10,8 @@ namespace NEG.UI.Area
private void Start()
{
if (UiManager.Instance.CurrentMainWindow == null)
window.Open();
// if (UiManager.Instance.CurrentMainWindow == null)
// window.Open();
}
}
}

View File

@ -8,9 +8,9 @@ namespace NEG.UI.Area
{
protected override void OnBackUsed(IControllable.BackUsed backUsed)
{
base.OnBackUsed(backUsed);
UiManager.Instance.CurrentMainWindow?.Close();
backUsed.Used = true;
// base.OnBackUsed(backUsed);
// UiManager.Instance.CurrentMainWindow?.Close();
// backUsed.Used = true;
}
}
}

View File

@ -17,8 +17,8 @@ namespace NEG.UI.Area
protected virtual void Awake()
{
if (setAsDefaultArea)
UiManager.Instance.CurrentArea = this;
// if (setAsDefaultArea)
// UiManager.Instance.CurrentArea = this;
}
private void Start()
@ -29,10 +29,10 @@ namespace NEG.UI.Area
private void OnDestroy()
{
if (UiManager.Instance == null)
return;
if (ReferenceEquals(UiManager.Instance.CurrentArea, this))
UiManager.Instance.CurrentArea = null;
// if (UiManager.Instance == null)
// return;
// if (ReferenceEquals(UiManager.Instance.CurrentArea, this))
// UiManager.Instance.CurrentArea = null;
}
public event Action<object> OnOpened;

View File

@ -34,11 +34,11 @@ namespace NEG.UI.UnityUi.Buttons
protected virtual void Awake()
{
button.onClick.AddListener(OnClicked);
if (groupButtonSettings == null)
MonoUiManager.Instance.DefaultUiSettings.Apply(this);
else
groupButtonSettings.Apply(this);
// button.onClick.AddListener(OnClicked);
// if (groupButtonSettings == null)
// MonoUiManager.Instance.DefaultUiSettings.Apply(this);
// else
// groupButtonSettings.Apply(this);
}
private void Start() => OnDeselect(null);
@ -74,13 +74,13 @@ namespace NEG.UI.UnityUi.Buttons
public void AddOrOverrideSetting(SettingData data)
{
if (behaviours.TryGetValue(data.Key, out var setting))
{
setting.ChangeData(data);
return;
}
behaviours.Add(data.Key, MonoUiManager.Instance.BehavioursFactory.CreateInstance(data.Key, this, data));
// if (behaviours.TryGetValue(data.Key, out var setting))
// {
// setting.ChangeData(data);
// return;
// }
//
// behaviours.Add(data.Key, MonoUiManager.Instance.BehavioursFactory.CreateInstance(data.Key, this, data));
}
public void RemoveSetting(string key)

View File

@ -30,10 +30,10 @@ namespace NEG.UI.UnityUi.Buttons.Behaviours
button.OnSelected -= OnButtonSelected;
button.OnDeselected -= OnButtonDeselected;
}
[FactoryRegistration]
private static void RegisterInFactory() =>
MonoUiManager.Instance.BehavioursFactory.Register("ChangeTextColor", typeof(ChangeTextColorBehaviour));
//
// [FactoryRegistration]
// private static void RegisterInFactory() =>
// MonoUiManager.Instance.BehavioursFactory.Register("ChangeTextColor", typeof(ChangeTextColorBehaviour));
private void OnButtonSelected(bool _) => button.Text.color = data.SelectedColor;
private void OnButtonDeselected(bool _) => button.Text.color = data.DeselectedColor;

View File

@ -2,6 +2,8 @@
{
public class CloseAllWindows : ButtonReaction
{
protected override void OnClicked() => UiManager.Instance.CurrentArea.CloseAllWindows();
//protected override void OnClicked() => UiManager.Instance.CurrentArea.CloseAllWindows();
protected override void OnClicked() {
}
}
}

View File

@ -8,6 +8,10 @@ namespace NEG.UI.UnityUi.Buttons.Reactions
{
[SerializeField] private MonoWindow windowToOpen;
protected override void OnClicked() => UiManager.Instance.CurrentMainWindow.OpenAsChild(windowToOpen);
// protected override void OnClicked() => UiManager.Instance.CurrentMainWindow.OpenAsChild(windowToOpen);
protected override void OnClicked()
{
throw new System.NotImplementedException();
}
}
}

View File

@ -21,12 +21,12 @@ namespace NEG.UI.UnityUi
{
public DefaultInputModule()
{
var defaultActions = new DefaultInputActions();
InputActionReference.Create(defaultActions.UI.Navigate).action.performed +=
ctx => OnSelectionChangeStarted();
InputActionReference.Create(defaultActions.UI.Cancel).action.performed +=
_ => UiManager.Instance.UseBack();
defaultActions.Enable();
// var defaultActions = new DefaultInputActions();
// InputActionReference.Create(defaultActions.UI.Navigate).action.performed +=
// ctx => OnSelectionChangeStarted();
// InputActionReference.Create(defaultActions.UI.Cancel).action.performed +=
// _ => UiManager.Instance.UseBack();
// defaultActions.Enable();
if (Gamepad.current != null)
SetDirectionInput();
@ -60,28 +60,28 @@ namespace NEG.UI.UnityUi
private void SetDirectionInput()
{
if (EventSystem.current == null || MonoUiManager.Instance == null) return;
CurrentSelectionSource = SelectionSource.Direction;
Cursor.visible = false;
if (EventSystem.current.currentSelectedGameObject == null &&
MonoUiManager.Instance.CurrentMainWindow != null)
{
EventSystem.current.SetSelectedGameObject(((MonoWindow)MonoUiManager.Instance.CurrentMainWindow)
.DefaultSelectedItem);
return;
}
var data = new PointerEventData(EventSystem.current);
var currentSelected = EventSystem.current.currentSelectedGameObject;
if (currentSelected != null)
{
for (var current = EventSystem.current.currentSelectedGameObject.transform;
current != null;
current = current.parent)
ExecuteEvents.Execute(current.gameObject, data, ExecuteEvents.pointerExitHandler);
}
EventSystem.current.SetSelectedGameObject(currentSelected);
// if (EventSystem.current == null || MonoUiManager.Instance == null) return;
// CurrentSelectionSource = SelectionSource.Direction;
// Cursor.visible = false;
// if (EventSystem.current.currentSelectedGameObject == null &&
// MonoUiManager.Instance.CurrentMainWindow != null)
// {
// EventSystem.current.SetSelectedGameObject(((MonoWindow)MonoUiManager.Instance.CurrentMainWindow)
// .DefaultSelectedItem);
// return;
// }
//
// var data = new PointerEventData(EventSystem.current);
// var currentSelected = EventSystem.current.currentSelectedGameObject;
// if (currentSelected != null)
// {
// for (var current = EventSystem.current.currentSelectedGameObject.transform;
// current != null;
// current = current.parent)
// ExecuteEvents.Execute(current.gameObject, data, ExecuteEvents.pointerExitHandler);
// }
//
// EventSystem.current.SetSelectedGameObject(currentSelected);
}
private void SetPointerInput()

View File

@ -24,7 +24,7 @@ namespace NEG.UI.UnityUi
/// </para>
/// NEG_UI_DISABLE_WARNING_DEFAULT_SELECTION
/// </summary>
public class MonoUiManager : UiManager, IDisposable
public abstract class MonoUiManager<TWindow, TPopup> : UiManager<TWindow, TPopup>, IDisposable where TWindow : Enum where TPopup : Enum
{
private readonly GameObject canvasPrefab;
@ -51,9 +51,9 @@ namespace NEG.UI.UnityUi
canvasPrefab = popupCanvas;
defaultPopupPrefab = defaultPopup.GetComponent<MonoDefaultPopup>();
SpawnDefaultPopup();
SceneManager.activeSceneChanged += (_, _) => SpawnDefaultPopup();
// SpawnDefaultPopup();
//
// SceneManager.activeSceneChanged += (_, _) => SpawnDefaultPopup();
BehavioursFactory = new KeyBasedFactory<string, ButtonElementBehaviour>();
BehavioursFactory.FireRegistration();
@ -64,7 +64,7 @@ namespace NEG.UI.UnityUi
//TODO: use default unity selection
//TODO: window snaping to slots
public static new MonoUiManager Instance { get; private set; }
//public static new MonoUiManager<T, T1, T2> Instance { get; private set; }
public ButtonSettings DefaultUiSettings { get; }
public KeyBasedFactory<string, ButtonElementBehaviour> BehavioursFactory { get; }
@ -75,27 +75,27 @@ namespace NEG.UI.UnityUi
Instance = null;
}
protected override void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
{
base.UpdatePopupsState(forceShow, priority, data);
if (inputModule.CurrentSelectionSource != SelectionSource.Direction)
return;
// protected override void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
// {
// base.UpdatePopupsState(forceShow, priority, data);
// if (inputModule.CurrentSelectionSource != SelectionSource.Direction)
// return;
//
// if (CurrentPopup == null && (EventSystem.current.currentSelectedGameObject == null ||
// !EventSystem.current.currentSelectedGameObject.activeInHierarchy))
// {
// if (((MonoWindow)CurrentMainWindow).DefaultSelectedItem == null)
// return;
// EventSystem.current.SetSelectedGameObject(((MonoWindow)CurrentMainWindow).DefaultSelectedItem);
// }
// }
if (CurrentPopup == null && (EventSystem.current.currentSelectedGameObject == null ||
!EventSystem.current.currentSelectedGameObject.activeInHierarchy))
{
if (((MonoWindow)CurrentMainWindow).DefaultSelectedItem == null)
return;
EventSystem.current.SetSelectedGameObject(((MonoWindow)CurrentMainWindow).DefaultSelectedItem);
}
}
private void SpawnDefaultPopup()
{
var canvas = Object.Instantiate(canvasPrefab);
canvas.name = "DefaultPopupCanvas";
SetDefaultPopup(Object.Instantiate(defaultPopupPrefab, canvas.transform));
currentDefaultPopup.Close(true);
}
// private void SpawnDefaultPopup()
// {
// var canvas = Object.Instantiate(canvasPrefab);
// canvas.name = "DefaultPopupCanvas";
// SetDefaultPopup(Object.Instantiate(defaultPopupPrefab, canvas.transform));
// currentDefaultPopup.Close(true);
// }
}
}

View File

@ -27,10 +27,10 @@ namespace NEG.UI.UnityUi.Window
private void OnDestroy()
{
if (UiManager.Instance == null)
return;
if (IsOpened)
UiManager.Instance.OnWindowClosed(this);
// if (UiManager.Instance == null)
// return;
// if (IsOpened)
// UiManager.Instance.OnWindowClosed(this);
}
private void OnValidate()
@ -50,23 +50,23 @@ namespace NEG.UI.UnityUi.Window
public void SetOpenedState(IWindowSlot parentSlot, object data)
{
gameObject.SetActive(true);
IsOpened = true;
Parent = parentSlot;
EventSystem.current.SetSelectedGameObject(defaultSelectedItem);
if (parentSlot.OpenWindowAsMain)
UiManager.Instance.SetMainWindow(this);
OnOpened?.Invoke(data);
// gameObject.SetActive(true);
// IsOpened = true;
// Parent = parentSlot;
// EventSystem.current.SetSelectedGameObject(defaultSelectedItem);
// if (parentSlot.OpenWindowAsMain)
// UiManager.Instance.SetMainWindow(this);
// OnOpened?.Invoke(data);
}
public void SetClosedState()
{
gameObject.SetActive(false);
IsOpened = false;
Parent = null;
((ISlotsHolder)this).CloseAllWindows();
UiManager.Instance.OnWindowClosed(this);
OnClosed?.Invoke();
// gameObject.SetActive(false);
// IsOpened = false;
// Parent = null;
// ((ISlotsHolder)this).CloseAllWindows();
// UiManager.Instance.OnWindowClosed(this);
// OnClosed?.Invoke();
}
public void SetHiddenState() => gameObject.SetActive(false);

View File

@ -25,9 +25,9 @@ namespace NEG.UI.WindowSlot
public override void DetachWindow(IWindow window)
{
if (UiManager.Instance.CurrentMainWindow == window)
UiManager.Instance.MainWindowClosed(window);
CurrentWindow = null;
// if (UiManager.Instance.CurrentMainWindow == window)
// UiManager.Instance.MainWindowClosed(window);
// CurrentWindow = null;
}
public override void CloseAllWindows() => CurrentWindow = null;

View File

@ -38,16 +38,16 @@ namespace NegUtils.NEG.UI.UnityUi.WindowSlot
public override void DetachWindow(IWindow window)
{
if (window == null)
return;
window.SetClosedState();
windowsHistory.Remove(window);
if (window != currentWindow || windowsHistory.Count == 0) return;
currentWindow = windowsHistory[^1];
currentWindow.SeVisibleState();
if (UiManager.Instance.CurrentMainWindow == window)
UiManager.Instance.MainWindowClosed(window);
EventSystem.current.SetSelectedGameObject(((MonoWindow)currentWindow).DefaultSelectedItem);
// if (window == null)
// return;
// window.SetClosedState();
// windowsHistory.Remove(window);
// if (window != currentWindow || windowsHistory.Count == 0) return;
// currentWindow = windowsHistory[^1];
// currentWindow.SeVisibleState();
// if (UiManager.Instance.CurrentMainWindow == window)
// UiManager.Instance.MainWindowClosed(window);
// EventSystem.current.SetSelectedGameObject(((MonoWindow)currentWindow).DefaultSelectedItem);
}
public override void CloseAllWindows()

View File

@ -51,7 +51,7 @@ namespace NEG.UI.Window
return;
}
UiManager.Instance.CurrentArea.OpenWindow(window, data);
//UiManager.Instance.CurrentArea.OpenWindow(window, data);
}
/// <summary>
@ -94,13 +94,13 @@ namespace NEG.UI.Window
return;
}
if (UiManager.Instance.CurrentMainWindow != null)
{
UiManager.Instance.CurrentMainWindow.OpenWindow(window, data);
return;
}
UiManager.Instance.CurrentArea.OpenWindow(window, data);
// if (UiManager.Instance.CurrentMainWindow != null)
// {
// UiManager.Instance.CurrentMainWindow.OpenWindow(window, data);
// return;
// }
//
// UiManager.Instance.CurrentArea.OpenWindow(window, data);
}
/// <summary>

47
NativePool.cs Normal file
View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using UnityEngine.Assertions;
namespace NegUtils;
public interface NativePool<T> where T : class, IPoolable
{
private static readonly List<T> Instances = new(10);
public static T Get()
{
T item;
if (Instances.Count == 0)
item = Activator.CreateInstance<T>();
else
{
item = Instances[^1];
Instances.RemoveAt(Instances.Count - 1);
}
item.OnGet();
return item;
}
public static void Return(T obj)
{
Assert.IsNotNull(obj);
obj.OnRelease();
if(Instances.Count >= Capacity)
return;
Instances.Add(obj);
}
public static int Capacity
{
get => Instances.Count;
set => Instances.Capacity = value;
}
}
public interface IPoolable
{
void OnGet();
void OnRelease();
}

3
NativePool.cs.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 924ee76ac4a34cd6b60b4d9b93ff0ee5
timeCreated: 1757278537