08

Hands Frame Application 1 – Basic Version

Main Scene

VOD Player

Summary

Chapter 8 demonstrates implementing a simple browsing-type application, “Hands Frame,” and reviews its functions. While the application has a basic design, it covers critical SmartTV application functions such as scene, focus, and player. Hands Frame is a gallery application that can browse various VOD content introducing Handstudio, the author organization of this book.

Briefly, the Hands Frame application has the following structure: The top header displays the company slogan and logo, the left side has a list of categories, and the right pane displays the currently focused category. All these are implemented on one main layer. There are more sublayers, such as company information that will be shown when the remote control Information key is pressed.

For creating and configuring a new project, refer to chapter 4, Hello TV! This chapter does not discuss that topic.

See the next figure for two screen shots of the Hands Frame application.

images

Figure 8-1. Hands Frame > Information Scene

images

Figure 8-2. Hands Frame > Main > Work

Main Scene

Most of the functions of the Hands Frame application, including event handling, run on the main scene. The main scene consists of the left category menu pane, and the right contents pane.

Note that all HTML codes are in the index.html file, JavaScript codes are in the Main.js file, and styles are in the Main.css file.

First, declare a div element for the main scene in the index.html.

<div id=“scene_main”></div>

Header

The header displays static information, including Handstudio's slogan and the application title. The header is not an independent scene and can be simply declared within the main scene.

<div id=“scene_main”>
    <div id=“header”></div>
</div>

The header also does not need its own styles, since it is just an image file.

Category List

A common website uses a top- or left-menu navigation system that is activated by mouse click events to display appropriate content. A TV application uses the same UX, except that the menu focus replaces the mouse clicks. The Hands Frame uses the category list for its navigation menu.

As shown below, add the category element following the header element, in the index.html file.

<div id=“scene_main”>
    <div id=“header”></div>
    <div id=“category”>
        <ul>
            <li class=“work”>Work</li>
            <li class=“people”>People</li>
            <li class=“dream”>Dream</li>
        </ul>
    </div>
 </div>

<a href=“javascript:void(0);” id=“anchor_category” onkeydown=“Main.category.
keyDown();”></a>

The category element is an HTML <div> layer with a <ul> list. The list has three options, each with its own ID and class. Then an anchor for the category element is defined to handle focus and remote control key events.

Next, the following CSS defines styles of the category element.

#category ul{
    list-style: none;
}


#category ul li{
    width: 235px;
    height: 50px;
    color: #fff;
    font-size:20px;
    line-height: 50px;
    text-align: center;
}


#category.focus ul li.focus{
    color: #fff;
    background: URL(“../../images/btn_menu.png”) top;
}


#category.focus ul li.selected{
    color: #c62ad3;
    background: URL(“../../images/btn_menu.png”) bottom;
}

Note that #category.focus ul li.focus was designed to have a distinguished style when it is focused. Note that .focus was declared twice. The first style was to distinguish the whole category menu scene from unfocused other scenes (header and contents), while the second style was to distinguish a selected menu item from the rest, within the category menu.

The category element is frequently used in the code. It is a good practice to assign an object member property of the Main variable, since the category scene is part of the main scene, to easily reference it.

