using System.Collections.Generic; using TEngine; using UnityEngine; namespace GameLogic { public abstract class UIWidget : UIBase { /// /// 窗口组件的实例资源对象。 /// public override GameObject gameObject { protected set; get; } /// /// 窗口组件矩阵位置组件。 /// public override RectTransform rectTransform { protected set; get; } /// /// 窗口位置组件。 /// public override Transform transform { protected set; get; } /// /// 窗口组件名称。 /// // ReSharper disable once InconsistentNaming public string name { protected set; get; } = string.Empty; /// /// UI类型。 /// public override UIType Type => UIType.Widget; /// /// 所属的窗口。 /// 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; } } /// /// 窗口可见性。 /// public bool Visible { get => gameObject.activeSelf; set { gameObject.SetActive(value); OnSetVisible(value); } } internal bool InternalUpdate() { if (!IsPrepare) { return false; } List listNextUpdateChild = null; if (ListChild != null && ListChild.Count > 0) { listNextUpdateChild = _listUpdateChild; var updateListValid = _updateListValid; List listChild = null; if (!updateListValid) { if (listNextUpdateChild == null) { listNextUpdateChild = new List(); _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 /// /// 创建窗口内嵌的界面。 /// /// 父节点UI。 /// 组件根节点。 /// 是否可见。 /// public bool Create(UIBase parentUI, GameObject widgetRoot, bool visible = true) { return CreateImp(parentUI, widgetRoot, false, visible); } /// /// 根据资源名创建 /// /// /// /// /// /// 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; } /// /// 根据prefab或者模版来创建新的 widget。 /// 存在父物体得资源故不需要异步加载。 /// /// 父物体UI。 /// 实例化预制体。 /// 实例化父节点。 /// 是否可见。 /// 是否创建成功。 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(); 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(); if (parentCanvas == null) { return; } if (gameObject != null) { var listCanvas = gameObject.GetComponentsInChildren(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 /// /// 组件被销毁调用。 /// 请勿手动调用! /// protected internal void OnDestroyWidget() { Parent?.SetUpdateDirty(); RemoveAllUIEvent(); foreach (var uiChild in ListChild) { uiChild.OnDestroy(); uiChild.OnDestroyWidget(); } if (gameObject != null) { Object.Destroy(gameObject); } } /// /// 主动销毁组件。 /// public void Destroy() { if (_parent != null) { _parent.ListChild.Remove(this); OnDestroy(); OnDestroyWidget(); } } #endregion } }