AlicizaX/Client/Packages/com.alicizax.unity.ui/Runtime/UI/Base/Panel/UIWindow.cs
2025-01-24 16:21:00 +08:00

286 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using AlicizaX.Runtime;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;
namespace AlicizaX.UI.Runtime
{
public abstract partial class UIWindow : UIBase
{
internal Canvas _canvas;
internal Canvas[] _childCanvas;
internal GraphicRaycaster _raycaster;
internal GraphicRaycaster[] _childRaycaster;
public override string AssetName
{
get => gameObject.name;
}
private bool mVisible;
public override bool Visible
{
get
{
if (_canvas != null)
{
return _canvas.gameObject.layer == UIComponent.WINDOW_SHOW_LAYER;
}
else
{
return false;
}
}
set
{
if (value == mVisible)
{
return;
}
if (value)
{
OnRegisterEvent();
}
else
{
RemoveAllUIEvent();
}
mVisible = value;
if (_canvas != null)
{
int setLayer = value ? UIComponent.WINDOW_SHOW_LAYER : UIComponent.WINDOW_HIDE_LAYER;
if (_canvas.gameObject.layer == setLayer)
return;
_canvas.gameObject.layer = setLayer;
for (int i = 0; i < _childCanvas.Length; i++)
{
_childCanvas[i].gameObject.layer = setLayer;
}
Interactable = value;
}
}
}
private bool Interactable
{
get
{
if (_raycaster != null)
{
return _raycaster.enabled;
}
else
{
return false;
}
}
set
{
if (_raycaster != null)
{
_raycaster.enabled = value;
for (int i = 0; i < _childRaycaster.Length; i++)
{
_childRaycaster[i].enabled = value;
}
}
}
}
/// <summary>
/// 窗口深度值。
/// </summary>
public int Depth
{
get
{
if (_canvas != null)
{
return _canvas.sortingOrder;
}
else
{
return 0;
}
}
set
{
if (_canvas != null)
{
if (_canvas.sortingOrder == value)
{
return;
}
// 设置父类
_canvas.sortingOrder = value;
// 设置子类
int depth = value;
for (int i = 0; i < _childCanvas.Length; i++)
{
var canvas = _childCanvas[i];
if (canvas != _canvas)
{
depth += 5; //注意递增值
canvas.sortingOrder = depth;
}
}
}
}
}
internal void InternalCreate(GameObject panel)
{
if (panel == null)
{
return;
}
panel.name = GetType().Name;
gameObject = panel;
panel.transform.localPosition = Vector3.zero;
rectTransform.pivot = new Vector2(0.5f, 0.5f);
rectTransform.anchorMin = Vector2.zero;
rectTransform.anchorMax = Vector2.one;
rectTransform.offsetMin = Vector2.zero;
rectTransform.offsetMax = Vector2.zero;
rectTransform.localScale = Vector3.one;
// 获取组件
_canvas = panel.GetComponent<Canvas>();
if (_canvas == null)
{
throw new Exception($"Not found {nameof(Canvas)} in panel {AssetName}");
}
_canvas.overrideSorting = true;
_canvas.sortingOrder = 0;
_canvas.sortingLayerName = "Default";
// 获取组件
_raycaster = panel.GetComponent<GraphicRaycaster>();
_childCanvas = panel.GetComponentsInChildren<Canvas>(true);
_childRaycaster = panel.GetComponentsInChildren<GraphicRaycaster>(true);
IsLoaded = true;
}
internal void RefreshParams(params System.Object[] userDatas)
{
this.userDatas = userDatas;
}
internal void InternalInitlize()
{
OnBindUIComponents();
OnInitlize();
}
internal void InternalOpen()
{
Visible = true;
OnOpen();
WithParentVisible(true, true);
}
internal bool InternalUpdate()
{
if (!IsLoaded || !Visible)
{
return false;
}
OnUpdate();
return true;
}
internal void InternalClose()
{
OnClose();
Visible = false;
CollectChildVisible();
WithParentVisible(false, false);
}
internal void InternalDestroy()
{
DisposeEvent();
for (int i = 0; i < childWidgets.Count; i++)
{
var uiChild = childWidgets[i];
uiChild.InternalDestroy();
}
childWidgets.Clear();
OnDestroy();
if (gameObject != null)
{
Object.Destroy(gameObject);
gameObject = null;
}
}
protected virtual void OnUpdate()
{
}
/// <summary>
/// 关闭自己
/// </summary>
/// <param name="force">如果有缓存时间 指定该参数可以直接移除 长期缓存的无效</param>
protected void CloseSelf(bool force = false)
{
GameEntry.GetComponent<UIComponent>().CloseUI(this.GetType(), force);
}
private void CollectChildVisible()
{
for (int i = 0; i < childWidgets.Count; i++)
{
var uiChild = childWidgets[i];
if (uiChild.Visible)
{
withOpenWidget.Add(uiChild);
}
}
}
private void WithParentVisible(bool visible, bool clear)
{
for (int i = 0; i < withOpenWidget.Count; i++)
{
var uiChild = withOpenWidget[i];
if (visible)
{
uiChild.InternalRegisterEvent();
}
else
{
uiChild.InternalRemoveAllUIEvent();
}
}
if (clear) withOpenWidget.Clear();
}
}
}