var Main = {
    category : {
        elem : jQuery(‘#category’),
        li     : jQuery(‘#category’).find(‘ul > li’),
        anchor : jQuery(‘#anchor_category’),
    }
};

In addition to the category element, an anchor element needs to be created to receive the focus for the category. Common elements are declared as member objects of Main for easier tracking.

The next event function handles key inputs while the category anchor is focused.

Main.category.keyDown = function()
{

    var keyCode = event.keyCode;

    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
            widgetAPI.sendReturnEvent();
            break;
        case tvKey.KEY_RIGHT:
            break;
        case tvKey.KEY_UP:
            break;
        case tvKey.KEY_DOWN:
            break;
        case tvKey.KEY_INFO :
            break;
        default:
            alert(“Unhandled key”);
            break;
    }
};

If a remote key event is generated while the declared category anchor (id = “anchor_category”) is focused, the onkeydown handler calls Main.category.keyDown().

Main.category.keyDown() obtains the remote key code from the event.keyCode object, and uses a switch statement to assign a code for each remote control key. The above code declared only key events needed by the category anchor, based on the Hands Frame application design.

The next step is defining how each member list element of the category element handles focus. Assume the next situation for this explanation.

  • The application has been running and the category anchor is focused.
  • The category anchor is focused, and its first member element is selected.
  • The member elements do not have an anchor.

To implement focus handling of a selected member element, the new index concept needs to be introduced. An index variable defines which <li> member element is currently selected. The index value changes with the up and down directional keys input, while the category anchor is focused. This index value is also used to apply different styles to the selected list member element.

Pressing the right directional key while the category anchor is focused moves the focus to the content scene for the current category selection. Pressing the up directional key that generally selects the above list member does nothing if the currently selected element is the first <li> element. This applies to the last <li> element on the opposite side.

The “selected” concept is introduced to distinguish the anchorless list elements that cannot be focused in the same way. This new index concept is useful to implement the focus without using anchors.

See the next example for the index system that implements the focus scenario for the category element's member list items. The example only handles the up and down directional keys at this point.

var index = 0;


Main.category.keyDown = function()
{

    var keyCode = event.keyCode;


    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
            widgetAPI.sendReturnEvent();
            break;
        case tvKey.KEY_RIGHT:
            break;
        case tvKey.KEY_UP:
            Main.category.li.eq(index).removeClass(‘focus’);
            Main.category.li.eq(--index).addClass(‘focus’);
            break;
        case tvKey.KEY_DOWN:
            Main.category.li.eq(index).removeClass(‘focus’);
            Main.category.li.eq(++index).addClass(‘focus’);
            break;
        case tvKey.KEY_INFO :
            break;
        default:
            alert(“Unhandled key”);
            break;
    }
};

The category list does not have any target on its left side. Therefore, it should ignore the left directional key input while moving the focus to the content anchor of the selected menu item (in the section area) if there is a right directional key input. As explained in chapter 5 while covering the focus, jQuery's addClass() and removeClass() are used to assign a distinct style to the newly focused element.

Completed source code for the event handling for the category scene is shown below, with some additional code for exception handling.

Main.category.keyDown = function()
{
    var keyCode = event.keyCode;


    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
            widgetAPI.sendReturnEvent();
            break;
        case tvKey.KEY_RIGHT:
            break;
        case tvKey.KEY_UP:
            if(index > 0){
                Main.category.li.eq(index).removeClass(‘focus’);
                Main.category.li.eq(--index).addClass(‘focus’);
            }
            break;
        case tvKey.KEY_DOWN:
            if(index < Main.category.li.size() − 1){
                Main.category.li.eq(index).removeClass(‘focus’);
                Main.category.li.eq(++index).addClass(‘focus’);
            }
            break;
        case tvKey.KEY_INFO :
            break;
        default:
            alert(“Unhandled key”);
            break;
    }
};

Contents Pane

In a standard web page, a menu selection causes a contents pane to load a page for the selected menu. The same user interface also needs to be provided by the Hands Frame applications.

Let's first add <div> elements for the content scenes in the index.html, as shown below.

<div id=“scene_main”>
    <div id=“header”></div>
    <div id=“category”>
        <ul>
            <li class=“work”>Work</li>
            <li class=“people”>People</li>
            <li class=“dream”>Dream</li>
        </ul>
    </div>

    <div id=“content”>
        <div class=“work”>Work</div>
        <div class=“people”>People</div>
        <div class=“dream”>Dream</div>
    </div>
</div>


<a href=“javascript:void(0);” id=“anchor_category” onkeydown=“Main.category.
keyDown();”></a>
<a href=“javascript:void(0);”  id=“anchor_content” onkeydown=“Main.content.
keyDown();”></a>

Each of the content elements is hidden and shown when the corresponding category is selected. Consider these scenes as subscreen layers. Each of the content elements plays a VOD file. See below for styles for the content elements.

#content{
    float: right;
    position: absolute;
    left: 313px;
    top: 92px;
    width: 900px;
}


#content > div{
    width: 100%;
    display: none;
}

Note that the #content > div element has a “display: none;” property setting. As screen layers, all content scenes must be hidden except the one that is currently focused. See the next code for the implementation.

The next function handles the content elements.

