コード例 #1
0
        // Searches for a navigable element starting from currentFocusable and scanning along the specified direction.
        // If no elements are found, wraps around from the other side of the panel and scan along the same direction
        // up to currentFocusable. If still no elements are found, returns currentFocusable.
        //
        // Though search order is hierarchy-based, the "best candidate" selection process is intended to be independent
        // from any hierarchy consideration. Scanned elements are validated using an intersection test between their
        // worldBound and a scanning validation rect, currentFocusable's worldBound extended to the panel's limits in
        // the direction of the search (or from the other side during the second "wrap-around" scan).
        //
        // The best candidate is the element whose border is "least advanced" in the scanning direction, using the
        // element's worldBound border opposite from scanning direction, left border when scanning right, right border
        // for scanning left, etc. See FocusableHierarchyTraversal for more details and how further ties are resolved.
        Focusable GetNextFocusable2D(Focusable currentFocusable, ChangeDirection direction)
        {
            if (!(currentFocusable is VisualElement ve))
            {
                ve = m_Root;
            }

            Rect panelBounds = m_Root.worldBoundingBox;
            Rect panelRect   = new Rect(panelBounds.position - Vector2.one, panelBounds.size + Vector2.one * 2);
            Rect rect        = ve.worldBound;
            Rect validRect   = new Rect(rect.position - Vector2.one, rect.size + Vector2.one * 2);

            if (direction == Up)
            {
                validRect.yMin = panelRect.yMin;
            }
            else if (direction == Down)
            {
                validRect.yMax = panelRect.yMax;
            }
            else if (direction == Left)
            {
                validRect.xMin = panelRect.xMin;
            }
            else if (direction == Right)
            {
                validRect.xMax = panelRect.xMax;
            }

            Focusable best = new FocusableHierarchyTraversal
            {
                currentFocusable = ve,
                direction        = direction,
                validRect        = validRect,
                firstPass        = true
            }.GetBestOverall(m_Root);

            if (best != null)
            {
                return(best);
            }

            validRect = new Rect(rect.position - Vector2.one, rect.size + Vector2.one * 2);
            if (direction == Down)
            {
                validRect.yMin = panelRect.yMin;
            }
            else if (direction == Up)
            {
                validRect.yMax = panelRect.yMax;
            }
            else if (direction == Right)
            {
                validRect.xMin = panelRect.xMin;
            }
            else if (direction == Left)
            {
                validRect.xMax = panelRect.xMax;
            }

            best = new FocusableHierarchyTraversal
            {
                currentFocusable = ve,
                direction        = direction,
                validRect        = validRect,
                firstPass        = false
            }.GetBestOverall(m_Root);

            if (best != null)
            {
                return(best);
            }

            return(currentFocusable);
        }
コード例 #2
0
        Focusable GetNextFocusable2D(Focusable currentFocusable, ChangeDirection direction)
        {
            if (!(currentFocusable is VisualElement ve))
            {
                ve = m_Root;
            }

            ve = GetRootFocusable(ve);

            Rect rect      = ve.worldBound;
            Rect validRect = new Rect(rect.position - Vector2.one, rect.size + Vector2.one * 2);

            if (direction == Up)
            {
                validRect.yMin = 0;
            }
            else if (direction == Down)
            {
                validRect.yMax = Screen.height;
            }
            else if (direction == Left)
            {
                validRect.xMin = 0;
            }
            else if (direction == Right)
            {
                validRect.xMax = Screen.width;
            }

            var best = new FocusableHierarchyTraversal
            {
                currentFocusable = ve,
                direction        = direction,
                validRect        = validRect,
                firstPass        = true
            }.GetBestOverall(m_Root);

            if (best != null)
            {
                return(GetLeafFocusable(best));
            }

            validRect = new Rect(rect.position - Vector2.one, rect.size + Vector2.one * 2);
            if (direction == Down)
            {
                validRect.yMin = 0;
            }
            else if (direction == Up)
            {
                validRect.yMax = Screen.height;
            }
            else if (direction == Right)
            {
                validRect.xMin = 0;
            }
            else if (direction == Left)
            {
                validRect.xMax = Screen.height;
            }

            best = new FocusableHierarchyTraversal
            {
                currentFocusable = ve,
                direction        = direction,
                validRect        = validRect,
                firstPass        = false
            }.GetBestOverall(m_Root);

            if (best != null)
            {
                return(GetLeafFocusable(best));
            }

            return(currentFocusable);
        }