Building cross-platform applications with Cocktail

You are viewing an old version of this entry, click here to see latest version.

A proof of concept


Cocktail is the ideal Haxe library to include UIs in your cross platform applications. Without conditional compilation, Cocktail API can be compiled and packaged for
  • mobiles and tablets
  • desktop computers
  • televisions (Google TV, Adobe Air for TV, HbbTV (using DTT, equivalent to french TNT))
  • all major browsers, in HTML5 with a Flash fallback
  • PHP, in order to be able to generate and manipulate the client "view" on the server side

Here is a little application which we have deployed and tested on each of these targets. For now, some functionalities are still missing, e.g. keyboard & accessibility which make it impossible to navigate inside the application on connected TVs.

This small app shows icons on start page, which let the user open the inner sections of the app, navigate in pages using lists of items. It makes an extensive use of liquid layouts which are rendered as native CSS styles in HTML, but are emulated in Flash which is close to what you can do with the Flex framework.

It is a very simple example which will show show you how easy it is to build cross platform applications with Haxe and Cocktail.

Feel free to download the source code of the application on github or the compiled application - one app for each target.

The code to generate the home page is quite simple, it is explained as a sample code at the end of the article.

Phones & tablets native apps (iOS, Android...)

The mobile version of the app is just the first step to real native apps. For this first test we have used the Flash version with AIR to package the application for Android and iOS.

This is quite impressive to see how the application resizes and how fast it reacts, but we plan to compile Cocktail app directly in C language and package it without AIR, which is very heavy and not supported by all phones.

Web sites in HTML5 with a Flash fallback

Here is the online version of the application. If your browser supports HTML5, you will see the HTML version, and the Flash version otherwise. We considere that either HTML5 or Flash is a reasonable requirement nowadays for a web application to reach the vast majority of the users.

Also a pure HTML version without javascript should be served in order to be well indexed by search engines. This will be possible when Cocktail also compiles to PHP, which will be the case before we release a beta version.

Take a look at the HTML version of the web app demo here, and look at the generated HTML code. It is clean and meaningful, like this:

<html>
    <head>
    <title>Haxe JS</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
</head>
<body style="display: inline; min-height: 130%; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; ">

    <div id="haxe:trace">
    </div>
    <script type="text/javascript" src="WebApp.js">
    </script>
    <div style="display: block; min-height: 130%; z-index: 0; ">
        <img style="min-height: 130%; 
                position: absolute; display: block; 
                top: 0px; left: 0px; right: 0px; bottom: 0px; 
                width: 100%; height: 100%; 
                z-index: 0; " 
                src="images/blackPixel.png"></img>
        <div style="display: block; z-index: 0; ">
            <img src="images/blackPixel.png">
            <ul>
                <li>
                <img src="images/calendrier_blanc.png">
                <div>Cal</div>
                </li>
....
                <li>
                <img src="images/NavButtonCreditsHD.png">
                <div>Credits</div>
                </li>
            </ul>
        </div>
    </div>

</body>
    </html>

And here is the Flash version (to be served at those who do not have HTML5 (50% of the browsers).

TV applications


Thanks to Intermedia company, we have the chance to test and deploy on a multitude of TVs, with different hardware and software.

The most exciting experience has been made with France Televisions (first French TV group), on TV sets which are not connected to the internet, but through the waves of the TNT. These TV sets implement a common open standard, HbbTV, which we also target with Cocktail. It is based on HTML, so it is not a real separate target in itself, but we have to take the remote control and the broadcast video into account.

As for HBBTV target, the GoogleTV is not really a separate target, since a native app for iOS and Android simply has to take the input controller into account to be compatible.

Here are the links to test it on your TV, knowing that the focus and keyboard navigation is not yet implemented, as it is explained in Cocktail v1.0.0alpha2 release notes.

Desktop applications or widget

This target also runs with AIR for now and we plan to compile with NME and Haxe cpp target in a near futur. This will also make it possible to integrate Haxe/Cocktail bits, initially developed for the web app version, into a native C++ desktop app.

Download Cocktail web app demo for the desktop (packaged using Adobe Air)

Take a look at the code

The code to generate the home page is quite simple - you will recognize Cocktail API (*DOMElement and *.style.*).
Also you should compare the DOM elements we create and the structure of the HTML generated in the HTML version - see the section "Web sites in HTML5 with a Flash fallback" of this article.

// **
// background
var backGround:ImageDOMElement = new ImageDOMElement(NativeElementManager.createNativeElement(NativeElementTypeValue.image));
backGround.load("images/blackPixel.png");

// style is applied here even if image is not loaded
backGround.style.position = PositionStyleValue.absolute;
backGround.style.display = DisplayStyleValue.block;

// 100% of height and width
backGround.style.top = PositionOffsetStyleValue.length(px(0));
backGround.style.left = PositionOffsetStyleValue.length(px(0));
backGround.style.width = DimensionStyleValue.percent(100);
backGround.style.height = DimensionStyleValue.percent(100);

// **
// create a list of icons

// create the data
var pageData = [
                {text:"Cal", imagePath:"images/calendrier_blanc.png" },
                {text:"Music", imagePath:"images/icone_music_blanc.png" },
                ...
            ];

// create a main container for the cells
var content:ContainerDOMElement = new ContainerDOMElement(NativeElementManager.createNativeElement(neutral));
content.style.display = block;

// create list's cells
var cellData:Dynamic;
for (cellData in pageData)
{
    // create cell with text and image
    // empty cell part
    var cell:ContainerDOMElement = new ContainerDOMElement(NativeElementManager.createNativeElement(NativeElementTypeValue.custom("li")));

    // image part
    if (cellData.imagePath != "" && cellData.imagePath != null)
    {
        var cellImage:ImageDOMElement = new ImageDOMElement();
        // add image
        cell.addChild(cellImage);
        // load image
        cellImage.load(cellData.imagePath);
    }

    // add text
    var cellTextContainer:ContainerDOMElement = Utils.getContainer();
    if (cellData.text != "" && cellData.text != null)
    {
        var textElement:TextElement = new TextElement(cellData.text);
        cellTextContainer.addText(textElement);
        cell.addChild(cellTextContainer);
    }

    // add cell to instance
    content.addChild(cell);

}

//**
// the main screen

// build the main container for all of our elements
var page:ContainerDOMElement = new ContainerDOMElement(NativeElementManager.createNativeElement(neutral));
page.addChild(backGround);
page.addChild(content);

// attach to the body (root timeline in flash or body in html)
var body:BodyDOMElement = new BodyDOMElement();
body.addChild(page);


version #12316, modified 2012-02-01 11:06:23 by codam