diff --git a/NEG/UI/Area/IArea.cs b/NEG/UI/Area/IArea.cs index 2c7df06..e9942f9 100644 --- a/NEG/UI/Area/IArea.cs +++ b/NEG/UI/Area/IArea.cs @@ -7,6 +7,11 @@ namespace NEG.UI.Area { public interface IArea : ISlotsHolder, IUiElement { + /// + /// Open window as child of + /// + /// + /// void OpenChildWindow(IWindow window, object data = null); } } \ No newline at end of file diff --git a/NEG/UI/Popup/IPopup.cs b/NEG/UI/Popup/IPopup.cs index 246272a..7d33066 100644 --- a/NEG/UI/Popup/IPopup.cs +++ b/NEG/UI/Popup/IPopup.cs @@ -7,16 +7,21 @@ namespace NEG.UI.Popup [PublicAPI] public interface IPopup { + /// + /// Event to fire when popup is closed + /// + event Action OnPopupClosed; + /// /// Show popup /// /// data assigned to popup, used to give info that popup is closed - void Show(PopupData data); + public void Show(PopupData data); /// /// Close popup or mark as closed if not visible /// - /// if true hide visually, without firing callbacks + /// if true hide visually, without firing callbacks to properly close void Close(bool silence = false); } } \ No newline at end of file diff --git a/NEG/UI/Popup/PopupData.cs b/NEG/UI/Popup/PopupData.cs index cd8bd24..a936b2a 100644 --- a/NEG/UI/Popup/PopupData.cs +++ b/NEG/UI/Popup/PopupData.cs @@ -1,7 +1,15 @@ -namespace NEG.UI.Popup +using System; + +namespace NEG.UI.Popup { public class PopupData { + public event Action PopupClosedEvent + { + add => popup.OnPopupClosed += value; + remove => popup.OnPopupClosed -= value; + } + public bool IsValid { get; protected set; } private IPopup popup; diff --git a/NEG/UI/UiManager.cs b/NEG/UI/UiManager.cs index 1fdac69..028a212 100644 --- a/NEG/UI/UiManager.cs +++ b/NEG/UI/UiManager.cs @@ -1,19 +1,21 @@ +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 { - //TODO: use default unity selection - //TODO: window snaping to slots - //TODO: Default prefabs? - public static UiManager Instance { get; private set; } - + + /// + /// Current area shown on screen. + /// public IArea CurrentArea { get => currentArea; @@ -26,10 +28,15 @@ namespace NEG.UI currentArea?.SetEnabled(true); } } + + /// + /// Current window that is considered main (focused, lastly opened). Can be null. + /// + public IWindow CurrentMainWindow { get; protected set; } private IArea currentArea; - protected IDefaultPopup currentDefaultPopup; private (PopupData data, int priority) currentShownPopup; + protected IDefaultPopup currentDefaultPopup; private PriorityQueue popupsToShow = new(); @@ -114,8 +121,8 @@ namespace NEG.UI popupsToShow.Enqueue(data, priority); UpdatePopupsState(forceShow, priority, data); } - - public void PopupClosed(PopupData data) + + protected void PopupClosed(PopupData data) { if (currentShownPopup.data != data) { @@ -124,7 +131,7 @@ namespace NEG.UI } UpdatePopupsState(false); } - + protected void SetDefaultPopup(IDefaultPopup popup) => currentDefaultPopup = popup; private void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null) @@ -147,8 +154,14 @@ namespace NEG.UI 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; } } } diff --git a/NEG/UI/UnityUi/Area/MonoArea.cs b/NEG/UI/UnityUi/Area/MonoArea.cs index 1baa112..77b2166 100644 --- a/NEG/UI/UnityUi/Area/MonoArea.cs +++ b/NEG/UI/UnityUi/Area/MonoArea.cs @@ -13,12 +13,12 @@ namespace NEG.UI.Area { public IEnumerable AvailableSlots => windowSlots; public IWindowSlot DefaultWindowSlot => windowSlots[0]; - + [SerializeField] private bool setAsDefaultArea; [SerializeField] private List windowSlots; - [SerializeField] private Queue currentPopups = new(); + private Queue currentPopups = new(); public virtual void SetEnabled(bool setEnabled) => gameObject.SetActive(setEnabled); diff --git a/NEG/UI/UnityUi/MonoUiManager.cs b/NEG/UI/UnityUi/MonoUiManager.cs index e74d6e8..6c26ed0 100644 --- a/NEG/UI/UnityUi/MonoUiManager.cs +++ b/NEG/UI/UnityUi/MonoUiManager.cs @@ -17,6 +17,9 @@ namespace NEG.UI.UnityUi /// public class MonoUiManager : UiManager { + //TODO: use default unity selection + //TODO: window snaping to slots + private readonly MonoDefaultPopup defaultPopupPrefab; private readonly GameObject canvasPrefab; diff --git a/NEG/UI/UnityUi/Popup/MonoPopup.cs b/NEG/UI/UnityUi/Popup/MonoPopup.cs index 5d4f9eb..425edfb 100644 --- a/NEG/UI/UnityUi/Popup/MonoPopup.cs +++ b/NEG/UI/UnityUi/Popup/MonoPopup.cs @@ -6,6 +6,8 @@ namespace NEG.UI.UnityUi.Popup { public class MonoPopup : MonoBehaviour, IPopup { + public event Action OnPopupClosed; + protected PopupData data; public void Show(PopupData data) @@ -21,7 +23,7 @@ namespace NEG.UI.UnityUi.Popup if(silence) return; - UiManager.Instance.PopupClosed(data); + OnPopupClosed?.Invoke(data); } } diff --git a/NEG/UI/UnityUi/Window/MonoWindow.cs b/NEG/UI/UnityUi/Window/MonoWindow.cs index 95db2a4..d13a121 100644 --- a/NEG/UI/UnityUi/Window/MonoWindow.cs +++ b/NEG/UI/UnityUi/Window/MonoWindow.cs @@ -1,4 +1,5 @@ using NEG.UI.Area; +using NEG.UI.UnityUi.Buttons; using NEG.UI.UnityUi.WindowSlot; using NEG.UI.Window; using NEG.UI.WindowSlot; @@ -10,13 +11,17 @@ namespace NEG.UI.UnityUi.Window { public class MonoWindow : MonoBehaviour, IWindow { + public IEnumerable AvailableSlots => windowSlots; public IWindowSlot Parent { get; private set; } - public IWindowSlot ChildWindowSlot => childWindowArea; - [SerializeField] private MonoWindowSlot childWindowArea; + public bool IsMainWindow { get; private set; } + + private IWindowSlot DefaultWindowSlot => windowSlots[0]; + + [SerializeField] private List windowSlots; [SerializeField] private WindowController controller; - void IWindow.SetOpenedState(IWindowSlot parentSlot) + public void SetOpenedState(IWindowSlot parentSlot) { gameObject.SetActive(true); Parent = parentSlot; @@ -30,12 +35,11 @@ namespace NEG.UI.UnityUi.Window controller.SetData(data); } - void IWindow.SetClosedState() + public void SetClosedState() { gameObject.SetActive(false); Parent = null; - if(childWindowArea != null) - ChildWindowSlot.CloseAllWindows(); + ((ISlotsHolder)this).CloseAllWindows(); } private void Awake() => ((IWindow)this).SetClosedState(); @@ -46,7 +50,10 @@ namespace NEG.UI.UnityUi.Window controller = GetComponent(); } - public IEnumerable AvailableSlots { get; } - public void OpenWindow(IWindow window, object data = null) => throw new NotImplementedException(); + public void OpenWindow(IWindow window, object data = null) + { + DefaultWindowSlot.AttachWindow(window); + window.SetData(data); + } } } \ No newline at end of file diff --git a/NEG/UI/UnityUi/WindowSlot/MonoWindowSlot.cs b/NEG/UI/UnityUi/WindowSlot/MonoWindowSlot.cs index 6525e6b..03e6b55 100644 --- a/NEG/UI/UnityUi/WindowSlot/MonoWindowSlot.cs +++ b/NEG/UI/UnityUi/WindowSlot/MonoWindowSlot.cs @@ -16,6 +16,5 @@ namespace NEG.UI.UnityUi.WindowSlot public abstract void CloseAllWindows(); [SerializeField] private SerializableInterface slotsHolder; - } } \ No newline at end of file diff --git a/NEG/UI/Window/IWindow.cs b/NEG/UI/Window/IWindow.cs index f3e7262..ad866fb 100644 --- a/NEG/UI/Window/IWindow.cs +++ b/NEG/UI/Window/IWindow.cs @@ -7,6 +7,9 @@ namespace NEG.UI.Window { public interface IWindow : ISlotsHolder { + /// + /// Parent slot of this window. + /// IWindowSlot Parent { get; } /// @@ -15,6 +18,10 @@ namespace NEG.UI.Window /// slot that opens window void SetOpenedState(IWindowSlot parentSlot); + /// + /// Sets data for window, usually used for dynamic content set by external logic controller. + /// + /// can be any type, window should cast for expected type void SetData(object data); /// @@ -25,7 +32,12 @@ namespace NEG.UI.Window public static class WindowInterfaceExtensions { - //Open + /// + /// Opens window as slot child. If slot is null or not provided, as child of current area. + /// + /// window to open + /// slot to attach window + /// data to send to window public static void Open(this IWindow window, IWindowSlot slot = null, object data = null) { if (slot != null) @@ -37,8 +49,21 @@ namespace NEG.UI.Window UiManager.Instance.CurrentArea.OpenWindow(window, data); } - + + /// + /// Opens window as child of selected area. + /// + /// window to open + /// area to attach window + /// data to send to window public static void Open(this IWindow window, IArea area, object data = null) => area.OpenWindow(window, data); + + /// + /// Open passed window as child of this window. + /// + /// parent window + /// window to open + /// data to send to window public static void OpenChild(this IWindow window, IWindow windowToOpen, object data = null) { if (windowToOpen == null) @@ -48,7 +73,13 @@ namespace NEG.UI.Window } window.OpenWindow(windowToOpen, data); } - + + /// + /// Open window as child of provided window. If is null, as child of current main window in + /// + /// window to open + /// + /// public static void OpenAsChild(this IWindow window, IWindow parentWindow = null, object data = null) { if (parentWindow != null)