Main.loadContent = function(){
    jQuery(‘#content’).find(‘div’).hide();
    jQuery(‘#content’).find(‘div’).eq(index).show();
};

The above function can be called within event-handling code blocks for the up and down keys to show the hidden content scene for the selected category item on the contents pane. Using the categories pane's list to control what's displayed in the contents pane is core logic of the reference application.

Main.category.keyDown = function()
{
    var keyCode = event.keyCode;

    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
            widgetAPI.sendReturnEvent();
            break;
        case tvKey.KEY_RIGHT:
            break;
        case tvKey.KEY_UP:
            if(index > 0){
                Main.category.li.eq(index).removeClass(‘focus’);
                Main.category.li.eq(--index).addClass(‘focus’);
                Main.loadContent();
            }
            break;
        case tvKey.KEY_DOWN:
            if(index < Main.category.li.size() − 1){
                Main.category.li.eq(index).removeClass(‘focus’);
                Main.category.li.eq(++index).addClass(‘focus’);
                Main.loadContent();
            }
            break;
        case tvKey.KEY_INFO :
            break;
        default:
            alert(“Unhandled key”);
            break;
    }
};

After a content scene is displayed in the contents pane, the next step is implementing handing over the focus to the currently displayed content scene. Also, the newly focused content scene needs to be marked. In this example, its font color will be changed to red using the next style element.

#content.focus > div{
    color: red;
}

While the categories anchor is focused, pressing the right directional key transfers the focus to the contents pane. See the following keyDown() function for the implementation within the case block tvKey.KEY_RIGHT:

Main.category.keyDown = function()
{
    var keyCode = event.keyCode;

    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
            widgetAPI.sendReturnEvent();
            break;
        case tvKey.KEY_RIGHT:
            Main.content.anchor.focus();
            Main.category.elem.removeClass(‘focus’);
            Main.content.elem.addClass(‘focus’);
            break;
        case tvKey.KEY_UP:
            if(index > 0){
                Main.category.li.eq(index).removeClass(‘focus’);
                Main.category.li.eq(--index).addClass(‘focus’);
                Main.loadContent();
            }
            break;
        case tvKey.KEY_DOWN:
            if(index < Main.category.li.size() − 1){
                Main.category.li.eq(index).removeClass(‘focus’);
                Main.category.li.eq(++index).addClass(‘focus’);
                Main.loadContent();
            }
            break;
        case tvKey.KEY_INFO :
            break;
        default:
            alert(“Unhandled key”);
            break;
    }
};

The above block transfers the focus to the contents pane's anchor, and marks the newly focused content scene by changing its font color to red. The next code shows how to return the focus back to the category item when the left directional key is pressed.

Main.content.keyDown = function()
{
    var keyCode = event.keyCode;

    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
        case tvKey.KEY_PANEL_RETURN:
            widgetAPI.sendReturnEvent();
            break;
        case tvKey.KEY_LEFT:
            Main.category.anchor.focus();
            Main.content.elem.removeClass(‘focus’);
            Main.category.elem.addClass(‘focus’);
            break;
        case tvKey.KEY_RIGHT:
            break;
        case tvKey.KEY_UP:
            break;
        case tvKey.KEY_DOWN:
            break;
        case tvKey.KEY_ENTER:
        case tvKey.KEY_PANEL_ENTER:
            break;
        default:
            break;
    }
};

The code uses jQuery's addClass() and removeClass() to change styles of focused or unfocused elements to inform users of the current focus. This concludes the Hands Frame application's basic navigation logic for layout, screen changing, and basic focus handling.

Check the addendum for the complete source code of the application to see how the example codes are integrated.

VOD Player

As of now, a newly shown and focused content scene only changes its font color to red to indicate the change. But the original design of the Hands Frame application also includes playing a VOD file.

The Samsung SmartTV's internal AVPlayer module will be used to display the VOD file. Let's jump into actually adding the AVPlayer library within this application, since the library was already well discussed in chapter 7, AV Player.

A container <div> element will be used to contain the player module.

<!– player container -->
<div id=“player_container”></div>

The player container's major functions are bringing the movie-playing screen to the front of the rest of the application, and providing an easy access point to control the screen properties. See the following code for styles for the player container.

#player_container {
     position: absolute;
     width: 1280px;
     height: 720px;
     opacity: 0;
     left: 0;
     top: 0;
}
#player_container.show {
     opacity: 1;
}

Next, declare the Web API library, which includes the AV Player within the index.html file. Then declare an anchor for the player.

<script  type=“text/javascript”  language=“javascript” src=“$MANAGER_WIDGET/
Common/webapi/1.0/webapis.js”></script>

