CoffeeScript with Sublime Text

Recently I’ve played with node.js and the Play! framework and I came across CoffeeScript.
CoffeeScript is a language which compiles to JavaScript. The advantage over using JavaScript is basically having a more compact language which looks a lot like Ruby. Sometimes one very readable line of CoffeeScript translates into 7-10 complex lines of JavaScript.

My dear friend Alec recommended Sublime Text, a relatively new lightweight editor similar to TextMate. Starting to learn CoffeeScript I decided to give Sublime a shot and I liked it a lot. Now I also use Sublime to do the Java coding for Play! framework code. Usually you want a richer IDE like Eclipse or IntelliJ for Java but since Play! compiles the code on the fly and comes with perfect compile errors in the browser, a lightweight editor like Sublime works just fine.

Here a little tutorial how to setup Sublime to start coding CoffeeScript:

  1. Install CoffeeScript (You need to have node.js and the node package manager installed):
    npm install -g coffee-script
  2. Download and install Sublime Text Editor
  3. Save the CoffeeScript.tmLanguage here: ~/Library/Application Support/Sublime Text 2/Packages/CoffeeScript/
  4. Create the CoffeeScript.sublime-build here: ~/Library/Application Support/Sublime Text 2/Packages/Users with the following content:
    {"cmd": ["coffee", "$file"],
    "selector" : "source.coffee",
    "path" : "/usr/bin"}
  5. Now open Sublime and create a helloWorld.coffee:
    console.log "Hello world"
  6. CMD-B to execute the script and you should see the output:
    Hello world
    [Finished]

Another helpful thing is to configure Sublime to be used from the command line. Open a terminal and create a symbolic link:

sudo ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" /usr/bin/subl

Now you can change to the directory of you project and with “subl .” Sublime opens the current directory as a project.

To get an overview how CoffeeScript compares to JavaScript check out the docs. Further I’ve read CoffeeScript: Accelerated JavaScript Development which gives a good overview of the language.

Update: Great link explaining some Sublime features/shortcuts 9 reasons you must install Sublime Text 2. Code like a man, man.

Detect Spark List Control Scroll To End

If you want to implement lazy loading (when the user scrolls to the end of the list it triggers to fetch more items) for a spark List control you have to use a workaround right now.

Usually you would add an event listener on the scrollers verticalScrollBar but due to a bug it does not fire events if the user scroll with the mouse wheel or uses the arrow buttons. The bug shows a workaround by listening to the PropertyChangeEvent of the scrollers viewport.

Here a little example app:

The bug has been fixed for Flex 4.5. If there is a better workaround for Flex 4.1 please let me know.

Compile-time FXG

FXG was introduced with Flex 4 and offers a great way to skin and style your application without relying on bitmaps like PNGs.

“FXG is a declarative XML syntax for defining vector graphics in applications built with Flex.”

When you declare FXG within your MXML it is computed at runtime but there is also a way to use compile time FXG. There is up to 10x improvement in memory consumption and start-up time when converting complex MXML Graphics (with lots of Paths) into FXG.

Deepa explains it like this:

“This is an optimization scheme which takes advantage of the fact that a lot of FXG content is simply static assets that do not need to be updatd or re-rendered at runtime. In cases like that, you could imagine that instead of creating ActionScript objects to represent those graphic elements, the Flex compiler could instead create SWF graphic primitive tags to draw the static FXG asset”

So there is some benefit in using compile time FXG and in many cases you can just copy and paste the FXG to an .fxg file with some minor syntactical changes. The downside of compile time FXG is that you have to specify fix dimensions. This means you cannot use percentage values for the width and height.

Let’s look at an example which uses FXG to define the background of a Group.
Comparison:

Runtime FXG

Compile-time FXG

You see that you can instantiate the Background.fxg like any other class.
The differences between compile and runtime are fairly simple:

  • Add a Graphic tag
  • Replace spark namespace with default namespace
  • Change numeric values 0x to #
  • Define fix width and height

Another difference is that you have to apply a scale-9-grid for the background in case of rounded corners and filters. This would like like this:

These are still simple examples and it can get way more complex and you will run into limitations. Compile time FXG was developed by Peter Farland from the Flex side and he gave some inside about the limitations of compile time FXG in combination with scale-9-grid:

  • An item with a scaling grid cannot have child <Group> elements (because ata lower level a scaling grid cannot be applied to a DefineSprite that has a child DefineSprite(s)… this also means that you can’t use a scaling grid with children that are ultimately DefineSprite based including <RichText>,or a custom Library Definition, and I think if alpha masks, luminosity masks, or pixel-bender based blend modes (such as colordodge, colorburn,exclusion, softlight, hue, saturation, color, luminosity) are applied).
  • A scaling grid must be a valid rectangle – i.e. the resulting rect must have a non-zero width and height and the left extent must be to the left of the right extend, and the top extent must be above the bottom extent.
  • The scaling grid¹s center rectangle must be wholly within the bounds ofthe item(s) being scaled.
  • Rotated items cannot be scaled with a scaling grid (I think? though notethat restriction doesn’t apply to rotated gradient fills applied to shapesbeing scaled, for instance).
  • There are several bugs when applying a scaling grid to a collection of child shapes – adding a transparent Rect underneath that spans the bounds of all of the child shapes can help.
  • When manually calculating the dimensions of a scaling grid you need to consider the total bounds of the item(s) being scaled. This must take into account the stroke width, miter and joint types. Watch out for fractionalpixels of strokes that apply once an item is scaled.

Conclusion
Try to use compile-time FXG when possible. The performance of your application will improve and you have a better separation of design and code which is one step further for the designer/developer workflow.
For further reference check the FXG 2.0 Specification

.

AIR Mobile StageWebView UIComponent

When you want to use webkit to display HTML in AIR 2.5 mobile projects you want to use StageWebView. Since StageWebView is a subclass of EventDispatcher you cannot add it to the display chain right away. The API works a bit differently and you need to define a Rectangle as the viewPort. However, I thought it would be convenient to have a StageWebView UIComponent so that you can add it to the display chain. It is just a wrapper class which exposes the needed APIs like the text and url setter and the methods show, hide and dispose. Further you can listen for all event listeners which just get cloned and re-dispatched.

Example:

Source:

How to Skin AIR Mobile ActionBar

It took me a bit to figure out how to skin the ActionBar in a mobile AIR application so here a short tutorial. There are also two small bugs when you want to skin the ActionBar but there are decent workarounds for now.

To apply a custom skin to the ActionBar you first have to define a skin for the MobileApplication itself.

In the ApplicationSkin.mxml you have to define a ViewNavigator component with the id navigagor:

The ViewNavigatorSkin.mxml contains the push and pop transition, the ActionBar component and the content group.
Due to a small bug in the SlideViewTransition.as you have to set the direction to right on creationComplete:

Finally we can create the ActionBarSkin. There is another small bug so for now you have to define an empty Group at the 1st position.

So right now you have to create 4 different skins to change the dimensions and look of the ActionBar. From an architectural standpoint this looks very clean but having to create 4 skins to just change the height is kind of overkill.
MobileApplication should expose a style to define the dimensions of the ActionBar and should support to set the actionBarSkin right away.

You can download the example project here. The example uses compile-time FXG for the ActionBar background. More on that in a later post.

Updating to AIR 2.0 Barriers

Now that Adobe 2.0 is released it’s time to update some older apps to use the new APIs.
The process to update seems kind of complicated and definitely worth a blog post. In my special case I am upgrading from an self signed 1.5.2 app to a self signed 2.0 app.

Since 1.5.3 the publisherID works differently so you have to add the publisherID to the XML descriptor like also described here. If you are not using EncryptedLocalStore you might be fine by now but otherwise you get this error when you debug the application: EncryptedLocalStore may not use publisher IDs passed in from ADL

A quick search lead me to add the publisherID to the debug configuration but then you get the error that the publisherID can’t be passed anymore by ADL since 1.5.3, damn.

More research brought me to this forum thread. So it looks like this bug is in the AIR 2.0 final so the only solution is to remove the publisherID from the descriptor while debugging the application. Before packaging the app you then have to add it to not break the update for your users who still have the older version of your app.

Ok, I removed the publisherID and finally could run my app with AIR 2.0, not! My next runtime exception is TypeError: Error #1034: Type Coercion failed: cannot convert flashx.textLayout.formats::TextLayoutFormat@184eb041 to flashx.textLayout.formats.TextLayoutFormatValueHolder.

Solution is to change TextLayoutFormat to TextLayoutFormatValueHolder like here:

var cfg : Configuration = TextFlow.defaultConfiguration;
var normalTLF : TextLayoutFormat = new TextLayoutFormat( cfg.defaultLinkNormalFormat );
cfg.defaultLinkNormalFormat = normalTLF;

to

var normalTLF : TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder( cfg.defaultLinkNormalFormat );

Now I can finally run the app with AIR 2.0 without any runtime exceptions or other errors, uhh!
The TextArea default height seems to have changed though but that’s for another time.