Happy New Year!

2010 is almost finished and yet, when I look back I can’t believe how packed was this year for those earning a living using the Flash Platform. I mean just look at the extension of the Flash Platform on mobile devices, the changes and improvements we’ve made to Flex and Flash Builder, the new capabilities added to the platform. It’s amazing that I can use today Flex “Hero” to build desktop applications and mobile applications (for Android, BlackBerry Playbook; iOS support is coming in 2011).

What continues to amaze me is the community around the Flash Platform. I truly feel privileged because I travel around and get a chance to meet and talk to you. This is one of the best parts of my job for sure. So, I want to thank you for the events you’ve organized this year and I’m looking forward to see you again next year.

And finally, I want to thank all my readers. It is so much easier writing tutorials and blog posts when you know people will read them :).

To all of you, I wish you A Happy New Year! And don’t forget, 2011 seems to be even better than 2010 – well I do work for Adobe so I have some inside information :).

My Technology Choices for the New Year

I get a lot of questions throughout the year about what technology I am currently using. This includes things like what phone, tablet, computer, and camera I am using. As 2010 comes to an end I thought I would write a quick article that talks about my current technology choices and why I made them. So here goes in no particular order.

Phone
This is always the trickiest one as there are so many quality phones being released. Google releasing the Nexus S with no 3G support of AT&T was a real bummer. It doesn’t deserve to be a called an unlocked phone in my opinion. I have been using my Samsung Captivate for months and it is still my favorite phone. The whole Galaxy S line from Samsung are the only phones that have a screen that can match up against the iPhone 4. To me a phone lives or dies by its screen. While a beautiful device, the iPhone 4 and its screen are too small for me. Another thing that is important is the software. Since my Captivate runs on Android, I can install whatever ROM I want on it to get the best performance and also ditch the crappy AT&T/Samsung software. I’m currently using some version of Cezar’s ROM (can’t remember which one) with the Gingerbread keyboard that has been really solid. (p.s. you suck Samsung for still not officially updating to froyo)

Tablet
Here Apple is the clear winner with the iPad. I bought one when they first came out and was supremely unimpressed. That was the result of the small number of tablet-optimized applications available. Now however there are thousands of great apps built just for the iPad. I use it mainly to check email and social networks from the couch and also for travelling. Lately I’ve been reading my Kindle books on there too (something I said I would never do). Samsung blew it with the first Samsung Tab in my opinion. They should have included a super-AMOLED display like on the Galaxy S phones. The screen looks downright blurry compared to my phone. Hopefully Apple competitors will step up their game in 2011.

Laptop
Once again Apple trounces the competition in this area. The Macbook Pro is still my preferred laptop simply because of the industrial design of it. It feels good, has a nice screen, and the backlit keyboard is a must for me. I’m really hoping that HTC gets into the laptop arena as they are great at industrial design. How about a soft touch laptop?

Operating System
While Apple wins the hardware award from me, Windows 7 is my operating system of choice. I have been using it for almost a year now and I don’t miss OSX for a second. Actually that is not entirely true. I do miss the Unix command line but I can get along with Cygwin just fine. Microsoft really nailed Windows 7 as I have yet to have a single blue-screen or OS crash since I started using it.

Gaming console
The PS3 was always my favorite console but the XBOX 360 has recently blown it out of the water. The Netflix integration is awesome and that is one of the main things I use it for. I also recently got the Kinect camera and I’m loving that thing as well.

Camera
Like I have mentioned before, I use the Canon 7D for all my shooting projects. I shoot everything at 60fps so that I can get buttery smooth-slow motion if I need it. For a lens, I currently carry a Canon 20mm 2.8 lens that I use for everything I do. You can see the video in the last post for an example. That is shot with the on-camera microphone, which is surprisingly good.

Audio gear
When I want to do a professional interview I record the audio using an Edirol R-09HR recorder and a hard-wired lapel mic that I got from Radio Shack. For recording tutorials I am currently using a Blue Snowball microphone with a hiss and pop filter screen over it. Plosives blow!

Well that’s what I’m using right now. Catch me in a month and it all might be different :-) .

Setting Custom Labels on Lists with the PlayBook

By default, it seems like the only property that the QNX List class can display as a label is label. In Flex I was used to being able to set my own label property or my own custom label function but it doesn’t look like that’s possible in the QNX List. Luckily, it’s not TOO hard to set up a class to do just that.

First step is to create a class that extends CellRenderer. There’s a lot that seems to go on in CellRenderer but I’m just starting to dig into it so I’ll save that for a later post. The easiest method I found was to override the setter for data and then use the setLabel function there. You can pass in whatever string you want to that setLabel function and it will display as the default label with the default font.

One of the issues I’m having is trying to figure out exactly when the data gets set on the CellRenderer component. Some of the other things I tried (setting it in the constructor, setting it on the drawLabel method) all didn’t work because the data object was still null. So I’m trying to figure out exactly when data becomes available. Hopefully I’ll have that for a followup post that goes into more detail on creating custom renderers for the list class.

