Click here to Skip to main content
Click here to Skip to main content

Using MXML with QNX UI Components for the PlayBook

By , 15 Apr 2011
Rate this:
Please Sign up or sign in to vote.

So what I am trying to do here?

I am trying to take a ActionScript 3 UI library and use MXML to describe its layout. More specifically I wanted to use the PlayBook's native OS UI component library from the BlackBerry Tablet OS SDK, called the QNX UI components. Lets take a look at some code to show you what I am talking about.

Here is a MXML based app using a new class called QApplication that extends QNX Container, which then contains a QNX UI Button:

<?xml version="1.0" encoding="utf-8"?>
<r:QApplication xmlns:r="http://ns.renaun.com/mxml/2010" 
                xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:buttons="qnx.ui.buttons.*">
    <buttons:Button />
</r:QApplication>

Doing this in ActionScript would look like this:

package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;

import qnx.ui.buttons.Button;
import qnx.ui.core.Container;

public class DisplayButtonAS3 extends Sprite
{
  public function DisplayButtonAS3()
  {
    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = StageAlign.TOP_LEFT;
    var container:Container = new Container();
    var but:Button = new Button();
    container.addChild(but);
    addChild(container);
    container.setSize(stage.stageWidth, stage.stageHeight);
  }
}
}

All to create the same application seen here:

display-example.png

DisplayButton Example

What does this mean?

This means you can create a PlayBook application all in MXML with no Flex. This also means you can use Flex 4 (including Flex Hero the latest SDK with mobile support) and mix in some QNX UI components. All you need is to add the QMXML.swc (compiled against Tablet OS SDK 0.9.2) and namespace xmlns:r="http://ns.renaun.com/mxml/2010" to your project/application.

Now that sounds like the bomb! Well its still another UI library. So its not like the QNX UI Component library all of the sudden works just like the Flex Spark architecture. No, the QNX UI lib walks its own path and you will have to remember that when using it. Doesn't mean its bad just be aware its not the same as Flex.

If you want to continue and play with the examples make sure to get the BlackBerry Tablet OS SDK from the BlackBerry developer site: http://us.blackberry.com/developers/tablet/devresources.jsp

NOTE: I am using BlackBerry Tablet OS SDK 0.9.1 as of writing this.

Ok I get it, let me see some code!

First! All the code is available on github, go get it. The repository has a few Flash Builder projects in it. The main library project is called QMXML. All you need to create your own project is the QMXML.swc (compiled against Tablet OS SDK 0.9.2) found in the bin folder or you can download it from here.

The other projects are sample projects called: NonFlexMXMLUsingQNX and FlexAndQNX. The NonFlexMXMLUsingQNX project contains the DisplayButton applications shown above, as well as another project showing a few more QNX UI classes nested in containers using QNX flow/containment properties.

The FlexAndQNX application is a standard Flex 4 spark (non-mobile) application that uses a QNX Button and List along side a Flex LineSeries data chart. Which made some sense as QNX UI library lacks charting at this point. Here is a view of the application running in the simulator:

FlexAndQNX-in-Simulator.png

FlexAndQNX in Simulator

Here is the source code for the FlexAndQNX application which allows you mix QNX UI components directly in Flex.

