protected virtual void OnCanvasGroupChanged()
 {
     // Get the canvas responsible for the tooltip
     this.m_Canvas = UIUtility.FindInParents <Canvas>(this.gameObject);
 }
        public void OnTransitionBegin(UIWindow window, UIWindow.VisualState state, bool instant)
        {
            if (!this.IsActive() || window == null)
            {
                return;
            }

            // Check if we are receiving hide event and we are not showing the overlay to begin with, return
            if (state == UIWindow.VisualState.Hidden && !this.IsVisible())
            {
                return;
            }

            // Prepare transition duration
            float       duration = (instant) ? 0f : window.transitionDuration;
            TweenEasing easing   = window.transitionEasing;

            // Showing a window
            if (state == UIWindow.VisualState.Shown)
            {
                // Increase the window count so we know when to hide the overlay
                this.m_WindowsCount += 1;

                // Check if the overlay is already visible
                if (this.IsVisible() && !this.m_Transitioning)
                {
                    // Bring the window forward
                    UIUtility.BringToFront(window.gameObject);

                    // Break
                    return;
                }

                // Bring the overlay forward
                UIUtility.BringToFront(this.gameObject);

                // Bring the window forward
                UIUtility.BringToFront(window.gameObject);

                // Transition
                this.StartAlphaTween(1f, duration, easing);

                // Toggle block raycast on
                this.m_CanvasGroup.blocksRaycasts = true;
            }
            // Hiding a window
            else
            {
                // Decrease the window count
                this.m_WindowsCount -= 1;

                // Never go below 0
                if (this.m_WindowsCount < 0)
                {
                    this.m_WindowsCount = 0;
                }

                // Check if we still have windows using the overlay
                if (this.m_WindowsCount > 0)
                {
                    return;
                }

                // Transition
                this.StartAlphaTween(0f, duration, easing);

                // Toggle block raycast on
                this.m_CanvasGroup.blocksRaycasts = false;
            }
        }
        /// <summary>
        /// Creates the list and it's options.
        /// </summary>
        protected void CreateList()
        {
            // Get the root canvas
            Canvas rootCanvas = UIUtility.FindInParents <Canvas>(this.gameObject);

            // Reset the last list size
            this.m_LastListSize = Vector2.zero;

            // Clear the option texts list
            this.m_OptionObjects.Clear();

            // Create the list game object with the necessary components
            this.m_ListObject       = new GameObject("UISelectField - List", typeof(RectTransform));
            this.m_ListObject.layer = this.gameObject.layer;

            // Change the parent of the list
            this.m_ListObject.transform.SetParent(this.transform, false);

            // Get the select field list component
            UISelectField_List listComp = this.m_ListObject.AddComponent <UISelectField_List>();

            // Make sure it's the top-most element
            UIAlwaysOnTop aot = this.m_ListObject.AddComponent <UIAlwaysOnTop>();

            aot.order = UIAlwaysOnTop.SelectFieldOrder;

            // Get the list canvas group component
            this.m_ListCanvasGroup = this.m_ListObject.AddComponent <CanvasGroup>();

            // Change the anchor and pivot of the list
            RectTransform rect = (this.m_ListObject.transform as RectTransform);

            rect.localScale = new Vector3(1f, 1f, 1f);
            rect.anchorMin  = Vector2.zero;
            rect.anchorMax  = Vector2.zero;
            rect.pivot      = new Vector2(0f, 1f);

            // Prepare the position of the list
            rect.anchoredPosition = new Vector3(this.listMargins.left, (this.listMargins.top * -1f), 0f);

            // Prepare the width of the list
            float width = (this.transform as RectTransform).sizeDelta.x;

            if (this.listMargins.left > 0)
            {
                width -= this.listMargins.left;
            }
            else
            {
                width += Math.Abs(this.listMargins.left);
            }
            if (this.listMargins.right > 0)
            {
                width -= this.listMargins.right;
            }
            else
            {
                width += Math.Abs(this.listMargins.right);
            }
            rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, width);

            // Hook the Dimensions Change event
            listComp.onDimensionsChange.AddListener(ListDimensionsChanged);

            // Apply the background sprite
            Image image = this.m_ListObject.AddComponent <Image>();

            if (this.listBackgroundSprite != null)
            {
                image.sprite = this.listBackgroundSprite;
            }
            image.type  = this.listBackgroundSpriteType;
            image.color = this.listBackgroundColor;

            // Prepare the vertical layout group
            VerticalLayoutGroup layoutGroup = this.m_ListObject.AddComponent <VerticalLayoutGroup>();

            layoutGroup.padding = this.listPadding;
            layoutGroup.spacing = this.listSpacing;

            // Prepare the content size fitter
            ContentSizeFitter fitter = this.m_ListObject.AddComponent <ContentSizeFitter>();

            fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;

            // Get the list toggle group
            ToggleGroup toggleGroup = this.m_ListObject.AddComponent <ToggleGroup>();

            // Create the options
            for (int i = 0; i < this.options.Count; i++)
            {
                // Create the option
                this.CreateOption(i, toggleGroup);

                // Create a separator if this is not the last option
                if (i < (this.options.Count - 1))
                {
                    this.CreateSeparator(i);
                }
            }

            // Prepare the list for the animation
            if (this.listAnimationType == ListAnimationType.None || this.listAnimationType == ListAnimationType.Fade)
            {
                // Starting alpha should be zero
                this.m_ListCanvasGroup.alpha = 0f;
            }
            else if (this.listAnimationType == ListAnimationType.Animation)
            {
                // Attach animator component
                Animator animator = this.m_ListObject.AddComponent <Animator>();

                // Set the animator controller
                animator.runtimeAnimatorController = this.listAnimatorController;

                // Set the animation triggers so we can use them to detect when animations finish
                listComp.SetTriggers(this.listAnimationOpenTrigger, this.listAnimationCloseTrigger);

                // Hook a callback on the finish event
                listComp.onAnimationFinish.AddListener(OnListAnimationFinish);
            }

            // Check if the navigation is disabled
            if (this.navigation.mode == Navigation.Mode.None)
            {
                this.CreateBlocker(rootCanvas);
            }
        }