basic functionality

This commit is contained in:
Hubert Mattusch 2022-12-16 02:30:06 +01:00
parent 1318e8fea4
commit a5fc6179fb
44 changed files with 636 additions and 0 deletions

View File

@ -0,0 +1,18 @@
{
"name": "NEG.Utils.Editor",
"rootNamespace": "",
"references": [
"GUID:3c4294719a93e3c4e831a9ff0c261e8a"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5928dc8d9173fd348aa77d4593ca3fd8
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
NEG.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 61eeed9106e147d8a76d7f0140d3571d
timeCreated: 1670708950

3
NEG/UI.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bbdebf147b9a40b0bc94b6f710c7aa6b
timeCreated: 1670690396

3
NEG/UI/Area.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 853f6a7d0f224278afbb5457d0fb8bde
timeCreated: 1670706939

32
NEG/UI/Area/IArea.cs Normal file
View File

@ -0,0 +1,32 @@
using System.Collections.Generic;
using NEG.UI.Popup;
using NEG.UI.Window;
using NEG.UI.WindowSlot;
namespace NEG.UI.Area
{
public interface IArea : IUiElement
{
IEnumerable<IWindowSlot> AvailableSlots { get; }
IEnumerable<IPopup> CurrentPopups { get; }
/// <summary>
/// Open window
/// </summary>
/// <param name="window"></param>
void OpenWindow(IWindow window);
/// <summary>
/// Open popup
/// </summary>
/// <param name="popup"></param>
void OpenPopup(IPopup popup);
void CloseAllWindows()
{
foreach (var slot in AvailableSlots)
{
slot.CloseAllWindows();
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ffa2155176774ab691d499979707a1bb
timeCreated: 1670690282

58
NEG/UI/Area/MonoArea.cs Normal file
View File

@ -0,0 +1,58 @@
using System.Collections.Generic;
using UnityEngine;
using NEG.UI.Popup;
using NEG.UI.Window;
using NEG.UI.WindowSlot;
namespace NEG.UI.Area
{
public class MonoArea : MonoBehaviour, IArea
{
public IEnumerable<IWindowSlot> AvailableSlots => windowSlots;
public IWindowSlot DefaultWindowSlot => windowSlots[0];
public IEnumerable<IWindow> CurrentWindows { get; }
public IEnumerable<IPopup> CurrentPopups => currentPopups;
[SerializeField] private List<MonoWindowSlot> windowSlots;
[SerializeField] private Queue<IPopup> currentPopups = new();
public void SetEnabled(bool setEnabled) => gameObject.SetActive(setEnabled);
public void OpenWindow(IWindow window) => DefaultWindowSlot.AttachWindow(window);
public void OpenPopup(IPopup popup)
{
currentPopups.Enqueue(popup);
popup.OnPopupClosed += OnPopupClosed;
popup.Show();
UpdatePopupStates();
}
private void UpdatePopupStates()
{
if(currentPopups.Count == 0)
return;
while (currentPopups.TryPeek(out var popup))
{
if(popup.IsValid)
popup.SetEnabled(true);
currentPopups.Dequeue();
}
}
private void OnPopupClosed(IPopup popup)
{
if (!currentPopups.Contains(popup))
return;
if(currentPopups.Peek() != popup)
return;
currentPopups.Dequeue();
UpdatePopupStates();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bbfe2293348b4c9096a3763479ec00c7
timeCreated: 1670707479

7
NEG/UI/IUiElement.cs Normal file
View File

@ -0,0 +1,7 @@
namespace NEG.UI
{
public interface IUiElement
{
void SetEnabled(bool setEnabled);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 296bf6969a6347f8aea788a7bdd086af
timeCreated: 1670693177

14
NEG/UI/NEG.UI.asmdef Normal file
View File

@ -0,0 +1,14 @@
{
"name": "NegUi",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7361f1d9c43da6649923760766194746
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
NEG/UI/Popup.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 76fc21263637443ca8268859d4cb5378
timeCreated: 1670707809

45
NEG/UI/Popup/IPopup.cs Normal file
View File

@ -0,0 +1,45 @@
using JetBrains.Annotations;
using NEG.UI.Area;
using System;
namespace NEG.UI.Popup
{
[PublicAPI]
public interface IPopup : IUiElement
{
/// <summary>
/// Call when popup is not forcly closed
/// </summary>
event Action<IPopup> OnPopupClosed;
/// <summary>
/// Is popup still valid to show
/// </summary>
bool IsValid { get; }
/// <summary>
/// Mark popup as ready to show.
/// </summary>
internal void Show();
/// <summary>
/// Close popup or mark as closed if not visible
/// </summary>
/// <param name="isForced">Is closing by forced by system, ex. close area</param>
void Close(bool isForced = false);
}
public static class PopupExtensions
{
public static void Show(this IPopup popup, IArea area = null)
{
if (area != null)
{
area.OpenPopup(popup);
return;
}
UiManager.Instance.CurrentArea.OpenPopup(popup);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 79767831e4324605974f3bb0bb5026fb
timeCreated: 1670692499

24
NEG/UI/Popup/MonoPopup.cs Normal file
View File

@ -0,0 +1,24 @@
using NEG.UI.Area;
using System;
using UnityEngine;
namespace NEG.UI.Popup
{
public class MonoPopup : MonoBehaviour, IPopup
{
public event Action<IPopup> OnPopupClosed;
public bool IsValid { get; private set; }
public void Close(bool isForced = false)
{
IsValid = false;
gameObject.SetActive(false);
if(!isForced)
OnPopupClosed?.Invoke(this);
}
public void SetEnabled(bool setEnabled) => gameObject.SetActive(setEnabled);
void IPopup.Show() => IsValid = true;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d3057d16be014bd58847b118a24c21dd
timeCreated: 1670707831

50
NEG/UI/UiManager.cs Normal file
View File

@ -0,0 +1,50 @@
using NEG.UI.Area;
using System.Collections.Generic;
using UnityEngine;
namespace NEG.UI
{
public class UiManager
{
//TODO: use default unity selection
//TODO: window snaping to slots
public static UiManager Instance { get; private set; }
public IArea CurrentArea
{
get => currentArea;
set
{
if (value == null)
{
Debug.LogError("CurrentArea can't be null");
return;
}
currentArea?.SetEnabled(false);
currentArea = value;
currentArea.SetEnabled(true);
}
}
private IArea currentArea;
public UiManager(IArea startArea)
{
if (Instance != null)
{
Debug.LogError("Only one instance od UiManager is allowed");
return;
}
Instance = this;
CurrentArea = startArea;
}
}
}

11
NEG/UI/UiManager.cs.meta Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c322beedd2ec8f844903c18b1ef74b15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
NEG/UI/UnityUi.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a0be272f427b40848b8aeff5b04770b4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dcaa262d2bcd4b19aa25512a19830555
timeCreated: 1670777190

View File

@ -0,0 +1,59 @@
using FMOD.Studio;
using FMODUnity;
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace NEG.UI.UnityUi.Buttons
{
[RequireComponent(typeof(ButtonSerializeFields))]
public class BaseButton : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler
{
public event Action OnButtonPressed;
protected ButtonSerializeFields serializeFields;
private bool isHovered;
public virtual void OnSelect(BaseEventData eventData)
{
if (serializeFields.Text)
serializeFields.Text.color = serializeFields.SelectedTextColor;
}
public void OnDeselect(BaseEventData eventData)
{
if (serializeFields.Text)
serializeFields.Text.color = serializeFields.DeselectedTextColor;
}
public void OnPointerEnter(PointerEventData eventData)
{
isHovered = true;
if (serializeFields.Text)
serializeFields.Text.color = serializeFields.SelectedTextColor;
}
public void OnPointerExit(PointerEventData eventData)
{
isHovered = false;
if (serializeFields.Text)
serializeFields.Text.color = serializeFields.DeselectedTextColor;
}
protected virtual void Awake()
{
serializeFields = GetComponent<ButtonSerializeFields>();
serializeFields.Button.onClick.AddListener(OnClicked);
OnDeselect(null);
}
protected virtual void OnClicked()
{
OnDeselect(null);
isHovered = false;
OnButtonPressed?.Invoke();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3a250ef2d0c34e7396a16fc5eddbdb01
timeCreated: 1670777213

View File

@ -0,0 +1,33 @@
using FMODUnity;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace NEG.UI.UnityUi.Buttons
{
public class ButtonSerializeFields : MonoBehaviour
{
[field: SerializeField]
public Button Button { get; private set; }
[field: SerializeField]
public TMP_Text Text { get; private set; }
[field: SerializeField]
public Color SelectedTextColor { get; private set; }
[field: SerializeField]
public Color DeselectedTextColor { get; private set; }
[field: SerializeField]
public EventReference HoverEventRef { get; private set; }
[field: SerializeField]
public EventReference ClickEventRef { get; private set; }
private void OnValidate()
{
if(Button == null)
Button = GetComponent<Button>();
if (Text == null)
Text = GetComponentInChildren<TMP_Text>();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3f8c6cf4cf18463c86ec1165c61c79b2
timeCreated: 1670777232

View File

@ -0,0 +1,23 @@
using NEG.UI.Window;
using System;
using UnityEngine;
namespace NEG.UI.UnityUi.Buttons
{
[RequireComponent(typeof(BaseButton))]
public class CloseWindow : MonoBehaviour
{
[Header("Set by hand or use editor button")]
[SerializeField] private MonoWindow windowToClose;
private void Awake() => GetComponent<BaseButton>().OnButtonPressed += OnClicked;
private void OnClicked() => windowToClose.Close();
private void OnValidate()
{
if(windowToClose != null)
return;
windowToClose = GetComponentInParent<MonoWindow>();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3001b971ff1e4915a29784efdf190bd6
timeCreated: 1670807872

View File

@ -0,0 +1,19 @@
using System;
using UnityEngine;
using NEG.UI.Window;
using NEG.UI.WindowSlot;
namespace NEG.UI.UnityUi.Buttons
{
[RequireComponent(typeof(BaseButton))]
public class OpenWindow : MonoBehaviour
{
[SerializeField] private MonoWindow window;
[Header("Open on default area slot if empty")]
[SerializeField] private MonoWindowSlot slot;
private void Awake() => GetComponent<BaseButton>().OnButtonPressed += OnClicked;
private void OnClicked() => window.Open(slot);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 66a5c05f0ba84b2a9b54f3e05a21d495
timeCreated: 1670806968

View File

@ -0,0 +1,21 @@
{
"name": "NEG.UI.UnityUi",
"rootNamespace": "",
"references": [
"GUID:343deaaf83e0cee4ca978e7df0b80d21",
"GUID:7361f1d9c43da6649923760766194746",
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:0c752da273b17c547ae705acf0f2adf2"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [
""
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e2aaf8effe1c9634d87b2edda6988a6a
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
NEG/UI/Window.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8e57424db9924004a7945bcbbea7bab9
timeCreated: 1670707788

48
NEG/UI/Window/IWindow.cs Normal file
View File

@ -0,0 +1,48 @@
using NEG.UI.Area;
using NEG.UI.WindowSlot;
using UnityEngine;
namespace NEG.UI.Window
{
public interface IWindow
{
IWindowSlot Parent { get; }
IArea ChildWindowArea { get; }
/// <summary>
/// Call internally by slot to open window
/// </summary>
/// <param name="parentSlot">Slot that opens window</param>
internal void Open(IWindowSlot parentSlot);
/// <summary>
/// Call internally to close window by slot
/// </summary>
internal void Close();
}
public static class WindowInterfaceExtensions
{
//Open
public static void Open(this IWindow window, IWindowSlot slot = null)
{
if(slot != null)
slot.AttachWindow(window);
else
UiManager.Instance.CurrentArea.OpenWindow(window);
}
public static void Open(this IWindow window, IArea area) => area.OpenWindow(window);
public static void OpenChildWindow(this IWindow window, IWindow windowToOpen, IWindowSlot slot = null)
{
if (window.ChildWindowArea == null)
{
Debug.LogError("This window doesn't contain area for child windows");
return;
}
//TODO: DO it
//window.ChildWindowArea.OpenWindow(windowToOpen, slot);
}
public static void Close(this IWindow window) => window.Parent.DetachWindow(window);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c68ab5f7e5d9440e9fbd26307211e8f1
timeCreated: 1670690267

View File

@ -0,0 +1,30 @@
using NEG.UI.Area;
using NEG.UI.Popup;
using NEG.UI.WindowSlot;
using System;
using UnityEngine;
namespace NEG.UI.Window
{
public class MonoWindow : MonoBehaviour, IWindow
{
public IWindowSlot Parent { get; private set; }
public IArea ChildWindowArea => childWindowArea;
[SerializeField] private MonoArea childWindowArea;
void IWindow.Open(IWindowSlot parentSlot)
{
gameObject.SetActive(true);
Parent = parentSlot;
}
void IWindow.Close()
{
gameObject.SetActive(false);
Parent = null;
}
private void Awake() => ((IWindow)this).Close();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3807b2039b1941d999642e241ce1f463
timeCreated: 1670709296

3
NEG/UI/WindowSlot.meta Normal file
View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1f54322bf2ce451dbfccb7c41e89dd62
timeCreated: 1670707801

View File

@ -0,0 +1,13 @@
using NEG.UI.Area;
using NEG.UI.Window;
namespace NEG.UI.WindowSlot
{
public interface IWindowSlot
{
IArea ParentArea { get; }
void AttachWindow(IWindow window);
void DetachWindow(IWindow window);
void CloseAllWindows();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f4f7edf281324a2ba86f4099eff57552
timeCreated: 1670694831

View File

@ -0,0 +1,14 @@
using NEG.UI.Area;
using NEG.UI.Window;
using UnityEngine;
namespace NEG.UI.WindowSlot
{
public abstract class MonoWindowSlot : MonoBehaviour, IWindowSlot
{
public IArea ParentArea { get; private set; }
public abstract void AttachWindow(IWindow window);
public abstract void DetachWindow(IWindow window);
public abstract void CloseAllWindows();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7bc46ac7f2454eaa934561b7ef20ff88
timeCreated: 1670709404

View File

@ -0,0 +1,25 @@
using NEG.UI.Window;
using UnityEngine;
namespace NEG.UI.WindowSlot
{
public class SingleWindowSlot : MonoWindowSlot
{
public IWindow CurrentWindow
{
get => currentWindow;
set
{
currentWindow?.Close();
currentWindow = value;
currentWindow?.Open(this);
}
}
private IWindow currentWindow;
public override void AttachWindow(IWindow window) => CurrentWindow = window;
public override void DetachWindow(IWindow window) => CurrentWindow = null;
public override void CloseAllWindows() => CurrentWindow = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9358679df24f458f8836506344eb169d
timeCreated: 1670716632