Here’s the code I used for my example:

package com.pintley.components.listClasses
{
import qnx.ui.core.SizeUnit;
import qnx.ui.listClasses.CellRenderer;
import qnx.ui.text.Label;
 
public class BeerItemRenderer extends CellRenderer
{
     private var _beer:Object;
 
     public function BeerItemRenderer()
     {
          super();
     }
 
     override public function set data(value:Object):void
     {
          _beer = value;
          setLabel(_beer.beerName);
     }
}
}

Introducing SimpleStageVideo

SimpleStageVideoIf you played with Stage Video, one of the coolest feature of Flash Player 10.2. You may have noticed that this it requires a little bit of code to be leveraged and you have to deal with multiple events (StageVideoEvent, StageVideoAvailability, VideoEvent) to be used properly. While writing the Stage Video article for the Adobe devnet I realized that the need of a wrapper would be useful for developers, and a few days ago I came across StageVideoProxy by Kenny Bunch which is intended to simplify the use of Stage Video. This confirmed the idea that AS3 developers will need little wrappers for Stage Video, I know Tinic has his own version too for his tests.

Here is my version a little bit different, which should handle all the situations, switching automatically from Video to StageVideo and vice versa when Stage Video becomes available or unavailable. It handles all this automatically so you do not have to worry about it. It also handles something I ALWAYS need in my video players, respecting the video ratio when giving a specific maximum width and height to fit a specific surface to display the video :

To use, it is very simple, just use a few lines code :

// specifies the size to conform (will always preserve ratio)
var simpleStageVideo:SimpleStageVideo = new SimpleStageVideo(800, 600);
// dispatched when stream can be played (NetStream object cannot be played before attached to the video object)
simpleStageVideo.addEventListener(Event.INIT, onInit);
// attach the NetStream to it
simpleStageVideo.attachNetStream(ns);
// display it (this is for the sake of
addChild(simpleStageVideo);

One thing to notice is that even if we addChild the SimpleStageVideo object, the StageVideo object sits behind the stage, and the Video object used as a fallback will be added as a child of the stage so as a sibling of the main timeline. As a result, where you addChild the SimpleStageVideo object has no real impact on the nesting of the video surfaces.

Also, when working with the low level Stage Video APIs, you have to work with two events, StageVideoEvent.RENDER_STATE and VideoEvent.RENDER_STATE to detect how compositing is done and if hardware video decoding is performed. With SimpleStageVideo, those events are centralized through a single event called SimpleStageVideoEvent.STATUS which gives you access to the hardwareCompositing, hardwareDecoding and fullGPU properties :

private function onStatus(event:SimpleStageVideoEvent):void
{
	// informs you about the decoding, compositing states and if full GPU acceleration is performing
	var hardwareDecoding:Boolean = event.hardwareDecoding;
	var hardwareCompositing:Boolean = event.hardwareCompositing;
	var fullGPU:Boolean = event.fullGPU;
}

If you need to resize the video surfaces, use the resize API which does it automatically for you while preserving the image ratio :

simpleStageVideo.resize(stage.stageWidth, stage.stageHeight);

If you need to force the fallback from Video to StageVideo and vice versa for performance benchmarking, just use the toggle API :

simpleStageVideo.toggle(!inited);

Of course, when toggling, the SimpleStageVideoEvent.STATUS is dispatched every time, to let you know about the decoding, compositing, useful for logging, debugging, and performance benchmarking. A SimpleStageVideoToggleEvent.TOGGLE is also dispatched to inform you about the current video object used internally.

This can be useful if you need to draw the content of the video on a BitmapData. As the StageVideo object is not a DisplayObject, you cannot draw it, but you can use the toggle API, then wait for the SimpleStageVideoToggleEvent.TOGGLE, and then draw the underlying Video object used as a fallback, and there you go, you have your video content rasterized.

If you need to access the underlying Video and StageVideo objects you can use the proper getters :

var underlyingStageVideo:StageVideo = simpleStageVideo.stageVideo;
var underlyingVideo:Video = simpleStageVideo.video;

To view a live demo of it, click here (Flash Player 10.2 required). To download SimpleStageVideo, check the simplestagevideo project.

Happy Holidays!

2010 was definitely a year with some spectacular roller coasters… I’ve been thinking all morning about which highlight I would pick if I had to choose one. Adobe MAX was definitely a huge highlight for me this year. The keynotes, MAX online, meeting Martha Stewart and William Shatner, the amazing buzz and meeting some amazing people at the MAX Bash, … It’s going to be tough to top that this year! But the biggest highlight is probably seeing how great the Flash community is. From the people that organize great events like FOTB, FFK, AUGXL, FITC, Flash Camps, user group meetings, … to the people that share code / help others and the people who read my blog and/or follow me on Twitter and Facebook. You guys are truly amazing. Wow… This is starting to sound like some acceptance speech for some award or something… Ehr… Before it gets too mushy… ;-) Happy holidays! 2011 is going to rock!

Paged list loaded from sqlite in Adobe AIR

