using System; using System.Collections.Generic; using System.Linq; using FairyGUI; using NBC.Asset; using NBC.Entitas; using NBC.Entitas.Interface; using UnityEngine; namespace NBC { public class UIComponent : Entity { public sealed class UIManagerComponentAwakeSystem : AwakeSystem { protected override void Awake(UIComponent self) { self.Awake(); } } public sealed class UIManagerComponentUpdateSystem : UpdateSystem { protected override void Update(UIComponent self) { self.Update(); } } public sealed class UIManagerComponentDestroySystem : DestroySystem { protected override void Destroy(UIComponent self) { self.Destroy(); } } /// /// 所有UI /// private readonly Dictionary _uiArray = new Dictionary(); private GGraph _modalLayer; private GRoot _uiRoot; private UIComponentLanguagePack _uiLanguageConfig; private void Awake() { Log.Info("UI 模块初始化"); _uiRoot = GRoot.inst; } public void Destroy() { } private void Update() { UIRunner.Update(); foreach (var panel in _uiArray.Values) { if (panel != null && panel.IsShowing) { panel.Update(); } } } #region 内部方法 internal void ShowUI(string uiName, object param = null) { var panel = GetUI(uiName); panel.SetData(param); if (panel.IsShowing) { panel.Refresh(); } else { _ = panel.Show(); } } internal void RemoveUI(string uiName) { var wind = GetUI(uiName); if (wind == null) { Log.Warning($"要删除的界面不存在:{uiName}"); return; } if (!wind.IsDotDel) { wind.Dispose(); _uiArray.Remove(uiName); } } private void CreateModalLayer() { var modalLayerColor = UIConfig.modalLayerColor; if (_modalLayer != null) { _modalLayer.onClick.Clear(); } _modalLayer = new GGraph(); _modalLayer.DrawRect(_uiRoot.width, _uiRoot.height, 0, Color.white, modalLayerColor); _modalLayer.AddRelation(_uiRoot, RelationType.Size); _modalLayer.name = _modalLayer.gameObjectName = "ModalLayer"; _modalLayer.SetHome(_uiRoot); } #endregion #region OpenUI public T OpenUI(object param = null) where T : UIPanel { return OpenUI(typeof(T).Name, param); } public T OpenUI(string uiName, object param = null) where T : UIPanel { var panel = GetUI(); if (panel == null) { panel = Activator.CreateInstance(); if (panel != null) { panel.SetUIManager(this); panel.SetData(param); panel.Init(); _uiArray[uiName] = panel; } } ShowUI(uiName, param); return panel; } #endregion #region Get public T GetUI() where T : UIPanel { UIPanel wind = null; Type type = typeof(T); var uiName = type.Name; foreach (var name in _uiArray.Keys) { if (name != uiName) continue; wind = _uiArray[name]; break; } return wind as T; } public UIPanel GetUI(string uiName) { foreach (var name in _uiArray.Keys) { if (name != uiName) continue; return _uiArray[name]; } return null; } public UIPanel[] GetAllUI() { return _uiArray.Values.ToArray(); } public List GetAllUIName() { return _uiArray.Keys.ToList(); } #endregion #region Hide public void HideUI(Type type) { HideUI(type.Name); } public void HideUI() { Type type = typeof(T); HideUI(type.Name); } public void HideUI(string uiName) { var wind = GetUI(uiName); if (wind == null) { Log.Warning($"要删除的界面不存在:{uiName}"); return; } wind.Hide().Coroutine(); } /// /// 隐藏所有窗口 /// public void HideAllUI(bool isDotDel = false) { var names = GetAllUIName(); foreach (var uiName in names) { UIPanel panel = GetUI(uiName); if (panel.IsShowing) { if (!panel.IsDotDel || isDotDel) { HideUI(uiName); } } } } #endregion #region Delete /// /// 删除所有打开的窗口 /// public void DeleteAllUI() { var names = GetAllUIName(); foreach (var uiName in names) { DestroyUI(uiName); } } public void DestroyUI() { Type type = typeof(T); DestroyUI(type.Name); } public void DestroyUI(Type type) { DestroyUI(type.Name); } public void DestroyUI(string uiName) { RemoveUI(uiName); } #endregion #region Util public void BringToFront(UIPanel uiPanel) { var uiRoot = GRoot.inst; var contentPane = uiPanel.ContentPane; if (contentPane.parent != uiRoot) { Log.Error("不在root内,无法置顶=="); return; } var cnt = uiRoot.numChildren; var i = 0; if (_modalLayer != null && _modalLayer.parent != null && !uiPanel.IsModal) { i = uiRoot.GetChildIndex(_modalLayer); } else { i = cnt - 1; } if (i >= 0) { uiRoot.SetChildIndex(contentPane, i); } } public bool IsTop(UIPanel uiPanel) { var parent = uiPanel.ContentPane.parent; if (parent == null) return false; var sortingOrder = uiPanel.ContentPane.sortingOrder; var maxIndex = -1; var panels = _uiArray.Values; foreach (var panel in panels) { if (panel.IsShowing && panel.ContentPane.sortingOrder == sortingOrder) { //只判断同层级的 var index = parent.GetChildIndex(panel.ContentPane); if (index > maxIndex) { maxIndex = index; } } } var uiIndex = parent.GetChildIndex(uiPanel.ContentPane); return uiIndex >= maxIndex; } public void AdjustModalLayer() { if (_modalLayer == null || _modalLayer.isDisposed) { CreateModalLayer(); } var showDic = new Dictionary(); var panels = _uiArray.Values; foreach (var panel in panels) { if (panel.IsShowing) { showDic[panel.ContentPane] = panel; } } var cnt = _uiRoot.numChildren; for (var i = cnt - 1; i >= 0; i--) { var g = _uiRoot.GetChildAt(i); if (showDic.TryGetValue(g, out var panel)) { if (panel.IsModal) { if (_modalLayer.parent == null) _uiRoot.AddChildAt(_modalLayer, i); else { _uiRoot.SetChildIndexBefore(_modalLayer, i); } return; } } } if (_modalLayer != null && _modalLayer.parent != null) { _uiRoot.RemoveChild(_modalLayer); } } public bool IsOpen(string uiName) { UIPanel wind = GetUI(uiName); return wind != null && wind.IsShowing; } #endregion #region Package public void AddPackage(string assetPath) { AddPackage(UIConst.UIPackRootUrl, assetPath); } public void AddPackage(string root, string assetPath) { var path = root + assetPath; if (path.StartsWith("Assets/")) { UIPackage.AddPackage(path, (string name, string extension, Type type, out DestroyMethod method) => { method = DestroyMethod.None; var pro = Assets.LoadAsset(name.Replace("\\", "/") + extension, type); return pro?.Asset; }); } else { UIPackage.AddPackage(path); } } #endregion #region Language public void SetUILanguage() where T : UIComponentLanguagePack { _uiLanguageConfig = Activator.CreateInstance(); } public void TrySetComponentLanguage(GComponent component) { _uiLanguageConfig?.TrySetComponentLanguage(component); } public void TrySetPanelLanguage(GComponent component) { _uiLanguageConfig?.TrySetPanelLanguage(component); } #endregion } }