4 “WTF?!” moments during a Flex/AIR experiment
Published by Ronny on June 11th, 2009 in Experiments, download. 9 Comments
On a shiny day I was sitting inside, and I don’t know what bug just bit me, but I felt like experimenting with Flex and AIR (instead of heading outside into the light). For some reason I felt like creating a Photobooth clone with only one feature: Taking a snapshot every few seconds and saving it to the disk. During my quest I came across a few findings that were either extremely weird or just plain awesome. Here goes my list of ‘WTF?!’
(If you don’t like reading, but you do want to check out the AIR app, click here)
HorizontalList and ItemRenderers in Flex
I must’ve done something wrong… I can’t imagine this being so hard.
What I did was: I used a simple HorizontalList component, set the columnWidth to 80, built my own itemrenderer and put them together. The itemrenderer basically loads a JPG and displays it. Seen as my images were larger than 80px I decided to do some maths the resize the image on the fly.
To start with, i went into my itemrenderer, and traced the with of the bitmap, and the width of the itemrenderer itself. Just to make sure those properties are actually ready. First thing to notice: this.width inside the itemrenderer randomly traced 80 and 85.![]()
What the f-… Wait… Eh… No, what?
I didn’t really find out why that is, but if anybody feels like enlightning me: go right ahead. (After that, I noticed that sometimes the first or the last (or both) items in the list weren’t updating at all… I must be misunderstanding some fundamentals of the framework I guess… [Btw: I did NOT manage to fix this in a decent way, so at some point I gave up an threw it away...])
The panel titlebar in Flex
So this is AIR, right? Goodbye system chrome, hello you science-fiction-looking chrome! I created my own (very Flex-looking) chrome and disabled the system chrome. I wanted my app to be able to be moved around on the desktop… You know: Like windows do (not Windows…).
I figured: Hell, the Panel component looks a lot like a basic window. Why not use it as the main window? So what’s the first thing a regular human brain would do? Right, you’ll try to get to the titleBar via the panel instance… But you can’t! I figured I must be misunderstanding the construction of the panel. So there I go, reading about the titleBar on the Panel Class page in the Flex Livedocs. Most of you already know but just let me spell it out for you: It’s protected… So you can’t get to it right away… You have to built your own panel class that extends the original Panel class, and create your own public getter for the titleBar…
Excuse me: WTF? Oh, I think I understa… Oh, no I don’t: Why again?
No seriously: What’s the deal with that? I can see how you don’t want a setter there… But no getter? What good is that supposed to do? Anyway, let’s fix this…
- < ?xml version="1.0" encoding="utf-8"?>
- <mx :Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="300">
- </mx><mx :Script>
- < ![CDATA[
- import mx.core.UIComponent;
- public function get theTitlebar():UIComponent{
- return this.titleBar;
- }
- // There are probably way easier/simpler ways than this...
- ]]>
- </mx>
And now I can use theTitlebar of my DraggablePanel class to actually drag my panel like a real window…
- pnlMain.theTitlebar.addEventListener(MouseEvent.MOUSE_DOWN, startTheDrag);
- private function startTheDrag(e:MouseEvent):void{
- nativeWindow.startMove();
- }
That looks pretty straight forward, and actually works like a charm… But why did I have to do this? Why is the titleBar protected??
AS3 JPGEncoder for FP9, FP10 and the one on speedballs
So at one point I actually got to building the thing I actually wanted to build: A Photobooth-clone that takes a picture and saves it to the harddrive. Drawing the bitmap went fine, saving the encoded JPG to disk went perfectly smooth as well. The AIR API is really fun to work with. Pretty straight foward… But I will get back to that in just a minute…
The problem at hand right now was the Bitmap encoding: I draw a bitmap (480 x 360) and I want to write it to disk. So I include the AS3corelib in my project and continue my quest. When testrunning I notice the application freezes while the bitmapdata is encoded. And not just for a moment. Noooo… For a full second (or longer)! I can hear you thinking: ‘A second…? So?’. Well if you want to shoot a picture every second this application will just completely freeze. And let’s just face the fact: it’s just plain annoying the have an application the freezes every few seconds for that amount of time.
So I started playing with quality settings, and bitmap sizes. All to no avail. The encoder is just too slow. Peter suggested taking a look at the Vector implementation found here. That went way faster already: Up to 4 times faster. But still: 0.3 seconds is pretty slow… So I read through the comments and run into the magic word: ‘Alchemy‘. I haven’t been playing with Alchemy myself (mainly because I don’t know C), but I knew Alchemy would be the key to he solution of this problem. So I downloaded this SWC (direct link), implemented this version of the encoder, ran the script and…
….I went ‘WHAT THE FUUUUCK?’ (You can see what that looks like below)
This video was made using the pictures Alchemy created. Alchemy was encoding these bitmaps in .05 seconds per frame! (I swear, I went on for at least 15 minutes WTF-ing over and over again…). So: From 1.2 seconds to 0.05 seconds… That’s about 24 times faster. Ain’t that amazing?
The coolest thing? I didn’t even have to compile the C code myself as I was given the .swc file. (Believe me I gave C compiling a try, but me and Terminal… It’s just not gonna happen…)
File.nativePath and File.url in AIR
The one thing I love about AIR? The combination of creating crossplatform applications using the tools I’m familiar with from online development. The keyword here is crossplatform. Creating AIR apps is supposed to be a straight forward process. You shouldn’t worry about platform specific issues. AIR is handling the heavy lifting for you. The only thing you need to do is create the app using the crossplatform API. Or so you would think.
One of the first things I noticed was the fact that the file.nativePath property isn’t all that crossplatform. And nobody can’t really explain why. Even Lee Brimelow didn’t manage to explain that in his tutorial…
I mean: How can the native path not be cross platform? It’s native to it’s own platform! (I really went WTF when learning that).
Apparently you can do anything using the file.url property. To me file.nativePath isn’t intended to be used when trying to access a file, but more intended to show the end-user where on the filesystem the file resides using a platform native notation.
Examples
- Windows XP: c:\Documents and Settings\noCreativity\My Documents\myFile.jpg
- Windows Vista: c:\Users\noCreativity\My Documents\myFile.jpg
- OSX: /Users/noCreativity/Documents/myFile.jpg
instead of
- file:///c:/Documents%20and%Settings/noCreativity/My%20Documents/myFile.jpg
- file:///Users/noCreativity/Documents/myFile.jpg
I am no Adobe AIR expert so please, feel free to correct me. Because this really itches me. How can a crossplatform API have a property which is not crossplatform-compatible (and don’t get me started on the whole OSX Dock/menubar vs Windows Start Menu/taskbar thing… But somehow, that’s different…)
Finally… The end…
Yes, I had a hard time doing all this but I learned a lot! My conclusions?
I like Flex and how it enables you to rapidly create data driven applications, but I’m pretty sure I’d really have to look into the inner workings of the framework before trying to build something, using the framework… And basically that ‘really looking into it’ ruins the mood for me… Definitely when experimenting.
Alchemy is amazing! I can’t wait to get a good C development environment up on my iMac and start playing with C and lean how I can get the best from both worlds. If you have got any decent suggestions on how to do that [without Terminal] feel free to tell me ![]()
Oh and by the way: If you’re experimenting with Alchemy and you’re open-sourcing code or libraries, I encourage you to add a .swc file with the compiled C code. Thanks in advance!
I love the AIR API. Although that nativePath thing will keep haunting me until somebody can give me a straight answer, ’cause I feel like a complete idiot right now.
Oh, and if you care: Feel free to check out the application!
Download: Click!
Posts that somehow relate to this one:
- Playr 2.0 is coming! – (567 views)
- Visualizr source – (1461 views)
- Spread the word, an iPad app built in Flash! – (231 views)
- My latest project: Walter Ego – (835 views)
- Webcam motion detection coolness – (13548 views)
Freedom of speech!
Whatever it is you feel: Tell me! It's for free!


