2025-04-22 17:16:40 +08:00

314 lines
8.9 KiB
C#

using System.Collections.Generic;
using TEngine;
using UnityEngine;
namespace GameLogic
{
public abstract class UIWidget : UIBase
{
/// <summary>
/// 窗口组件的实例资源对象。
/// </summary>
public override GameObject gameObject { protected set; get; }
/// <summary>
/// 窗口组件矩阵位置组件。
/// </summary>
public override RectTransform rectTransform { protected set; get; }
/// <summary>
/// 窗口位置组件。
/// </summary>
public override Transform transform { protected set; get; }
/// <summary>
/// 窗口组件名称。
/// </summary>
// ReSharper disable once InconsistentNaming
public string name { protected set; get; } = string.Empty;
/// <summary>
/// UI类型。
/// </summary>
public override UIType Type => UIType.Widget;
/// <summary>
/// 所属的窗口。
/// </summary>
public UIWindow OwnerWindow
{
get
{
var parentUI = base._parent;
while (parentUI != null)
{
if (parentUI.Type == UIType.Window)
{
return parentUI as UIWindow;
}
parentUI = parentUI.Parent;
}
return null;
}
}
/// <summary>
/// 窗口可见性。
/// </summary>
public bool Visible
{
get => gameObject.activeSelf;
set
{
gameObject.SetActive(value);
OnSetVisible(value);
}
}
internal bool InternalUpdate()
{
if (!IsPrepare)
{
return false;
}
List<UIWidget> listNextUpdateChild = null;
if (ListChild != null && ListChild.Count > 0)
{
listNextUpdateChild = _listUpdateChild;
var updateListValid = _updateListValid;
List<UIWidget> listChild = null;
if (!updateListValid)
{
if (listNextUpdateChild == null)
{
listNextUpdateChild = new List<UIWidget>();
_listUpdateChild = listNextUpdateChild;
}
else
{
listNextUpdateChild.Clear();
}
listChild = ListChild;
}
else
{
listChild = listNextUpdateChild;
}
for (int i = 0; i < listChild.Count; i++)
{
var uiWidget = listChild[i];
if (uiWidget == null)
{
continue;
}
var needValid = uiWidget.InternalUpdate();
if (!updateListValid && needValid)
{
listNextUpdateChild.Add(uiWidget);
}
}
if (!updateListValid)
{
_updateListValid = true;
}
}
bool needUpdate = false;
if (listNextUpdateChild is not { Count: > 0 })
{
_hasOverrideUpdate = true;
OnUpdate();
needUpdate = _hasOverrideUpdate;
}
else
{
OnUpdate();
needUpdate = true;
}
return needUpdate;
}
#region Create
/// <summary>
/// 创建窗口内嵌的界面。
/// </summary>
/// <param name="parentUI">父节点UI。</param>
/// <param name="widgetRoot">组件根节点。</param>
/// <param name="visible">是否可见。</param>
/// <returns></returns>
public bool Create(UIBase parentUI, GameObject widgetRoot, bool visible = true)
{
return CreateImp(parentUI, widgetRoot, false, visible);
}
/// <summary>
/// 根据资源名创建
/// </summary>
/// <param name="resPath"></param>
/// <param name="parentUI"></param>
/// <param name="parentTrans"></param>
/// <param name="visible"></param>
/// <returns></returns>
public bool CreateByPath(string resPath, UIBase parentUI, Transform parentTrans = null, bool visible = true)
{
GameObject goInst = UIModule.Resource.LoadGameObject(resPath, parent: parentTrans);
if (goInst == null)
{
return false;
}
if (!Create(parentUI, goInst, visible))
{
return false;
}
goInst.transform.localScale = Vector3.one;
goInst.transform.localPosition = Vector3.zero;
return true;
}
/// <summary>
/// 根据prefab或者模版来创建新的 widget。
/// <remarks>存在父物体得资源故不需要异步加载。</remarks>
/// </summary>
/// <param name="parentUI">父物体UI。</param>
/// <param name="goPrefab">实例化预制体。</param>
/// <param name="parentTrans">实例化父节点。</param>
/// <param name="visible">是否可见。</param>
/// <returns>是否创建成功。</returns>
public bool CreateByPrefab(UIBase parentUI, GameObject goPrefab, Transform parentTrans, bool visible = true)
{
if (parentTrans == null)
{
parentTrans = parentUI.rectTransform;
}
return CreateImp(parentUI, Object.Instantiate(goPrefab, parentTrans), true, visible);
}
private bool CreateImp(UIBase parentUI, GameObject widgetRoot, bool bindGo, bool visible = true)
{
if (!CreateBase(widgetRoot, bindGo))
{
return false;
}
RestChildCanvas(parentUI);
_parent = parentUI;
Parent.ListChild.Add(this);
Parent.SetUpdateDirty();
ScriptGenerator();
BindMemberProperty();
RegisterEvent();
OnCreate();
OnRefresh();
IsPrepare = true;
if (!visible)
{
gameObject.SetActive(false);
}
else
{
if (!gameObject.activeSelf)
{
gameObject.SetActive(true);
}
}
return true;
}
protected bool CreateBase(GameObject go, bool bindGo)
{
if (go == null)
{
return false;
}
name = GetType().Name;
transform = go.GetComponent<Transform>();
rectTransform = transform as RectTransform;
gameObject = go;
Log.Assert(rectTransform != null, $"{go.name} ui base element need to be RectTransform");
return true;
}
protected void RestChildCanvas(UIBase parentUI)
{
if (parentUI == null || parentUI.gameObject == null)
{
return;
}
Canvas parentCanvas = parentUI.gameObject.GetComponentInParent<Canvas>();
if (parentCanvas == null)
{
return;
}
if (gameObject != null)
{
var listCanvas = gameObject.GetComponentsInChildren<Canvas>(true);
for (var index = 0; index < listCanvas.Length; index++)
{
var childCanvas = listCanvas[index];
childCanvas.sortingOrder = parentCanvas.sortingOrder + childCanvas.sortingOrder % UIModule.WINDOW_DEEP;
}
}
}
#endregion
#region Destroy
/// <summary>
/// 组件被销毁调用。
/// <remarks>请勿手动调用!</remarks>
/// </summary>
protected internal void OnDestroyWidget()
{
Parent?.SetUpdateDirty();
RemoveAllUIEvent();
foreach (var uiChild in ListChild)
{
uiChild.OnDestroy();
uiChild.OnDestroyWidget();
}
if (gameObject != null)
{
Object.Destroy(gameObject);
}
}
/// <summary>
/// 主动销毁组件。
/// </summary>
public void Destroy()
{
if (_parent != null)
{
_parent.ListChild.Remove(this);
OnDestroy();
OnDestroyWidget();
}
}
#endregion
}
}