public virtual void OnLeave(bool NeedPool = true, bool ignoreTransition = false)
 {
     DisableGameObjectOnComplete = !NeedPool;
     if (leaveCoroutine != null)
     {
         viewController.StopMicroCoroutine(leaveCoroutine);
         leaveCoroutine = null;
     }
     leaveCoroutine = viewController.StartMicroCoroutine(OnLeaveRunner(NeedPool, ignoreTransition));
 }
 public virtual void OnShow(bool manual = false)
 {
     if (showCoroutine != null)
     {
         viewController.StopMicroCoroutine(showCoroutine);
         showCoroutine = null;
     }
     if (leaveCoroutine != null)
     {
         viewController.StopMicroCoroutine(leaveCoroutine);
         leaveCoroutine = null;
     }
     showCoroutine = viewController.StartMicroCoroutine(OnShowRunner(manual));
 }
        public void OnLeaveAnimationFinish()
        {
            IsShowed       = false;
            OnLeaveWorking = false;
            leaveCoroutine = null;
            if (_allGraphics != null)
            {
                for (int i = 0; i < _allGraphics.Length; i++)
                {
                    GraphicRegistry.UnregisterGraphicForCanvas(_allGraphics[i].canvas, _allGraphics[i]);
                }
            }
            //先 SetParent 就好除了被託管的
            if (DisableGameObjectOnComplete)
            {
                SetActive(false);
            }

            if (needPool == false)
            {
                return;
            }

            if (runtimePool != null)
            {
                runtimePool.QueueViewElementToRecovery(this);
                OnBeforeRecoveryToPool?.Invoke();
                OnBeforeRecoveryToPool = null;
                if (runtimeOverride != null)
                {
                    runtimeOverride.ResetToDefaultValues();
                }
            }
            else if (DestroyIfNoPool)
            {
                // if there is no runtimePool instance, destroy the viewelement.
                Destroy(gameObject);
            }
        }
        public IEnumerator OnLeaveRunner(bool NeedPool = true, bool ignoreTransition = false)
        {
            //ViewSystemLog.LogError("OnLeave " + name);
            if (transition == TransitionType.Animator && hasLoopBool)
            {
                animator.SetBool(ButtonAnimationBoolKey, false);
            }
            needPool       = NeedPool;
            OnLeaveWorking = true;

            if (lifeCyclesObjects != null)
            {
                foreach (var item in lifeCyclesObjects.ToArray())
                {
                    try
                    {
                        item.OnBeforeLeave();
                    }
                    catch (Exception ex) { ViewSystemLog.LogError(ex.Message, this); }
                }
            }

            if (selfViewElementGroup != null)
            {
                selfViewElementGroup.OnLeaveChild(ignoreTransition);
            }

            //在試圖 leave 時 如果已經是 disable 的 那就直接把他送回池子
            //如果 ignoreTransition 也直接把他送回池子
            if (gameObject.activeSelf == false || ignoreTransition)
            {
                goto END;
            }
            if (transition == TransitionType.Animator)
            {
                try
                {
                    if (animatorTransitionType == AnimatorTransitionType.Direct)
                    {
                        if (animator.HasState(0, Animator.StringToHash(AnimationStateName_Out)))
                        {
                            animator.Play(AnimationStateName_Out);
                        }
                        else
                        {
                            animator.Play("Disable");
                        }
                    }
                    else
                    {
                        animator.ResetTrigger(AnimationStateName_Out);
                        animator.SetTrigger(AnimationStateName_Out);
                    }
                }
                catch
                {
                    goto END;
                }
            }
            else if (transition == TransitionType.CanvasGroupAlpha)
            {
                if (canvasGroup == null)
                {
                    ViewSystemLog.LogError("No Canvas Group Found on this Object", this);
                }

                if (canvasGroupCoroutine != null)
                {
                    viewController.StopMicroCoroutine(canvasGroupCoroutine);
                }
                // canvasGroupCoroutine = viewController.StartMicroCoroutine(EaseMethods.EaseValue(
                //     canvasGroup.alpha,
                //     0,
                //     canvasOutTime,
                //     EaseMethods.GetEase(canvasOutEase),
                //     (v) =>
                //     {
                //         canvasGroup.alpha = v;
                //     },
                //     () =>
                //     {
                //         canvasGroupCoroutine = null;
                //     }
                //     ));

                canvasGroupCoroutine = viewController.StartMicroCoroutine(
                    EaseUtility.To(
                        canvasGroup.alpha,
                        0,
                        canvasOutTime,
                        canvasOutEase,
                        (v) =>
                {
                    canvasGroup.alpha = v;
                },
                        () =>
                {
                    canvasGroupCoroutine = null;
                }
                        )
                    );

                goto END;
            }
            else if (transition == TransitionType.Custom)
            {
                OnLeaveHandle.Invoke(OnLeaveAnimationFinish);
            }
            else
            {
                goto END;
            }

END:
            if (!ignoreTransition && !isSkipOutAnimation)
            {
                float time        = 0;
                var   outDuration = GetOutDuration();
                while (time < outDuration)
                {
                    time += GlobalTimer.deltaTime;
                    yield return(null);
                }
            }

            if (lifeCyclesObjects != null)
            {
                foreach (var item in lifeCyclesObjects.ToArray())
                {
                    try
                    {
                        item.OnStartLeave();
                    }
                    catch (Exception ex) { ViewSystemLog.LogError(ex.Message, this); }
                }
            }
            leaveCoroutine = null;
            OnLeaveAnimationFinish();
            // });
        }
        public IEnumerator OnShowRunner(bool manual)
        {
            IsShowed = true;
            if (lifeCyclesObjects != null)
            {
                foreach (var item in lifeCyclesObjects.ToArray())
                {
                    try
                    {
                        item.OnBeforeShow();
                    }
                    catch (Exception ex) { ViewSystemLog.LogError(ex.ToString(), this); }
                }
            }

            SetActive(true);

            if (selfViewElementGroup != null)
            {
                if (selfViewElementGroup.OnlyManualMode && manual == false)
                {
                    if (gameObject.activeSelf)
                    {
                        SetActive(false);
                    }
                    goto END;
                }
                selfViewElementGroup.OnShowChild();
            }

            if (transition == TransitionType.Animator)
            {
                animator.Play(AnimationStateName_In);

                if (transition == TransitionType.Animator && hasLoopBool)
                {
                    animator.SetBool(ButtonAnimationBoolKey, true);
                }
            }
            else if (transition == TransitionType.CanvasGroupAlpha)
            {
                canvasGroup.alpha = 0;
                if (canvasGroupCoroutine != null)
                {
                    viewController.StopMicroCoroutine(canvasGroupCoroutine);
                }
                // canvasGroupCoroutine = viewController.StartMicroCoroutine(EaseMethods.EaseValue(
                //     canvasGroup.alpha,
                //     1,
                //     canvasInTime,
                //     EaseMethods.GetEase(canvasInEase),
                //     (v) =>
                //     {
                //         canvasGroup.alpha = v;
                //     },
                //     () =>
                //     {
                //         canvasGroupCoroutine = null;
                //     }
                //  ));
                canvasGroupCoroutine = viewController.StartMicroCoroutine(
                    EaseUtility.To(
                        canvasGroup.alpha,
                        1,
                        canvasInTime,
                        canvasInEase,
                        (v) =>
                {
                    canvasGroup.alpha = v;
                },
                        () =>
                {
                    canvasGroupCoroutine = null;
                }
                        )
                    );
            }
            else if (transition == TransitionType.Custom)
            {
                OnShowHandle.Invoke(null);
            }

END:
            if (lifeCyclesObjects != null)
            {
                foreach (var item in lifeCyclesObjects.ToArray())
                {
                    try
                    {
                        item.OnStartShow();
                    }
                    catch (Exception ex) { ViewSystemLog.LogError(ex.ToString(), this); }
                }
            }
            if (_allGraphics != null)
            {
                for (int i = 0; i < _allGraphics.Length; i++)
                {
                    if (_allGraphics[i].raycastTarget == false)
                    {
                        GraphicRegistry.UnregisterGraphicForCanvas(_allGraphics[i].canvas, _allGraphics[i]);
                    }
                }
            }
            showCoroutine = null;
            yield break;
        }
        public IEnumerator OnChangePageRunner(bool show, Transform parent, ViewElementTransform rectTransformData, float TweenTime, float delayIn, bool ignoreTransition, bool reshowIfSamePage)
        {
            if (lifeCyclesObjects != null)
            {
                foreach (var item in lifeCyclesObjects.ToArray())
                {
                    try
                    {
                        item.OnChangePage(show);
                    }
                    catch (Exception ex) { ViewSystemLog.LogError(ex.ToString(), this); }
                }
            }
            if (show)
            {
                if (parent == null)
                {
                    ViewSystemLog.LogError($"{gameObject.name} does not set the parent for next viewpage.", this);
                    goto END;
                    //throw new NullReferenceException(gameObject.name + " does not set the parent for next viewpage.");
                }
                //停掉正在播放的 Leave 動畫
                if (leaveCoroutine != null)
                {
                    // viewController.StopCoroutine(OnLeaveCoroutine);
                }
                //還在池子裡,應該先 OnShow
                //或是正在離開,都要重播 OnShow
                if (IsShowed == false || OnLeaveWorking)
                {
                    rectTransform.SetParent(parent, true);

                    if (rectTransformData == null || !string.IsNullOrEmpty(rectTransformData.parentPath))
                    {
                        rectTransform.anchoredPosition3D = Vector3.zero;
                        rectTransform.localScale         = Vector3.one;
                    }
                    else
                    {
                        ApplyRectTransform(rectTransformData);
                    }

                    float time = 0;
                    while (time < delayIn)
                    {
                        time += GlobalTimer.deltaTime;
                        yield return(null);
                    }
                    OnShow();
                    goto END;
                }
                //已經在場上的
                else
                {
                    //如果目前的 parent 跟目標的 parent 是同一個人 那就什麼事都不錯
                    if ((rectTransformData == null || !string.IsNullOrEmpty(rectTransformData.parentPath)) && parent.GetInstanceID() == rectTransform.parent.GetInstanceID())
                    {
                        //ViewSystemLog.LogWarning("Due to already set the same parent with target parent, ignore " +  name);
                        if (reshowIfSamePage)
                        {
                            OnShow();
                        }
                        goto END;
                    }
                    //其他的情況下用 Tween 過去
                    if (TweenTime >= 0)
                    {
                        rectTransform.SetParent(parent, true);
                        if (rectTransformData == null || !string.IsNullOrEmpty(rectTransformData.parentPath))
                        {
                            var marginFixer = GetComponent <ViewMarginFixer>();
                            viewController.StartMicroCoroutine(EaseUtility.To(
                                                                   rectTransform.anchoredPosition3D,
                                                                   Vector3.zero,
                                                                   TweenTime,
                                                                   EaseStyle.QuadEaseOut,
                                                                   (v) =>
                            {
                                rectTransform.anchoredPosition3D = v;
                            },
                                                                   () =>
                            {
                                if (marginFixer)
                                {
                                    marginFixer.ApplyModifyValue();
                                }
                            }
                                                                   ));

                            viewController.StartMicroCoroutine(EaseUtility.To(
                                                                   rectTransform.localScale,
                                                                   Vector3.one,
                                                                   TweenTime,
                                                                   EaseStyle.QuadEaseOut,
                                                                   (v) =>
                            {
                                rectTransform.localScale = v;
                            }
                                                                   ));
                        }
                        else
                        {
                            rectTransform.SetParent(parent, true);
                            var flag = rectTransformData.rectTransformFlag;
                            FlagsHelper.Unset(ref flag, RectTransformFlag.AnchoredPosition);
                            FlagsHelper.Unset(ref flag, RectTransformFlag.LocalScale);

                            ApplyRectTransform(rectTransformData, flag);

                            viewController.StartMicroCoroutine(EaseUtility.To(
                                                                   rectTransform.anchoredPosition3D,
                                                                   rectTransformData.rectTransformData.anchoredPosition,
                                                                   TweenTime,
                                                                   EaseStyle.QuadEaseOut,
                                                                   (v) =>
                            {
                                rectTransform.anchoredPosition3D = v;
                            },
                                                                   () =>
                            {
                            }
                                                                   ));
                            viewController.StartMicroCoroutine(EaseUtility.To(
                                                                   rectTransform.localScale,
                                                                   rectTransformData.rectTransformData.localScale,
                                                                   TweenTime,
                                                                   EaseStyle.QuadEaseOut,
                                                                   (v) =>
                            {
                                rectTransform.localScale = v;
                            },
                                                                   () =>
                            {
                            }
                                                                   ));
                        }

                        goto END;
                    }
                    //TweenTime 設定為 <0 的情況下,代表要完整 OnLeave 在 OnShow
                    else
                    {
                        float time = 0;
                        while (time < delayIn)
                        {
                            time += GlobalTimer.deltaTime;
                            yield return(null);
                        }
                        OnLeave(ignoreTransition: ignoreTransition);
                        while (OnLeaveWorking == true)
                        {
                            yield return(null);
                        }
                        ViewSystemLog.LogWarning("Try to ReShow ", this);
                        rectTransform.SetParent(parent, true);
                        if (rectTransformData == null || !string.IsNullOrEmpty(rectTransformData.parentPath))
                        {
                            rectTransform.anchoredPosition3D = Vector3.zero;
                            rectTransform.localScale         = Vector3.one;
                        }
                        else
                        {
                            ApplyRectTransform(rectTransformData);
                        }
                        time = 0;
                        while (time < delayIn)
                        {
                            time += GlobalTimer.deltaTime;
                            yield return(null);
                        }
                        OnShow();
                        goto END;
                    }
                }
            }
            else
            {
                OnLeave(ignoreTransition: ignoreTransition);
                goto END;
            }

END:
            changePageCoroutine = null;
            yield break;
        }
 public virtual void ChangePage(bool show, Transform parent, ViewElementTransform rectTransformData, int sortingOrder = 0, float TweenTime = 0, float delayIn = 0, bool ignoreTransition = false, bool reshowIfSamePage = false)
 {
     this.sortingOrder = sortingOrder;
     NormalizeViewElement();
     changePageCoroutine = viewController.StartMicroCoroutine(OnChangePageRunner(show, parent, rectTransformData, TweenTime, delayIn, ignoreTransition, reshowIfSamePage));
 }