<a href=“javascript:void(0);”    id=“anchor_player” onkeydown=“Main.player.
keyDown();”></a>

The declared anchor_player anchor is focused and receives remote control key events while a VOD file is playing. For example, the remote control play or stop key events can be implemented to play or stop the VOD playing. See the next code for the handler function that is used by the anchor_player.

Main.player.keyDown = function()
{
    var keyCode = event.keyCode;
    switch(keyCode)
    {

        case tvKey.KEY_RETURN:
            event.preventDefault();
            break;
        case tvKey.KEY_PLAY:
            break;
        case tvKey.KEY_STOP:
            break;
        default:
            break;
    }
};

Note that event.preventDefault() was inserted in the tv.KEY_RETURN: case block to prevent the application from terminating when the return or exit key is pressed. This topic will be discussed in the later Exception Handling chapter in more detail.

Player Object

The player module can be included either in an existing scene or in an exclusive VOD-playing-only scene, with its own JavaScript file. The exclusive scene method is more versatile and better suited for a large application with full screen / windowed mode transition, a remote information window, subtitles, and other complex player event handling.

However, the Hands Frame application only needs simple play and stop functions. The next example will use the main screen layer to include the player module.

// path for a movie file
var URL = ‘C://Users/Administrator/Videos/1_1.mp4’;


var Player = {
      init : function(){
          try{
              var playerInstance = deviceapis.avplay;
              playerInstance.getAVPlay(Player.onAVPlayObtained, Player.
onGetAVPlayError);


          }catch(e){
               alert(‘######getAVplay Exception :[‘ +e.code + ’] ’ +
e.message);
          }
     },
     onAVPlayObtained : function(avplay){
          // callback function for initializing the AVPlayer module
          Main.AVPlayer = avplay;
          Main.AVPlayer.init({containerID : ‘player_container’, displayRect:
{
              top: 0,
              left: 0,
              width: 1280,
              height: 720
         }, autoRatio: true });
     },
     onGetAVPlayError : function(){
          // error handling function for initializing the AVPlayer module
          alert(‘######onGetAVPlayError: ’ + error.message);
     },
     onError : function(){
         alert(‘######onError: ’);
     },
     onSuccess : function(){
         alert(‘######onSuccess: ’);
     },
     play: function() {
          try{
              jQuery(‘#player_container’).addClass(‘show’);
              Main.AVPlayer.open(URL);
              Main.AVPlayer.play(Player.onSuccess, Player.onError);


          }catch(e){
              alert(e.message);
          }
     },
     stop: function() {
          jQuery(‘#player_container’).removeClass(‘show’);
          Main.AVPlayer.stop();
     }
};

See the source code where Main.AVPlayer.init() receives a callback parameter to initialize the player module. This allows binding the player module to the previously declared player container. Except that the API is bound under the player object, it was implemented exactly as shown in chapter 7, AV Player. See the previous chapter for details. The player is implemented with only play and stop capabilities.

Only one static file link was entered as the VOD source. However, an array of URLs was used in the attached final source code for the Hands Frame – Basic so that it can play a different VOD for each focused menu item.

The next function plays the VOD file.

Player.play();

Pause and resume capabilities are not too difficult to add under the preceding player object. However, this example will include play and stop capabilities only. See the next example for an event-handling function that only handles those two.

Main.player.keyDown = function()
{
    var keyCode = event.keyCode;


    switch(keyCode)
    {
        case tvKey.KEY_RETURN:
            event.preventDefault();
            Player.stop();
            Main.content.anchor.focus();
            break;
        case tvKey.KEY_PLAY:
            Player.play();
            break;
        case tvKey.KEY_STOP:
            Player.stop();
            Main.content.anchor.focus();
            break;
        default:
            break;
    }
};

Note that the preceding code returns the focus to anchor_content after the player stops. This returns control of the application to the contents pane, which called the player module. Review chapter 7, AV Player, for the details and other useful tips.

This concludes most of the developing Hands Frame – Basic application. See the complete source code in the addendum for the information scene and dynamic URL that were not covered in this chapter.

Summary

The Hands Frame is a simple reference application that helps in understanding basics of Samsung SmartTV application development, including scenes-based focus handling and movie player. This application provides reference materials on ideas, culture, and contact information of the author of this book, Handstudio company. See the addendum for the complete source code.

The following link provides additional information about the sample application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset