예제 #1
0
    /// <summary>
    /// 分配的UI深度
    /// </summary>
    private int AssignDepths(IStackableWrapper wrapper)
    {
        int stackDepth = _nextStackDepth;

        int originStartSortingOrder = wrapper.lastSortingOrder = wrapper.firstSortingOrder = GetHighestSortingOrder();

        if (wrapper.stackable is Component)
        {
            List <UIPanel>  panels    = new List <UIPanel>();
            List <Renderer> renderers = new List <Renderer>();

            panels.AddRange(((Component)wrapper.stackable).GetComponentsInChildren <UIPanel>(true));
            renderers.AddRange(((Component)wrapper.stackable).GetComponentsInChildren <Renderer>(true));

            panels.Sort((UIPanel panel1, UIPanel panel2) => panel1.sortingOrder != panel2.sortingOrder ? panel1.sortingOrder - panel2.sortingOrder : panel1.depth - panel2.depth);
            renderers.Sort((Renderer r1, Renderer r2) => r1.sortingOrder - r2.sortingOrder);

            if (wrapper.inputBlockerInstance != null)
            {
                if (panels.Count == 0)
                {
                    EB.Debug.LogWarning("AssignDepths: need panel above blocker on {0}", wrapper.stackable);
                    UIPanel uiPanel = ((Component)wrapper.stackable).gameObject.AddComponent <UIPanel>();
                    panels.Add(uiPanel);
                }

                UIPanel blockerPanel = wrapper.inputBlockerInstance.GetComponent <UIPanel>();
                blockerPanel.depth        = panels[0].depth - 1;
                blockerPanel.sortingOrder = panels[0].sortingOrder;
                panels.Insert(0, blockerPanel);
            }

            if (panels.Count > 0)
            {
                int currentOffset = 0;
                int previousDepth = panels[0].depth;

                panels[0].renderQueue = UIPanel.RenderQueue.StartAt;

                panels[0].depth = stackDepth;

                wrapper.firstStackDepth = panels[0].depth;

                int previousSortingOrder = originStartSortingOrder = panels[0].sortingOrder;
                panels[0].sortingOrder = wrapper.firstSortingOrder;
                int sortingOrder = panels[0].sortingOrder;
                for (int i = 1; i < panels.Count; i++)
                {
                    int currentSortingOrderOffset = panels[i].sortingOrder - previousSortingOrder;
                    previousSortingOrder     = panels[i].sortingOrder;
                    panels[i].sortingOrder   = sortingOrder + currentSortingOrderOffset;
                    sortingOrder             = panels[i].sortingOrder;
                    wrapper.lastSortingOrder = Mathf.Max(sortingOrder, wrapper.lastSortingOrder);
                    if (currentSortingOrderOffset > 0)
                    {
                        previousDepth   = panels[i].depth;
                        panels[i].depth = stackDepth + currentSortingOrderOffset + 100;
                        stackDepth      = panels[i].depth;
                    }
                    else
                    {
                        currentOffset   = panels[i].depth - previousDepth;
                        previousDepth   = panels[i].depth;
                        panels[i].depth = stackDepth + currentOffset;
                        stackDepth      = panels[i].depth;
                    }
                }

                panels[0].SetDirty();
            }
            else
            {
                wrapper.firstStackDepth = stackDepth;
            }

            if (renderers.Count > 0)
            {
                int previousSortingOrder = originStartSortingOrder;
                int sortingOrder         = wrapper.firstSortingOrder;

                List <Material> materials = new List <Material>();
                for (int i = 0; i < renderers.Count; i++)
                {
                    if (renderers[i].materials != null)
                    {
                        materials.AddRange(renderers[i].materials);
                    }

                    SetSortingOrder sso = renderers[i].GetComponent <SetSortingOrder>();
                    int             currentSortingOrder       = sso != null ? sso.SortingOrder : 0;
                    int             currentSortingOrderOffset = currentSortingOrder - previousSortingOrder;
                    previousSortingOrder = currentSortingOrder;
                    sortingOrder         = sortingOrder + currentSortingOrderOffset;
                    if (sso != null)
                    {
                        sso.SortingOrder = sortingOrder;
                    }
                    wrapper.lastSortingOrder = Mathf.Max(sortingOrder, wrapper.lastSortingOrder);
                }

                if (materials.Count > 0)
                {
                    materials.Sort((Material m1, Material m2) => m1.renderQueue - m2.renderQueue);
                }
            }
        }
        else
        {
            wrapper.firstStackDepth = stackDepth;
        }

        stackDepth += 10;
        return(stackDepth);
    }
예제 #2
0
    /// <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();
            }
        }
    }
예제 #3
0
    /// <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();
            }
        }
    }
예제 #4
0
    /// <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()));
    }