<?xml version="1.0" encoding="utf-8"?>
			<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:r="http://ns.renaun.com/mxml/2010"
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx"
       xmlns:buttons="qnx.ui.buttons.*" xmlns:listClasses="qnx.ui.listClasses.*"
       width="1024" height="600"
       backgroundColor="0xcccccc" 
      >
  <s:layout>
    <s:HorizontalLayout />
  </s:layout>
  <fx:Script>
    <![CDATA[<span class="code-SummaryComment">
      import mx.collections.ArrayCollection;
      
      import qnx.ui.core.ContainerFlow;
      import qnx.ui.core.SizeUnit;
      import qnx.ui.data.DataProvider;
      import qnx.ui.events.ListEvent;
      private var data:Array = [];
      [Bindable]
      private var chartData:ArrayCollection;
      private function createData():void
      {
        data = [];
        for (var i:int = 0; i <50; i++)
          data.push({label: "Point " + i, data: i+(Math.random()*30),
            data2: i+60+(Math.random()*60),
            data3: i+80+(Math.random()*120)});
        lstData.dataProvider = new DataProvider(data);
        chartData = new ArrayCollection(data);
      }
      protected function lstData_listItemClickedHandler(event:ListEvent):void
      {
        trace(event.data.data + " - " + event.row);
      }
    ]]></span>
  </fx:Script>
  <fx:Declarations>  
    <!--<span class="code-comment"> Define custom colors for use as fills in the AreaChart control. --></span>
    <mx:SolidColor id="sc1" color="0x336699" alpha=".3"/>
    <mx:SolidColor id="sc2" color="0x993333" alpha=".3"/>
    <mx:SolidColor id="sc3" color="0x339933" alpha=".3"/>
    <!--<span class="code-comment"> Define custom Strokes. --></span>
    <mx:SolidColorStroke id = "s1" color="0x336699" weight="2"/>
    <mx:SolidColorStroke id = "s2" color="0x993333" weight="2"/>
    <mx:SolidColorStroke id = "s3" color="0x339933" weight="2"/>
    
    <mx:SeriesInterpolate id="seriesInterpolate" duration="500" />
  </fx:Declarations>
  <s:Group height="100%" width="20%">
    <r:QContainer id="c" align="near">
      <buttons:LabelButton label="Create Data" click="createData()" />
      <listClasses:List id="lstData" size="100" sizeUnit="percent"
              listItemClicked="lstData_listItemClickedHandler(event)" />
    </r:QContainer>
  </s:Group>
  <s:HGroup width="80%" height="100%">
    <mx:AreaChart id="Areachart" height="100%" width="80%"
          paddingLeft="5" paddingRight="5"
          showDataTips="true" dataProvider="{chartData}">
      
      <mx:horizontalAxis>
        <mx:CategoryAxis categoryField="label"/>
      </mx:horizontalAxis>
      
      <mx:series>
        <mx:AreaSeries yField="data" form="curve" 
               displayName="Plot 1" showDataEffect="{seriesInterpolate}"
               areaStroke="{s1}" areaFill="{sc1}"/>
        <mx:AreaSeries yField="data2" form="curve" displayName="Plot 2" 
               showDataEffect="{seriesInterpolate}"
               areaStroke="{s2}" areaFill="{sc2}"/>
        <mx:AreaSeries yField="data3" form="curve" displayName="Plot 3" 
               showDataEffect="{seriesInterpolate}"
               areaStroke="{s3}" areaFill="{sc3}"/>
      </mx:series>
    </mx:AreaChart>
    
    <mx:Legend dataProvider="{Areachart}"/>
  </s:HGroup>
</s:Application>

There is probably more integration on the QContainer class that I can do to make it work with Flex better but for now follow these loose rules. When mixing QNX UI components in a Flex app always start with a QContainer, think of that as your little mini QNX app space. You will want to wrap this in a Flex Spark Group or SkinnableContainer with the notion of the QContainer filling up all of its parents width and height. The QContainer listens for its parents RESIZE event and then invalidates its layout. Then based on the new width and height of its parent it remeasures itself and its children. There is some leaway for setting different QNX properties like size and sizeUnit, but for the safest bet start with:

<s:Group height="100%" width="20%">
  <r:QContainer />
				</s:Group>

Any changes to the dimensions of the Group will automatically be detected by the QContainer and it will fill up the whole space of its parent.

NOTE: BlackBerry Tablet OS SDK does not provide a manifest file and namespace for their classes, which means your apps will have a lot of namespaces that look like qnx.ui.buttons.*. Also some QNX classes might cause problems with Flex's SystemManager control the stage, let me know if you come across something.

Project Types, SDKs, and Plugins

There are various projects types across Flash Builder 4 and Flash Builder Burrito. Also the BlackBerry Tablet OS SDK installs plugins for both Flash Builder versions. Typically all you will need is to create a AIR project and modify your application descriptor file for mobile devices (meaning typically non-WindowedApplication and set visible=true). The QMXML classes will work in Flex 4 spark desktop apps as well as the newer Flex Hero mobile app and theme. This assumes your projects are created and point to the BlackBerry Tablet OS SDK 0.9.1.

Be aware the classes have had limited testing and would love you to take them for a ride. Have fun!

Geek Tidbits from my Journey

With MXML you get Binding. Which is one of the great benefits of MXML. But this also means I had to take a UI framework that didn't take that in to consideration and tweak it to work. Some of the QNX UI framework choices made this not so straightforward. I had to work in a bunch of hooks to properties that might change the layout and create my own layout invalidation/refresh. Luckily the Container class is the only Container in QNX UI library and it only had a half dozen layout related properties. That made it easy to make this a viable solution.

There is still probably some issues with using width/height instead of the QNX's size, sizeUnit, and sizeMode for flow layouts. But if you are using explicit width/height you probably are not invalidating the layout a bunch.

Also there where a few properties that didn't implement getter/setters so I had to watch for changes on them differently to invalidate the layout on changes. Overall it wasn't too complicated but could be improved. Having said all that I have to put a disclaimer that BlackBerry Tablet OS SDK is in beta and will improve, as well as my understanding how it works will change over time.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Renaun Erickson

United States United States
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 15 Apr 2011
Article Copyright 2011 by Renaun Erickson
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid