using Cysharp.Threading.Tasks; using UnityEngine; namespace AlicizaX.UI.Runtime { public abstract class UIWidget : UIBase { /// /// Widget父节点。 /// private UIBase _parent = null; /// /// Widget父节点。 /// public UIBase Parent => _parent; private bool mVisible; private bool isFirst = true; public override string AssetName { get => gameObject.name; } /// /// Widget自身不要调用 /// public override bool Visible { get => mVisible; //Widget内部禁止调用 否则有Bug set { if (!isFirst && value == mVisible) { return; } if (value) { OnRegisterEvent(); } else { RemoveAllUIEvent(); } VisibleWithLife(value).Forget(); isFirst = false; } } #region 生命周期 internal void InternalCreate(UIBase parent, GameObject obj) { _parent = parent; gameObject = obj; IsLoaded = true; OnBindUIComponents(); OnInitlize(); } internal void InternalDestroy() { DisposeEvent(); _parent.RemoveWidget(this); OnDestroy(); if (gameObject != null) { UnityEngine.Object.Destroy(gameObject); gameObject = null; } } internal void InternalRemoveAllUIEvent() { RemoveAllUIEvent(); } internal void InternalRegisterEvent() { OnRegisterEvent(); } #endregion /// /// 对外销毁用这个 持有者能销毁 /// public void DestroyWidget() { InternalDestroy(); } /// /// 自身关闭用这个 自己只允许关闭自己 /// protected void CloseWidget() { RemoveAllUIEvent(); VisibleWithLife(false).Forget(); } private async UniTask VisibleWithLife(bool value) { mVisible = value; if (value) { gameObject.SetActive(value); OnOpen(); if (this is IUIOpenTween tweenUI) { tweenUI.OnOpenTween().Forget(); } WithParentVisible(true, true); } else { OnClose(); if (this is IUICloseTween tweenUI) { await tweenUI.OnCloseTween(); } gameObject.SetActive(value); CollectChildVisible(); WithParentVisible(false, false); } } 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(); } } }