void OnBackstack(IStackableUI stackable) { if (stackable.GetType() == _uiType && GetComponent <Camera>() != null) { SetCameraParams(GetComponent <Camera>(), _previousParams); } }
/// <summary> /// ui完成了出栈操作 /// </summary> private void OnFinishedBackstacking() { if (_toEnstackWhenPossible.Count > 0 && CanDisplayNextOnQueue()) { _currentQueuedStackableDisplayed = _toEnstackWhenPossible.Dequeue(); EnStack(_currentQueuedStackableDisplayed, false); } }
/// <summary> /// 让指定的ui出栈 /// </summary> /// <param name="ui"></param> public void Destack(IStackableUI ui) { if (IsTop(ui)) { BackStack(); } else { StartCoroutine(Remove(ui)); } }
/// <summary> /// 获取顶层的SortingOrder /// </summary> /// <param name="ui"></param> /// <returns></returns> public int GetTopSortingOrder(IStackableUI ui) { var wrapper = GetWrapper(ui); if (wrapper == null) { return(0); } return(wrapper.lastSortingOrder); }
/// <summary> /// 获取黑色遮罩背景 /// </summary> /// <param name="ui"></param> /// <returns></returns> public GameObject GetPanelBlocker(IStackableUI ui) { var wrapper = GetWrapper(ui); if (wrapper == null) { return(null); } return(wrapper.inputBlockerInstance); }
/// <summary> /// ui入栈 /// </summary> /// <param name="stackable"></param> /// <param name="queued"></param> /// <param name="manualDepth"></param> public void EnStack(IStackableUI stackable, bool queued = false) { if (!queued || CanDisplayNextOnQueue()) { StartCoroutine(EnStackCoroutine(stackable)); } else { stackable.Show(false); _toEnstackWhenPossible.Enqueue(stackable); } }
void OnEnstack(IStackableUI stackable) { if (stackable.GetType() == _uiType && GetComponent <Camera>() != null) { _previousParams = GetCameraParams(GetComponent <Camera>()); if (relicRevealCameraParams != null) { SetCameraParams(GetComponent <Camera>(), relicRevealCameraParams); } } }
/// <summary> /// 从队列中让ui出队列入栈 /// </summary> public void EnstackQueue() { if (_toEnstackWhenPossible.Count == 0) { TopUIOnFocus(); } while (_toEnstackWhenPossible.Count > 0) { _currentQueuedStackableDisplayed = _toEnstackWhenPossible.Dequeue(); EnStack(_currentQueuedStackableDisplayed, false); _currentQueuedStackableDisplayed = null; } }
/// <summary> /// 把ui移动到栈顶(注:该方法是把目标ui上面的所有ui都从栈中移除掉来达到效果的) /// </summary> /// <param name="ui"></param> public void MoveToTop(IStackableUI ui) { IStackableUI[] stack = _backStack.Select(b => b.stackable).ToArray(); int index = System.Array.FindIndex(stack, m => m == ui); //把目标ui上面的ui都移除出栈 for (int i = stack.Length - 1; i > index; --i) { Instance.BackStack(); } var top = _backStack.Peek() as IStackableWrapper; }
/// <summary> /// wrap of EnStack /// </summary> /// <param name="ui"></param> public static void Queue(IStackableUI ui) { if (Instance.IsStacked(ui)) { Instance.Destack(ui); } if (Instance.IsQueued(ui)) { Instance.Dequeue(ui); } Instance.EnStack(ui, true); }
void Awake() { if (Application.isPlaying) { _ui = GetComponent <IStackableUI>(); if (_ui != null) { _uiType = _ui.GetType(); } UIStack.Instance.onEnstack += OnEnstack; UIStack.Instance.onBackstack += OnBackstack; } }
/// <summary> /// 清除队列中的ui /// </summary> public void ClearEnstackQueue() { while (_toEnstackWhenPossible.Count > 0) { IStackableUI stackable = _toEnstackWhenPossible.Dequeue(); if (stackable is Component) { Component c = (Component)stackable; if (c != null && c.transform.parent != null) { c.gameObject.CustomSetActive(false); Destroy(c.gameObject); } } } }
/// <summary> /// wrap of Destack /// </summary> /// <param name="ui"></param> public static void Close(IStackableUI ui) { if (!Instance.IsStacked(ui) && !Instance.IsQueued(ui) && !object.ReferenceEquals(ui, null) && !ui.Equals(null) && ui.Visibility) { ui.Show(false); return; } if (Instance.IsStacked(ui)) { Instance.Destack(ui); } if (Instance.IsQueued(ui)) { Instance.Dequeue(ui); } }
/// <summary> /// 让指定的ui队列中移除 /// </summary> /// <param name="ui"></param> public void Dequeue(IStackableUI ui) { EB.Collections.Queue <IStackableUI> tmpQueue = new EB.Collections.Queue <IStackableUI>(); while (_toEnstackWhenPossible.Count > 0) { IStackableUI q = _toEnstackWhenPossible.Dequeue(); if (q == ui) { break; } tmpQueue.Enqueue(q); } while (_toEnstackWhenPossible.Count > 0) { tmpQueue.Enqueue(_toEnstackWhenPossible.Dequeue()); } _toEnstackWhenPossible = tmpQueue; }
protected void OnLoadAndPlace(GameObject placed) { if (placed == null) { return; } IStackableUI stackable = (IStackableUI)placed.GetComponent(typeof(IStackableUI)); if (stackable != null && stackable.EnstackOnCreate) { if (UIStack.Instance.IsLoadingScreenUp || UIStack.Instance.IsWaittingScreenUp) { UIStack.Queue(stackable); } else { UIStack.Open(stackable); } } SetHudShow(); }
/// <summary> /// wrap of EnStack /// </summary> /// <param name="ui"></param> public static void Open(IStackableUI ui) { if (Instance.IsStacked(ui)) { if (Instance.IsTop(ui)) { EB.Debug.Log(string.Format("UIStack.Open: {0} is already opened", ui)); return; } else { Instance.MoveToTop(ui); return; } } if (Instance.IsQueued(ui)) { Instance.Dequeue(ui); } Instance.EnStack(ui, false); }
/// <summary> /// 把ui从堆栈中移除(可以不是栈顶的ui) /// </summary> /// <param name="ui"></param> /// <returns></returns> private IEnumerator Remove(IStackableUI ui) { EB.Debug.LogUI("界面UIStack:【<color=#00ff00>{0}</color>】在<color=#fff348>UIStack</color>中<color=#ff0000>从非栈顶出栈</color>,调用Remove方法", ui); // assume invisible first, update later _isInputBlockerVisible = false; _isFullScreenOpened = false; // remove from backStack IStackableWrapper wrapper = null; EB.Collections.Stack <IStackableWrapper> tmp = new EB.Collections.Stack <IStackableWrapper>(); while (_backStack.Count > 0) { var top = _backStack.Pop(); if (top.stackable != ui) { if (top.stackable.IsFullscreen()) { _isFullScreenOpened = true; } if (top.inputBlockerInstance != null && !_isInputBlockerVisible) { _isInputBlockerVisible = true; top.inputBlockerInstance.GetComponent <UIPanel>().alpha = top.inputBlockerInstance.GetComponentInChildren <TweenAlpha>().to; } tmp.Push(top); } else { wrapper = top; break; } } IStackableWrapper[] below = _backStack.ToArray(); while (tmp.Count > 0) { _backStack.Push(tmp.Pop()); } // remove from fullStack EB.Collections.Stack <StackedItem> fullTmp = new EB.Collections.Stack <StackedItem>(); while (_fullStack.Count > 0) { var top = _fullStack.Pop(); if (top != wrapper) { fullTmp.Push(top); } else { break; } } while (fullTmp.Count > 0) { _fullStack.Push(fullTmp.Pop()); } // update visibility for (int i = 0; i < below.Length; ++i) { if (!_isFullScreenOpened) { below[i].stackable.Show(true); if (below[i].inputBlockerInstance != null && !_isInputBlockerVisible) { _isInputBlockerVisible = true; below[i].inputBlockerInstance.GetComponent <UIPanel>().alpha = below[i].inputBlockerInstance.GetComponentInChildren <TweenAlpha>().to; } if (below[i].stackable.IsFullscreen()) { _isFullScreenOpened = true; GameUtils.SetMainCameraActive(below[i].stackable.IsRenderingWorldWhileFullscreen()); } } if (_isFullScreenOpened) { break; } } if (!_isFullScreenOpened && !IsLoadingScreenUp) { GameUtils.SetMainCameraActive(true); } // remove if (wrapper.inputBlockerInstance != null) { TweenAlpha ta = wrapper.inputBlockerInstance.GetComponentInChildren <TweenAlpha>(); ta.tweenFactor = _isInputBlockerVisible ? 0.1f : 1.0f; EventDelegate.Add(ta.onFinished, () => Destroy(wrapper.inputBlockerInstance)); ta.PlayReverse(); } ui.ClearData(); yield return(StartCoroutine(ui.OnRemoveFromStack())); }
public bool IsStacked(IStackableUI ui) { return(GetWrapper(ui) != null); }
public bool IsQueued(IStackableUI ui) { return(_toEnstackWhenPossible.Where(m => m == ui).FirstOrDefault() != null); }
/// <summary> /// 是否在栈顶 /// </summary> /// <param name="ui"></param> /// <returns></returns> public bool IsTop(IStackableUI ui) { return(_backStack.Count > 0 && _backStack.Peek().stackable == ui); }
/// <summary> /// 获取ui集合(包含预设、controller、深度等信息) /// </summary> /// <param name="ui">UIController</param> /// <returns></returns> private IStackableWrapper GetWrapper(IStackableUI ui) { return(_backStack.Where(m => m.stackable == ui).FirstOrDefault()); }
/// <summary> /// 执行ui出栈操作,移除栈顶ui /// </summary> /// <param name="isPartOfExitStack">是否是退出状态的一部分,从而决定是否做些uicontroller中的一些逻辑或回调</param> /// <returns></returns> private IEnumerator BackstackCoroutine(bool isPartOfExitStack) { if (_backStack.Count == 0) { EB.Debug.LogWarning("BackstackCoroutine: backStack is empty"); yield break; } IStackableWrapper wrapper = _backStack.Pop(); EB.Debug.LogUI("界面UIStack:【<color=#00ff00>{0}</color>】在<color=#fff348>UIStack</color>中<color=#ff0000>从栈顶出栈</color>", wrapper.stackable); // Clear eventual stacked renderers from the full stack while (_fullStack.Pop() != wrapper) { ; } if (onBackstack != null) { onBackstack(wrapper.stackable); } if (wrapper.inputBlockerInstance != null) { // Value might be changed later depending on whether we find another input blocker before the next panel _isInputBlockerVisible = false; TweenAlpha ta = wrapper.inputBlockerInstance.GetComponentInChildren <TweenAlpha>(); ta.tweenFactor = 1.0f; EventDelegate.Add(ta.onFinished, () => Destroy(wrapper.inputBlockerInstance)); ta.PlayReverse(); } if (wrapper.firstStackDepth >= 0 && wrapper.firstStackDepth < _nextStackDepth) { _nextStackDepth = wrapper.firstStackDepth; } // Let the other windows know what happened, show what needs to be shown, etc. if (_backStack.Count > 0) { EB.Collections.Stack <IStackableWrapper> tempStack = new EB.Collections.Stack <IStackableWrapper>(); while (_backStack.Count > 0 && !_backStack.Peek().stackable.IsFullscreen()) { tempStack.Push(_backStack.Pop()); if (wrapper.stackable.IsFullscreen()) { tempStack.Peek().stackable.Show(true); } if (tempStack.Peek().inputBlockerInstance != null && !_isInputBlockerVisible) { // show top blocker //TweenAlpha tempTa = tempStack.Peek().inputBlockerInstance.GetComponentInChildren<TweenAlpha>(); _isInputBlockerVisible = true; tempStack.Peek().inputBlockerInstance.GetComponent <UIPanel>().alpha = 1f; // tempTa.to; // update tween parameters if (wrapper.inputBlockerInstance != null) { TweenAlpha ta = wrapper.inputBlockerInstance.GetComponentInChildren <TweenAlpha>(); ta.tweenFactor = 0.0f; wrapper.inputBlockerInstance.GetComponentInChildren <UISprite>().alpha = 0.05f; } } } if (wrapper.stackable.IsFullscreen()) { // If the count is positive, it means that we've hit a full screen if (_backStack.Count > 0) { // show top full screen _backStack.Peek().stackable.Show(true); if (_backStack.Peek().inputBlockerInstance != null && !_isInputBlockerVisible) { // show top blocker TweenAlpha tempTa = tempStack.Peek().inputBlockerInstance.GetComponentInChildren <TweenAlpha>(); _isInputBlockerVisible = true; _backStack.Peek().inputBlockerInstance.GetComponent <UIPanel>().alpha = tempTa.to; // update tween parameters if (wrapper.inputBlockerInstance != null) { TweenAlpha ta = wrapper.inputBlockerInstance.GetComponentInChildren <TweenAlpha>(); ta.tweenFactor = 0.0f; wrapper.inputBlockerInstance.GetComponentInChildren <UISprite>().alpha = 0.05f; } } GameUtils.SetMainCameraActive(_backStack.Peek().stackable.IsRenderingWorldWhileFullscreen()); } else { // No full screen, show the HUD _isFullScreenOpened = false; } } while (tempStack.Count > 0) { _backStack.Push(tempStack.Pop()); } } else { // There's nothing in the stack, so no full screen, no blocker _isFullScreenOpened = false; _isInputBlockerVisible = false; } if (!_isFullScreenOpened && !IsLoadingScreenUp) { GameUtils.SetMainCameraActive(true); } if (wrapper.stackable == _currentQueuedStackableDisplayed) { _currentQueuedStackableDisplayed = null; } if (_enstackFlag == 0 && _backstackFlag == 0 && !isPartOfExitStack) { wrapper.stackable.OnBlur(); } _enstackFlag = 0; _backstackFlag = 0; _backstackFlag = ++s_seed; var currentFlag = _backstackFlag; wrapper.stackable.ClearData(); yield return(StartCoroutine(wrapper.stackable.OnRemoveFromStack())); if (currentFlag == _backstackFlag) { _backstackFlag = 0; if (_backStack.Count > 0 && !isPartOfExitStack) { //EB.Debug.LogWarning("Backstack: finish {0} onfocus", backStack.Peek().stackable); _backStack.Peek().stackable.OnFocus(); } else { //EB.Debug.LogWarning("Backstack: finish"); } if (!isPartOfExitStack) { OnFinishedBackstacking(); } } }
/// <summary> /// 入栈的协程 /// </summary> /// <param name="stackable"></param> /// <param name="manualDepth"></param> /// <returns></returns> private IEnumerator EnStackCoroutine(IStackableUI stackable) { if (stackable != null && !stackable.Equals(null)) { // disable Main Camera if (stackable.IsFullscreen()) { _isFullScreenOpened = true; GameUtils.SetMainCameraActive(stackable.IsRenderingWorldWhileFullscreen()); } // OnBlur Event on top ui if (_backStack.Count > 0) { if (_enstackFlag == 0 && _backstackFlag == 0) { _backStack.Peek().stackable.OnBlur(); } } _enstackFlag = 0; _backstackFlag = 0; // Create wrapper IStackableWrapper wrapper = new IStackableWrapper(); wrapper.stackable = stackable; // Insert an input blocker if needed if (stackable.ShowUIBlocker) { _isInputBlockerVisible = true; wrapper.inputBlockerInstance = GameObject.Instantiate(inputBlockerPrefab); wrapper.inputBlockerInstance.name = string.Format("InputBlockerFor{0}", stackable.ToString()); wrapper.inputBlockerInstance.transform.SetParent(gameObject.transform); wrapper.inputBlockerInstance.transform.localPosition = Vector3.zero; wrapper.inputBlockerInstance.transform.localScale = Vector3.one; wrapper.inputBlockerInstance.GetComponentInChildren <UISprite>().alpha = 0.05f; TweenAlpha ta = wrapper.inputBlockerInstance.GetComponentInChildren <TweenAlpha>(); ta.tweenFactor = 1.0f; //0.0f ta.PlayForward(); } // Warn other screens that we're about to stack someone if (onEnstack != null) { onEnstack(stackable); } _nextStackDepth = AssignDepths(wrapper); // Hide below, set visible variables EB.Collections.Stack <IStackableWrapper> tempStack = new EB.Collections.Stack <IStackableWrapper>(); while (_backStack.Count > 0) { tempStack.Push(_backStack.Pop()); if (stackable.IsFullscreen()) { tempStack.Peek().stackable.Show(false); } if (tempStack.Peek().inputBlockerInstance != null && (stackable.ShowUIBlocker || stackable.IsFullscreen())) { if (stackable.IsFullscreen() && wrapper.inputBlockerInstance == null) { _isInputBlockerVisible = false; } // hide blocker for next frame var tempPanel = tempStack.Peek().inputBlockerInstance.GetComponent <UIPanel>(); if (wrapper.inputBlockerInstance && wrapper.inputBlockerInstance.name.Contains("DataPanelNew")) { tempPanel.alpha = 0.0f; } else { EB.Coroutines.EndOfFrame(delegate() { tempPanel.alpha = 0.0f; }); } } } while (tempStack.Count > 0) { _backStack.Push(tempStack.Pop()); } // Fix again if (_isInputBlockerVisible && stackable.IsFullscreen() && wrapper.inputBlockerInstance == null) { _isInputBlockerVisible = false; } // Place stackable _backStack.Push(wrapper); _fullStack.Push(wrapper); // OnFocus Event _enstackFlag = ++s_seed; int currentFlag = _enstackFlag; yield return(StartCoroutine(stackable.OnAddToStack())); if (_enstackFlag == currentFlag && !IsLoadingScreenUp) { _enstackFlag = 0; stackable.OnFocus(); } } }