popular opinion
9 others felt like sharing their feelings about this. Feel free to do so as well.
Jonas De Smet @ 13:49 - June 11th, 2009
Hi Ronny, while developing I had some of the same WTF’s like your. I don’t understand why some AIR Api’s aren’t that crossplatform like they should be… We can only hope they will find something for it
Cool app btw!
Ronny @ 13:58 - June 11th, 2009
Thx, Jonas.
Are you running it on OSX or on Windows?
(A friend of mine tested it on Linux, and the webcam didn’t work at all)
Frederik Jacques @ 14:07 - June 11th, 2009
Compiling a C file is very easy on osx.
put your c file in a folder (lets say /Desktop/test/mycfile.c)
open terminal and navigate to that folder
then just compile by this statement “cc -o myCompiled mycfile.c
cc = command to compile
-o = no ouput
myCompiled = the name of your executable
mycfile.c = the c file it has to compile
pretty simple isnt it
Frederik Jacques @ 14:07 - June 11th, 2009
oh yeah and a good environment? xcode
Ronny @ 14:16 - June 11th, 2009
Ok, that looks pretty straight forward… But I guess we’re not compiling to Flash now? (Seen as there’s A LOT of stuff on the Alchemy Labs page one has to do before actually be up & running)
Frederik Jacques @ 18:58 - June 11th, 2009
no, it’s just for compiling .c files
Peter @ 12:42 - June 12th, 2009
Nice post Ronny, these moments are what make Flash/Flex/AIR development fun
Those platform specific properties in AIR are usually just there for convenience so if you need to write an XML file out or show the path to the user it is in the typical format for that OS, like you used as an example: /Users/noCreativity/Documents/myFile.jpg for a Mac user
All APIs should have cross platform properties available, and in some cases you can also access the OS-specific values. The exceptions are the dock and system tray vs OS X menubar (not supported at the moment). I hope they change that in the next update to AIR.
Alchemy is incredibly powerful but it is quite hard to do — even for some really basic C code you need to write some hooks and go through at least half a dozen steps to get it compiled to a SWC. Hope to soon have the time to play around with it.
Ian @ 13:28 - August 22nd, 2009
Hey Ronny,
It would be nice if it could upload the file to an FTP server too!
(well not at maximum speed lol)
greetz
Ian
Jonas @ 22:40 - September 22nd, 2009
I lol’d @ the video. Great blog, great articles!