Skip to end of metadata
Go to start of metadata


This tutorial is for building a SceneGraph Developer Extensions (SGDEX) based channel. Developers who want to build their first Roku channel, or are interested in moving their existing channel to RSG, benefit from this guide.

SGDEX includes the following views:

  • Grid
  • Details
  • Video with endcard view
  • Category list
  • Entitlement

Combining the views listed above, the developer can create their channel without a deep knowledge of Roku SceneGraph components.

Creating a project

Using an IDE, create a new project or use an existing project

Make sure the app manifest contains:

All views are developed in HD resolution and autoscaled to FHD and SD. Make sure to develop the views for the app in HD resolution as well.

Required files

File structure

 

In the source folder, create a file main.brs and populate it with the following:

Contents of main.brs

The code above creates the scene and is the first step in building an app.

Here, "MainScene" is the name of the scene.

Developing a channel

To develop a SGDEX channel, create a Scene that extends from BaseScene.

Scene

The XML file contains the following:

 

In /components/MainScene.brs, add:

This function passes params from main.brs and decides what view is displayed.

You can display a home screen(view), or create a deep linking screen(view) here by passing the proper params.

 

The scene has a ComponentController interface field that is used to show views and control flows.

ComponentController

A componentController is the component that controls all views.

Interface

Fields

FieldDescription
currentScreenThe view that is currently shown
shouldCloseLastScreenOnBackIndicates if the last screen in the stack should be closed before the channel exits


Manipulate this screen if the channel needs to implement deep linking or, a confirm exit dialog when the user presses back on the first screen.

Function interface

FunctionUse
showUsed to add a new view to the stack

Showing the first view

To show the first view, the developer needs to create the view, add content to it, and then display it.

Example

In /components/MainScene.brs, add the following to indicate the show(args) function:

The above code creates a simple grid view and displays it.

 

All views that extend Component have the following interfaces:

View UI setup

FieldDescription
styleThe style to be used, see the documentation for each view
posterShapeThe shape of the poster to be used in this view
contentView's content
overhangCongifure the overhang node to customize each view of your channel. For example, some views can have options or another logo or title

View visibility handling

  
wasClosedTriggered when the current view is closed. Use this when reading any value from a closed view. For example, itemFocused to set proper focus on the previous screen
saveState Triggered when a new view is opened after the current view. It is useful when data needs to be saved before another view is opened. For example, pause audio or video when a new view is opened
wasShownTriggered when the current view is opened for the first time or restored after the top view was closed
closeUse this field to manually close view. For example, during a registration flow, all registration views are closed after successful login

 

If the developer does not have content for the grid, use HandlerConfigGrid that describes how to populate rows for grid view:

Content Getters

A content getter is a component responsible for populating content for views.

To load certain data for a view, use content getters.

To add root Content Getter, add it to the content of the created view:

 

Each SGDEX view has an Associative Array (AA) Content Getter field and contains the following: 

name [required] - Project Content Getter component name

fields [optional] - Developer interface fields to be populated

Default Content Getter

Interfaces

Content getter provides a predefined list of interfaces:

FieldDescription
contentContentto be modified by the content getter. This content can be the view's content field or a child of it when the content for the child needs to be loaded (Example, a row in the grid or an item in the details or video view)
handlerConfig

Config added by the developer. Use handlerConfig to read the value of the config or restore it to content if needed

Note: Content getter removes processed Configs. If data needs to be reloaded each time content is shown, restore the config for the content in the proper Content Getter

offsetIndicates which offset is in use. Use offset for horizontal lazy loading of the grid row
pageSizeIndicates the page size configured by the developer. Used for horizontal lazy loading of the grid row

Implementing Content Getter

To implement a Content Getter, create a component and extend it from ContentHandler.

Example

 

Content Getter implements only one required function GetContent() that does not return anything:


Contents of the JSON file

 

Note: According to SceneGraph best practices, it is suggested to use

As this removes multiple rendezvous between the render thread and the task node.

Opening next view

To open a new view for a certain action, use the same mechanism to create and populate the view.

For example, to open details screen upon selection on a grid, use:

Assuming the following has been executed,

 

Implement the function OnGridItemSelected:

DetailsView

In /components/DetailsScreenLogic.brs

The above code creates new details view and passes grid row as the content for details. It also uses jumpToItem to set starting index.

 

If the developer does not want to pass a list of items but only one item, they can use the snippet below:


Details view interfaces

Details view provides several interfaces:

buttons type = "node"

Buttons content node

Buttons support same content meta-data fields as Label list which sets the title as well as a small icon for each button.

FieldTypeDescription
TITLE StringThe label for the list item
HDLISTITEMICONURLUriThe image file for the icon displayed to the left of the list item label when the list item is not focused


Field description

FieldTypeDefaultDescription
isContentListBooleanTrue

Tells details view how your content is structured

  • If set to true it will take children of content to display on the screen
  • If set to false it will take content and display it on the screen
allowWrapContentBooleanTrue

Defines the logic of showing content when pressing left on the first item or pressing right on the last item

If set to true, it starts playback from first item (when pressing right) or the last item (when pressing left)  

itemFocusedInteger0Indicates the item currently in focus
jumpToItemInteger0Manually focus on the desired item
buttonFocused Integer0Tells what button is focused
buttonSelectedInteger0Is set when the button is selected by a user
jumpToButtonInteger0Interface for setting the focused button
currentItemNode-

Currently displayed item

This item is set when the Content Getter finishes loading extra meta-data  

Getting extra metadata for details view

Sometimes when setting content to details view you are still pending some info to be loaded to properly show this item.

To resolve this issue you should use content getter for details screen.

Opening non-SGDEX view

SGDEX is not limited to use only SGDEX views; the channel can show its own view and observe its fields.

To open a non-SGDEX view, create, and populate interface fields, set observers and call:

This hides the current view (if any) and displays the non-SGDEX view.

Note: Component controller set's focus on your view, so your view should implement proper focus handling.


Example

 

In /components/customView.brs, add:

Whenever the view receives focus, it should be checked if it's in the focus chain and the node unfocused.

 

Focus handling is important as component controller sets focus to a non-SGDEX view in two cases:

  • The view is just shown
  • The view is restored after top view was closed

Component Controller is responsible for closing this view when the back button is pressed.

If the view needs to be closed manually, a new field called "close" should be added to the view. 

By setting yourView.close = true, the developer can close the current view and the previous view is opened.

  • No labels