Search code examples
navigationrokubrightscriptscenegraph

Does Roku have a built in focus management system?


I've been researching this a lot, and have gotten some mixed answers about the way that Roku manages focus. I know Apple TV has a complex manager that determines what the next focused element should be, but in Roku, I'm having some trouble achieving simple behavior.

For example, take this basic Scenegraph component:

<component name="HelloWorld" extends="Scene" initialFocus="exampleButton">
      <script type="text/brightscript" uri="helloworld.brs" />
      <children>
            <Group>
                  <ButtonGroup>
                        <Button
                              id="exampleButton"
                              text="Example Button"
                              showFocusFootprint="true"
                              minWidth="240" />
                        <Button
                              id="exampleButton2"
                              text="Example Button"
                              showFocusFootprint="true"
                              minWidth="240" />
                  </ButtonGroup>

                  <ButtonGroup focusable="true"
                        translation="[0,200]">
                        <Button
                              id="exampleButton3"
                              text="Example Button"
                              showFocusFootprint="true"
                              minWidth="240" />
                        <Button
                              id="exampleButton4"
                              text="Example Button"
                              showFocusFootprint="true"
                              minWidth="240" />
                  </ButtonGroup>
            </Group>
      </children>
</component>

It contains two button groups, displayed vertically on top of each other. For some reason, I can't navigate to the second button group from the first and vice versa. That seems wrong to me and is a giant red flag. Are we expected to implement focus patterns for every view on the screen? Am I missing something?

If I don't set the initialFocus attribute, nothing gets focused and I can't do anything. The only thing I call in the code behind is m.top.setFocus(true) since even the initialFocus attribute doesn't work without that.

Just some clarity on the focus system would be appreciated! Thanks!

For a simpler example, this doesn't work either:

<component name="HelloWorld" extends="Scene" initialFocus="exampleButton">
      <script type="text/brightscript" uri="helloworld.brs" />
      <children>
            <Button
                  id="exampleButton"
                  text="Example Button"
                  showFocusFootprint="true"
                  minWidth="240" />
            <Button
                  id="exampleButton2"
                  text="Example Button 2"
                  showFocusFootprint="true" 
                  minWidth="240"
                  translation="[0,240]" />
      </children>
</component>
    

Is this by design? Why?

I've tried lots of things, like using LayoutGroup or other containers. I really don't want to have to invent a focus management system for every custom component.


Solution

  • The answer is "yeah but not really".

    Like if you have elements in the same container, brightscript will try to handle it. But you're better off making your own if you're moving from component to component.

    hasFocus() will become your best friend.