During my recent work on Adobe Evangelists Blogroll application I wanted to implement lazy-loaded/paginated List component with data coming from local sqlite database. The reason for this was of course memory usage consideration. Adobe Evangelists Blogroll is a mobile application so I didn’t want to load all available Post objects for selected blog at once. I [...]

A Couple of Hacks for Mobile Flex Development

The new Flex Hero 4.5 SDK has great features and the architecture for mobile applications is very cool.  Working with it over the last few months has also taught me a couple of coding hacks to share.  First let’s look at how it works.

A Flex Mobile application is composed of a minimum of three files.  The first is the main entry point into the application which has two main content areas.  The top content area (shown below in green) may contain three content areas.  These are Navigation content, Title content and Action content. Note that these are optional and some application might use different navigation schemes such as creating a Vector of Spark Navigators.

The gray area below the title is the main content area of an application.  This is controlled by the navigator(s).

When you set up a new Mobile application, the minimum three files are the main entry point, the first default Home or First View and the Application Descriptor. The descriptor file has the same basic purpose as in previous versions of AIR except it has been extended to declare Android manifests and other items.  The graphic below depicts a larger project and shows some of the main components of a mobile application.

When you launch a mobile Flex application, the first view may be declared within the entry point to the application.  In the example above, MobileFileBrowser.mxml has a single declaration that points to MobileFlexBrowserHome.mxml.   This is declared below in line 5 of Code Sample 1 below.


Code Sample 1

Line 6 shows a great trick.  Mobile applications may take a while to initialize and providing user feedback during that time is sometimes useful.  The splashScreenImage shows up when the application launches to let the user know the app is initializing.

Now let’s take a deeper look at how the navigation works.  Below is a screenshot of the Mobile Slashdot RSS reader I am working on.  The first half of the tutorial to build it and the source code are available at http://technoracle.blogspot.com/2010/12/mobile-slashdot-rss-reader-tutorial.html Note that the current code base has some need for optimization.

The Home view in this case contains a list and has a service call linked to it to reach out and grab an RSS feed from slashdot.org.  The service call (getData()) is initiated on an event called “viewActivate” which is fired when as the view becomes active.  When a user gets this view, they may select an item from the list and the view navigator will then pass the data object to a new view and instantiate the new view.  In this example, the RSS item is passed and details are shown in the new view.  If the user wishes to navigate backwards, they simply use the back button.  The code for this is written as pushView(View, Data) and popView().  

Here is an important tip! Consider what happens in a mobile scenario when the user examines several different RSS items and navigates backwards to the main list.  When the new view is active, the old view does not persist by default so a new service call must be performed every time the list view is shown.  If you link your service call up to the viewActive event as shown below on line 5 of Code Sample 2, your application will make the service call each time the view becomes active.


Code Sample 2

Needless to state, in many situations, this is architecturally really bad as it will eat up both bandwidth and battery/CPU life.  Luckily, this problem can be rectified with a single declaration.  The better way is to not call the service based on a viewActivate event and instead allow the user to trigger it with a button or use the applicationInitialize event.  Once you do this, you can simply add the declaration that the destructionPolicy is none as shown below in line 7 of the code snippet. If you download the current source code from part one of this tutorial, note that this has not yet been done and is being slated for part 2.


Code Sample 3

Now let’s consider another way you can allow user to navigate on your application.  The Slashdot RSS reader application has an information view.  To access the information view, the call is made directly from the action content area.

When the user clicks the information icon, a call is made through the navigator.activeView object as shown in code samples 4 (below) and 2 above.


Code Sample 4

Note that on line 29 of code sample 4, the call is made to the public function on line 19 of code sample 2.  This function only requests that the navigator push the information view, in this case with no accompanying data.  Since the information view will also have the info icon in the parent container, it too must contain the showInfo() function or an error will be thrown.   If you wrote the function exactly the same as in the other views, it could lead to a recursive problem.  If the user keeps
hitting the information icon, new info views get created and activated.  If the user hits the icon 25 times, they would have to hit the back button 25 times to return.

There are two ways to keep the view from being pushed more than once.  On line 10 of the code sample below is the function that gets called when a user clicks on the information icon.  Line 12 sets up a regular expression that will detect if the current view is the “InfoView”.


Code Sample 5

Note that there is a “\d*” within the regular expression.  If you add a line of code to trace the name of the currently active view,  the console will show that the runtime appends some numbers to the end of the name as shown below.

Essentially the regular expression can detect if the activeView is already the InfoView and prevent it from creating another instance of itself.

The problem with this approach is that over time it become unmanageable.  A far better way to prevent this is to simply make the showInfo() function in the information view do nothing as shown on lines 8-11 of Code Sample 6 below.  Note that if you do not have the showInfo function in the info view, an error will be thrown when the user hits the icon.


Code Sample 6

This is a far better way to handle the problem.

Well, that is all for now.    A video tutorial will be out shortly to summarize some of these lessons and the source code for the RSS Reader will also be released.

Happy Holidays everyone!