Advanced Focus Management

In most situations, the default behavior of focus management for You.i React Native apps should meet your needs, but there may be times when it does not. The following advanced focus management topics cover the fundamentals required to understand how You.i Engine One focus management works and how to override default behavior.

Consider the following important terms and concepts when working with You.i Engine One focus management:

The following diagram shows the process of creating a SceneTree from an After Effects file.

The diagram illustrates the process behind how a SceneTree is created.

SceneTree

A SceneTree contains a group of objects arranged in an hierarchical order for use in rendering. Each object has a spatial and logical relation between other objects.

The scene tree can be seen at runtime using the Scene Tree Viewer option in the Debug panel The following code snippet shows a typical SceneTree:

<CYIStackView name="StackView" drawParent="Main" WorldBB="x:     0, y:     0, w:    1881, h:    1534" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="400" Y="400" >
<CYIPerspectiveCameraSceneNode name="Camera 1" drawParent="StackView" WorldBB="x:   400, y:   400, w:       0, h:       0" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="400" Y="400" Target="No Target Specified" UpVector="(0,-1,0)" NearPlane="0.1" FarPlane="20000" FOV="13.5071" >
</CYIPerspectiveCameraSceneNode>
<CYISceneView name="StreamingView" drawParent="StackView" WorldBB="x: 19.55, y: 22.01, w:   760.9, h:     711" CompositeOpacity="1" LocalOpacity="1" Visibility="Hidden" X="400" Y="400" >
<FocusView name="FocusableItem" drawParent="StreamingView" WorldBB="x:  22.5, y: 24.01, w:     200, h:     200" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="122.495" Y="124.008" >
<CYISceneNode name="Black Solid 1" drawParent="FocusableItem" WorldBB="x:  22.5, y: 24.01, w:     200, h:     200" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="100" Y="100" >
</CYISceneNode>
<CYISceneNode name="White Solid 1" drawParent="FocusableItem" WorldBB="x:  32.5, y: 34.01, w:     180, h:     180" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="100" Y="100" >
</CYISceneNode>
<CYISceneNode name="Medium Purple Solid 1" drawParent="FocusableItem" WorldBB="x:  22.5, y: 24.01, w:     200, h:     200" CompositeOpacity="0" LocalOpacity="0" Visibility="Visible" X="100" Y="100" >
</CYISceneNode>
<CYIAtlasTextSceneNode name="Placeholder-Text" drawParent="FocusableItem" WorldBB="x: 122.5, y:   124, w:       0, h:       0" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="100" Y="100"  text="">
</CYIAtlasTextSceneNode>
</FocusView>
<FocusView name="FocusableItem" drawParent="StreamingView" WorldBB="x: 580.5, y:   368, w:     200, h:     200" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="680.495" Y="468.008" >
<CYISceneNode name="Black Solid 1" drawParent="FocusableItem" WorldBB="x: 580.5, y:   368, w:     200, h:     200" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="100" Y="100" >
</CYISceneNode>
<CYISceneNode name="White Solid 1" drawParent="FocusableItem" WorldBB="x: 590.5, y:   378, w:     180, h:     180" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="100" Y="100" >
</CYISceneNode>
<CYISceneNode name="Medium Purple Solid 1" drawParent="FocusableItem" WorldBB="x: 580.5, y:   368, w:     200, h:     200" CompositeOpacity="0" LocalOpacity="0" Visibility="Visible" X="100" Y="100" >
</CYISceneNode>
<CYIAtlasTextSceneNode name="Placeholder-Text" drawParent="FocusableItem" WorldBB="x: 680.5, y:   468, w:       0, h:       0" CompositeOpacity="1" LocalOpacity="1" Visibility="Visible" X="100" Y="100"  text="">
</CYIAtlasTextSceneNode>
</FocusView>

Refer to the following diagram to see a visual representation of the SceneTree showing all the logical relationships:

Visual representation of a SceneTree

SceneNode

The objects that are part of SceneTree are called SceneNodes. A SceneNode, which has the CYISceneNode class, is the basis of all visual elements that you see on screen, such as buttons, views, images, and so on. Using CYISceneNode class, a SceneNode gives required functionality for input, signals, and animation.

Some the important tasks a SceneNode can do are:

  • drawing order relationships
  • spatial transformation hierarchy, such as information about scene position and size in in both local and world coordinates
  • nodes can be detached and placed anywhere in the scene tree

  • render into different render targets for the purpose of off-screen rendering
  • CYISceneNode is similar to the React Native’s View component

Scene nodes provide parent/child relationships and inherit properties such as, clipping, opacity, and visibility.

FocusRoot

By default, the root of a SceneTree is a focus root. Therefore, when focus enters a focus root, focus is constrained to its descendants until:

  • it is deleted, or
  • it becomes hidden, or
  • it is detached from the main tree

When focus leaves a focus root, focus returns to the last view that had focus in the parent focus root. If that view is no longer focusable, another view in the parent focus root is given focus. If no views in the parent focus root are focusable, focus leaves that focus root. If there are no focusable views, focus is cleared using CYISceneManager::ClearFocus().

For more information, see the Focus Manager module.

Focus Timelines

SceneViews have timelines that play an important part in defining its interactivity and visual behavior. Also, there are dedicated Focus timelines for the UI component used in a scene.

Marker What it does
FocusIn Plays the animation on a view when the focus is gained.
FocusOut Plays the animation on a view when the focus is lost.

Focus Management Rules

Before working on focus management for a view, you should be aware of the rules for deciding if it can be focused or not. The first two are mandatory. The remaining ones may apply depending on circumstances:

Rule One - Focusability

Before moving focus to a particular view, you must ensure that the view is focusable using CYISceneView::IsFocusable(). It returns either True or False.

Once it is confirmed that a view is focusable (that is, IsFocusable()=True), other rules can be verified.

See the following code snippet for using IsFocusable():

if (!pView->IsFocusable())
{
	YI_LOGE("ViewName", "View is not focusable");
}

Rule Two - Reachability

Once you know that the view is focusable and that the node that has the view is visible, you need to verify that the view is reachable from the SceneManager; that is, the presence of SceneView on the staged screen. To do this, use CYISceneManager::IsReachable().

See the following code snippet for using IsReachable():

if (!pView->GetSceneManger()->IsReachable())
{
	YI_LOGE("View Name", "View is not visible");
}

Other Important Points

Consider the following points related to focus management rules:

  • A focusable view should be able to visually indicate that it has received focus. The focus timeline should have an animation that makes it easy for the user to see when the view has gained focus. For example, the following animation shows the highlighting of buttons when they receive focus:

    Image   

  • Once the view receives focus, You.i TV recommends that it perform some action. For example, the button at the bottom of the screen opens a new screen after it receives focus:

    Image

  • A disabled button never receives focus.
  • For a view to become an eligible candidate to receive focus, it must be within the focus search area.
  • A view within another view never receives focus. For example, the bigger view (H) contains a smaller view (I) within it. The smaller view (I) never gets focus.

    Image