Saturday, December 22, 2007

I am older than the *nix epoch

This fact dawned on me this week, during a discussion of UTC time handling in particular, and time/date handling in Flex in general.

I don't know why I fixated on it. OK, I do know why. I'm terribly vain, *and* I'm the oldest guy in the company. At least I'm not the most mature!

Random Fun Facts

  • The UNIX epoch is defined as midnight, UTC, Jan 1, 1970.
  • I'm 42 years old, born just after the Earth finished cooling in July 1965, so that makes me about -4.5 years from the epoch.
  • UTC is not technically an acronym, since the letters don't stand for anything. Instead, the letters represent an interesting compromise between the French TUC (temps universel coordonné) and the English CUT (coordinated universal time).
  • I think the year 2038 problem is much more likely to be a big issue than the non-event that was Y2K.
  • Man, this date/time stuff is a difficult problem to solve precisely.
  • Did you know that the Unix epoch of Jan 1, 1970 is not the same as the UTC epoch of Jan 1, 1972?
  • Did you know that the official UTC spec includes leap seconds, but Unix time doesn't?
  • All of this makes me think of this Chicago song. Which is also older than the Unix epoch.

Wednesday, October 3, 2007

DryerFox - Moxie Beta 2 Upgrade Completed

This post updates a couple of earlier posts about DryerFox in particular and how to deploy AIR apps with a seamless install from your web page.

Click on the "Install Now" button in the sidebar to get the latest DryerFox executable, or click here for the source.

Updating from AIR Beta 1 to AIR Beta 2

This step was pretty straight forward. The foo-app.xml schema has changed (again!) in FB3B2, so the simplest thing to do (and the sequence recommended in the release notes) was:
  1. Create a new AIR project
  2. Cut-n-paste the few project descriptors and icon paths from the old project to the new project. The same information exists in both projects, but the location of each XML node has changed.
So far, each public beta of AIR has changed the app.xml schema, so this seems to be an area of churn. Not a biggie though. It took about 3 minutes to do this.

Once DryerFox was compiling in FB3B2, I found that the stage.window property was renamed to stage.nativeWindow, so I have to update the startMove(), minimize(), and close() handlers. That took another 5 minutes, and then DryerFox was up and running again.

Adding UpdateManager

This was quite straightfoward. Kudos to Rich at the EverythingFlex blog for posting this useful class.
  1. I copied the class to my project.
  2. I created a version.xml that matched the new version in -app.xml
  3. Added the following two lines to the onAppInit() method:

import com.everythingflex.air.managers.UpdateManager;
var um:UpdateManager = new UpdateManager("");

Seamless Installation update (imageurl is gone!)

I followed the instructions in the AIR release notes, and updated my install badge to the latest version bundled in the SDK. This folder can be found at "installRoot/Adobe Flex Builder 3/sdks/3.0.0/samples/badge".
In doing so I found that the new badge.fla no longer attempts to frame a supplied image with the button. I quite liked the embedded, so I just updated my older badge flash project from here, simply replacing older with the newer, more robust version included in FB3B2.

Feel free to steal my backwards-compatible badge.swf if you want something you can just drop in as a replacement. Also note that Adobe now recommends setting Flash 8 as the minimum flash version. Since Flash 9 has well over 90% market penetration, that's a pretty reasonable setting.

SWFObject 2.0

Geoff Stearns and Bobby van der Sluis have been busy improving their individual SWF-hosting efforts into a combined project, just released on Google code. I've updated my "Install Now" button to use the SWFObject 2.0 script, and it seems to be working well. There is a syntax change from the previous use case, but it is still pretty simple to use.

Here's the new syntax:

<script type="text/javascript" src="swfobject.js"/>

<div id="dryerfox_flashcontent">
Whoa. You need to install <a href="">Adobe Flash Player</a>.

<script type="text/javascript">
var flashvars = {
appname: "DryerFox",
appurl: "DryerFox.air",
imageurl: "dryerfox_badge.jpg",
airversion: "1.0.M5",
buttoncolor: "008811",
messagecolor: "000000"
swfobject.embedSWF( "badge.swf", "dryerfox_flashcontent", "217", "180", "8", "expressInstall.swf", flashvars );
The first two sections are unchanged. Include the swfobject.js script in a <script> tag, and your app's alternate content in a <div> tag. Then use a swfobject.embedSWF() method call to replace the alternate content with your SWF and viola!

DryerFox demoed at Best Buy!

Thanks for reading this far. I just thought I'd send a shout out to the techs at Best Buy (is that still Geek Squad?) for leaving their Vista demo systems wide open. On the weekend I was able to install DryerFox on a sweet HP 19" touchscreen system, and associate DryerFox with the .HTML file extension. Who sets up demo accounts with admin privileges?

Oh well, it was fun to drag the dryer around with my finger.

Tuesday, October 2, 2007

DryerFox - Maintenance mode

The DryerFox code is getting a wee bit stale, so it's time for an update. Rather than make incremental changes, I thought I'd lump in the following tweaks:

  1. Build it with Flex Builder 3 (Moxie) Beta 2
  2. Add in Rich Tretola's UpdateManager class
  3. Deploy it with the new badge installer (now called Seamless Installation)
  4. Wrap the Install Now badge using SWFObject 2.0

Four framework upgrades at once. What could possibly go wrong? ;-)

Stay tuned ...

Wednesday, September 26, 2007

To Catch A Thief

Or at least, to catch a buyer of hot items. :-)

Mr. Flickr-fied turned the stolen iMac into Victoria police (that's a 2hr ferry ride away from Vancouver), on the advice of his lawyer. He had "bought it from a friend who bought it from someone else". Apparently our friend is "known to police" and the investigation is ongoing.

I think we should chip in and get the iMac tattooed for easy identification next time.

Monday, September 24, 2007

It wasn't me! I didn't do it! You can't prove anything!

OK, so this post is off-topic, but it is too sweet to not blog about.

Our Vancouver office space is at the lovely WorkSpace in Gastown. Last Tuesday night there was a break-in, and the thugs stole some computers, including a public-use iMac that lived near the espresso bar.

That stolen iMac had the great FlickrBooth plugin installed and today someone posted a few interesting pics of themselves to the WorkSpace Flickr account. Nice tats dude!

40 minutes ago, one of the Flickr admins called WorkSpace owner Bill MacEwen with the IP address used to upload today's photos. I sure hope the cops nail this guy.

At the time of the heist, I was in Denver, at the EffectiveUI main office. Since it was international Talk-Like-A-Pirate day, I was required by law to dress up. Today I noticed that my fake tats and bloated face make me look similar to the person of interest.

I'm thankful I have a rock solid alibi.

Now go get him, boys!

Sunday, August 26, 2007

Etch-A-Sketch Technical Support

I can't really describe how I found myself there, but this Etch-A-Sketch FAQ gave me quite a laugh today.

Wednesday, August 22, 2007

Wanted: Eclipse IDE widget to quickly change the editor font size

Does anyone know of an existing Eclipse widget / plugin that puts a quick font-size dropdown on the IDE toolbar? If so, please share and the Flex presenter / speaker community will give you a hug.

Can y’all see this in the back?

Changing the font size of the Eclipse text editor is a royal pain. It is a completely undiscoverable feature. It seemed that all the 360 Flex sessions I attended had the same scene:

Presenter: OK, let’s look at some code now. (switches to the IDE, either Flex Builder or full-blown Eclipse)

Guy At The Back Of The Room: Umm. Can you increase the font size so that we can read it back here?

Presenter: Oh, OK, no problem. (fiddles with Eclipse for a few seconds) Umm. Anyone know the secret handshake?

GATBOTR: Preferences —> General —> Appearance —> Color And Fonts —> Text Font —> Change …

Presenter: Whut?

GATBOTR: (louder and more slowly, as if talking to one's great Aunt Ethel) Preferences —> General —> Appearance —> Color And Fonts —> Text Font —> Change …

Presenter: (kinda sorta fiddles some more, and eventually stumbles onto the right path) OK, got it.

GATBOTR: Thanks.

I think the brain is wired to immediately forget such painful experiences. It almost made me long for the intuitiveness of Ctrl-Alt-Delete again. As the conference progressed, some of the presenters got wise early, and had pre-configured their IDE for “presenter mode”, but if they were like me, they still had a hard time finding it buried in the UI. I had to search the Eclipse online help the night before my presentation in order to find the setting.

Turn down the suck

Now, I’m not trying to bash Eclipse here. Really. I like Eclipse. I have all their albums.

I’m just guessing that this UI just sort of grew unwieldy over time, rather than by design. Maybe it is already scheduled to be fixed in the 4.x codebase. But the current experience sucks.

Preferences —> General —> Appearance —> Color And Fonts —> Text Font —> Change …

I'm counting seven clicks (7!!!) until I see a familiar font size selection dialog. There are at least three glaring issues at play:

  1. The "Colors and Fonts" category is too long, and by default is clipped to "Colors an". So I can't even just use the tree control to expand and navigate the categories. I have to click each expanded item to see if its full name gives me some clue about what it controls.

  2. Once selected, the "Colors and Fonts" panel displays the list of settings, and the "Text Font" entry is selected (it is highlighted in blue), but there are no obvious controls that suggest "click me to change the font".

  3. So now you click the already-selected entry "Text Font" and viola! The "Change" and "Reset" buttons appear like magic.

  4. OK, I know I said 3 issues not 4. I'll concede that this one might just be me. Grouping colors together with fonts doesn't make sense to me. I assume that each language controls its own syntax highlighting, so I just don't expect to be setting colors when I'm setting fonts.

How to help

A savvy Java developer (ie. not me) can probably create a wee widget to sit in the IDE toolbar and add a font size dropdown. No font face changes, no color changes, just make the existing font bigger for the text editor (or better yet, the text editor and any console/output/trace buffer windows).

There now. Assuming this saves 2 minutes of a 60 minute session, the widget you’ve just created has increased the productivity of the presenter by 3%. Not bad! U R AWESOME!!!!

Sunday, August 19, 2007

Using SWFObject and the AIR install badge for easy deployment

One of the topics I spoke on at 360|Flex was how to add an "Install Now" button to a page, using the AIR install badge from Adobe. This is very easy to do, even though this post is long-ish. Explaining what is happening takes longer than the dozen lines of JavaScript required to get this to work.

I have an example "Install Now" button for DryerFox in the blog sidebar. This button will provide a one-click install experience for your users.

Quick-n-dirty summary for adding an "Install Now" button.

Copy foo.air to your web folder. This is your app's AIR application bundle.

Create a 215 x 100 image of your app, and save it as foo_badge.jpg in your web folder.

Copy swfobject.js to your web folder. Thanks to Geoff Stearns for the fabulous SWFObject.

Copy badge.swf to your web folder.

Add the following HTML snippet to your page:

<script type="text/javascript" src="swfobject.js"></script>

<div id="foo_flashcontent">
Whoa. You need to install <a href="">Adobe Flash Player</a>.

<script type="text/javascript">
var so = new SWFObject("badge.swf", "badge", "217", "180", "6.0.65", "#FFFFFF");
so.addVariable( "appname", "Foo" );
so.addVariable( "appurl", "foo.air" );
so.addVariable( "imageurl", "foo_badge.jpg" );
so.addVariable( "airversion", "1.0.M4" );
so.addVariable( "buttoncolor", "008811" );
so.addVariable( "messagecolor", "000000" );

Details - Under the hood

The SWFObject script will replace the <div> section labeled "foo_flashcontent" with the badge SWF, and populate its required Flashvars with your apps resources. Note that it is important to include some sort of fallback text in the <div> in case no Flash player is found.

Flashvar nameDescription
appnameThe name of your app. This name will be displayed by the badge in various messages below the "Install Now" button. Messages like "In order to install FooApp, the AIR runtime will also be installed".
appurlThe URL of your app's AIR bundle. The URL can be relative to the same folder as the page, or can be an absolute URL pointing to some other domain.
imageurlThe URL of the 215 x 100 image (JPG/PNG) to display inside the badge. As with the app URL, this URL can be relative or absolute.
airversionThe version of the AIR runtime required by your app, as specified in Foo-app.xml. For Moxie beta 1, this is "1.0.M4".
buttoncolorThe color of the "Install Now" text in hex RRGGBB format.
messagecolorThe hex RRGGBB color of the message text displayed below the badge.

Clicking the badge will do the following:

Auto-update the Flash player. The user's current Flash player version is examined and the script will update to the latest Flash Player if required. This bootstrap works as far back as Flash player 6.0.65 (released in December 2002), so that gives pretty good coverage. Will a 2002-era computer run a useful AIR app? Hmm. Probably not.

Auto-install the AIR runtime. Verify that the AIR runtime required by your app is installed, and auto-install it when missing. Each AIR app is tied to a specific runtime release, and the install badge knows how to deal with this correctly.

Auto-install your AIR app. This is, of course, what you really wanted to do in the first place.

Security Issues

Just to be clear, all of the above installation operations take place in the context of the active operating system user account. No OS security restrictions are bypassed, so the user will need admin or install privileges to succeed. This is a good thing.

Churn, Churn, Churn

The badge.swf example was added to the Flex SDK as part of the Flex 3 (Moxie) public prerelease, but that version of badge.swf was rather buggy. Adobe quickly released a patch and you will need to use the patch and avoid the one included in the SDK. I'm sure this will be fixed in the next public code drop. For now, avoid the code in INSTALLROOT/sdks/moxie/samples/badge.

Also make sure your web server is configured to know the mime-type of .air files. (*.air=application/vnd.adobe.apollo-application-installer-package+zip) More detail on the mime type is found in Mike Chamber's post here.


Tom Cornilliac's excellent post on the AIR install badge. (It is just missing the SWFObject example)

Friday, August 17, 2007

So here's the downside of having a dozen designers on staff

So I'm in Seattle for the 360 Flex conference, speaking about DryerFox yet again, and the "Your Mom" jokes start flying fast & furious from the entire EffectiveUI team.

Saying "your mom" to an EUI-er is like saying Aloha to a Hawaiian. You can use it as a greeting, as a goodbye, or in place of whitespace or punctuation.

So I'm feeling a little punchy at the end of a day and I spam this silly self-portrait to the entire company.

Suddenly, our president Anthony spams back with "$20 to the best Photoshop of Doug's pic by Friday". Everyone knows that designers are completely shameless when a twenty is waved in front of them so now I've got the equivalent of Something Awful's PS forum descending like vultures on my boyish good looks.

I'm not the judge of this contest, but I'm pretty sure Patrick will win with this entry, which I absolutely love!

Out of respect for you Patrick, I will always say "Your Mother". :-)

var office:Office = new Office( "EffectiveUI" );

I've been offline for longer than I wanted, and now I've got too many blog post ideas and not enough time.

So first things first, I'm happy to announce that I've joined the crazy folks at EffectiveUI, a rich internet app services company, with headquarters in Denver, Colorado. Some of the cooler public projects we've worked on include the San Dimas project for eBay and the Cancer Collage for Discovery Channel.

We opened up an Vancouver office a month ago (me and two other buddies) in the funky Gastown space offered by WorkSpace, home of the best barista in town (thanks Dane!)

The team down in Denver ("down" in longitude, but "up" in elevation) is a very creative and fun bunch, and I'm hoping that we can build an equally impressive team and culture here in Lotus Land.

I'm definitely gonna need to be riding my bike to work more often, since all the excellent restaurants nearby seem to be keeping me extra well fed.

Wednesday, July 18, 2007

DryerFox - Updated for new AIR runtime

I've finally updated my DryerFox hack for the Adobe AIR runtime. The conversion from the alpha version of AIR to the public beta was pretty straightforward.

One-click Install
I've added "Install DryerFox Now" badge in the sidebar, which should provide a one-click install experience, installing the AIR runtime if required, and then installing DryerFox.

I haven't logged too many test hours on the install badge, so please let me know if you have any problems.

Geek links
The source for DryerFox is available here.
The AIR file (the DryerFox executable) is available here, in case the "Install Now" button gives you trouble. You might need need the AIR runtime too, if "Install Now" chokes.

Monday, July 2, 2007

Please come again! Props to Apu!


The 7-11 near my home is one of only 12 stores across North America to be temporarily transformed into a Kwik-E Mart as part of the upcoming Simpsons Movie promotion. I saw the 7-11 under construction the other day, but I haven't been back to see the final product.

Hopefully, it will be close to the this 7-11 in Burbank, CA, which has been profiled on Flickr.

Sunday, June 24, 2007

Get on the bus, Gus! Come say hi in Vancouver July 11th

Mike Chambers was kind enough to offer me a chance to speak at the Vancouver leg of the Adobe onAIR bus tour.

I'm just doing a small session on my 15-minutes-of-fame-are-now-over DryerFox hack, as an example of no-chrome (or would that be self-chromed) app development.

This is a free event, and everyone is invited, but you need to register. I'm expecting the schwag-o-meter to be pretty high, so it will be worth it. I hope to see you there. Did I mention the free-as-in-beer beer? 'Nuf said.

Technorati Tags: , , ,

Saturday, June 23, 2007

Gee, I wonder how Silverlight will work on my Mac? Oh ... never mind

I was keen to check out some of the Silverlight capabilities on my MacBook Pro. I heard that our friends in Redmond were doing all their demos on a Mac first. Apparently none of them were running the latest 10.4 release.

Here is my out of the box experience ... Doh!

What, is the installer just doing a string compare on the versions?
Since when is 10.4.10 < 10.4.8?

OK, so it's a beta, and they'll probably have a patch soon, but it's a pretty nasty out-of-the-box experience.

Oh well, back to AIR-land.

[Update] There is a workaround posted on the MS-site, but it is clunky.

Sunday, June 10, 2007

I'm an Airhead now!

... but my wife could have told you that a long time ago. :-)

Adobe has renamed the Apollo runtime as "Air" (Adobe Integrated Runtime), and I like the new name. Apollo was a good code name, and "Air" is a nice product name. It also helps that the file format for Apollo bundles was already called a ".AIR" file.

I've been involved with enough products over the years to see my fair share of silly product names ending up with "designed by committee" feel to them. (Ironically, best described by this in-house Microsoft ad parody).

Congrats to the Air team.

New stuff on Adobe labs today:

Air beta installer:

Flex 3 beta:


Technorati Tags: ,

Monday, May 21, 2007

Ah! Movies the way I remember them ...

If you're as old as me, then you remember what movies were like when the first came out (right after the earth finished cooling).

Sunday, May 13, 2007

See you at 360|Flex in August

Apparently there is a bit of interest in pointless app development. I'll be presenting DryerFox at the upcoming 360|Flex conference in Seattle.

And while presenting is a nice boost for my ego, what I really hope to accomplish is:

  1. Stimulate discussion for the creative use of the WebKit HTML control.

  2. Encourage other Flex or Apollo n00bs to give it a try. I wasn't a Flex or Java developer before I started DryerFox, and I had it up and running in a few days. I think that speaks volumes for the short learning curve.

  3. Consume some good espresso and good micro-brew (but not at the same time).

I hope to see you there. Drop me a note if you plan on attending.

Technorati Tags: , , , , ,

Busy, busy, so here's a timewaster ...

I've been swamped over the past couple of weeks, so I thought I'd post a re-run link to a video I made from the recent Red Bull Flugtag event in Vancouver.

I condensed the 3 hour event into a 3 minute music video. I still think the best vehicle was the giant boombox.

Technorati Tags: ,

Monday, May 7, 2007

I'd like to thank the members of the academy ...

There is DryerFox sitting at #6! w000000000000000000000000t! I rule!!!!!!!!!!!!!!!!!!

Nothing warms my heart more than the comments of “useless, but I like it!” or “There’s no sense in explaining it; suffice to say that it’s absolutely useless, but we just had to mention it.”

Hooray for pointless endeavors!

DryerFox even beat out Scout from Adobe Labs! (#9 on the list, and an excellent web developer tool in its own right. I used Scout to help me hack-out DryerFox).

It looks like my blog is getting quite a viewer spike from all of this. More than half of its traffic
ever is from the last 6 hrs.

[Update 2007/04/09] Wow. I've had nearly 3000 unique visits over the past 2 days. Way more than the 150 visits from the previous 2 months!


Saturday, April 21, 2007

Mama don't take my MODA 'phones away!

Tm028Zma Unified

I ordered a set of V-MODA Vibe earphones on eBay last week for $70 US, and I've been trying them out on my iPod Shuffle, comparing them to the original Apple earbuds.

All I can say is "Wow"!

Having designed professional audio gear in a previous life, I knew the original Apple earbuds weren't anything spectacular, but after A/B ing the V-MODAs against the original PodBuds, I'm hooked.

The difference is incredible, even for an old guy like me. Bass exists once more, huzzah! I wear my iPod while cycling, and I was afraid that the silicon fittings would block out all the road noise, but that's not the case. Road noise is definitely muted, but still noticeable, so I'm still aware of my surroundings.

And now I can turn down the volume on my iPod and still hear more of the music than before. Yay!

Highly recommended (especially at the eBay price!)

3GB in my MacBook: Best $300 spent ever!

I've had my MacBook Pro since late December (Merry Christmas), and I ordered it with 2GB of RAM, thinking that would be enough. And it was, for a while.

Virtually Home Free

Partition080806 Box Desktop Ss Fusion

However, I'm now at a 4-week gig where I need to be running Windoze. I have a 20 GB Boot Camp partition running WinXP. I have both Parallels Desktop (paid for) and VMWare Fusion (beta) installed, and both allow me to run a virtual machine using my Boot Camp partition. I've configured my VM to use 1GB of RAM for Windows, leaving the rest for OS X to do its stuff.

So now I can either boot direct to Windows and get the full power of my MacBook to run Windows, or I can run Windows-in-a-window using one of my virtualization tools.

The problem is that running the 1GB VM on a 2GB Mac just ends up bogging down OS X to the point where I can't run anything else. Not Firefox, not Entourage, nottin'!

Solution - Just add money!

So I decided to max-out my MacBook's RAM, swapping out one of the two 1GB SODIMMs for a 2GB SODIMM, giving me a total of 3GB.

I ordered from They had a great price for a 2GB module ($299 Cdn) and they shipped overnight. With shipping and taxes, everything came to about $360 Cdn. I had other Mac stores in town quoting me between $600 and $800 (before taxes), but I've had good experiences with CanadaRAM before.

Wow. What a difference that extra 1GB makes. OS X is back to its old snappy self when running a Windows VM. All the Dock effects, Expose, and Dashboard apps make lovely smooth transitions, and the OS is no longer paging to disk like crazy.

Right now, I'm running my Windows VM, plus OS X is running Entourage, Excel, Flex Builder 2, Firefox, ecto, and Acrobat Reader. Everything is happy-n-snappy.

Plus I should be able to resell the extra 1GB SODIMM for about $150 on craigslist, making the deal even sweeter!

Which VM tool to run?

I had previously been running Parallels Workstation on my PC, so I bought Parallels Desktop when I got my Mac, so that I could reuse the same VMs on either host platform. When VMware announced their Fusion product for Mac, I just let it go and kept using Parallels. But my experience with later versions of Parallels has seen quite a large slow down. VMs just didn't seem snappy, no matter what the configuration was.

So I installed the Fusion beta and gave it a try. It is great so far. The biggest advantage so far over Parallels is that Fusion will present 2 virtual CPUs to the guest OS, letting my Windows VM take full advantage of any unused cycles.

As part of the Fusion beta tester agreement, I'm not allowed to post any public claims about the performance of the product. I don't want to violate that agreement. But I am running VMware Fusion exclusively now, so I'll let you draw your own conclusions. :-)

Technorati Tags: , , , ,

Tuesday, April 17, 2007

Inside DryerFox - Part 3: Using WebKit

The DryerFox hack was accomplished by a few basic ActionScript3 stunts.

Get Thee Behind Me, HTML!

When the application starts, it creates an HTML component beneath the image of the drum window, and slightly smaller than the window, so that event when rotated at 45 degrees, no parts of the HTML control "peek out" from behind the graphics.
// Match the size & location of the drum image
html.x = dryerDrumImage.x + 10;
html.y = dryerDrumImage.y - 10;
html.width = dryerDrumImage.width - 20;
html.height = dryerDrumImage.height - 20;

// Now add the html control to the beginning of the display list
application.addChildAt( html, 0 );

Allow mouse events to flow through

Since the dryer frame and the drum window are in front of the HTML control, we need to allow mouse events to flow through to the HTML control. This is done by setting the mouseEnabled and mouseFocusEnabled properties of the mx:Image components to false.

Browser events

Now that the HTML control can respond to mouse and keyboard events, the control can now load web pages and respond to user input. Just to make things fun, I wired up some event handlers to start the drum rotation and sound FX when a page starts loading, plus another handler to stop the drum and sound when the page is fully rendered.

WebKit limitations

The Apollo HTML control is based on the open source WebKit engine. This is the HTML engine used for Apple's Safari browsers, and others too, including the Nokia S60 mobile platform. So yeah, maybe I should have called the app SurfinSafari, but I thought DryerFox was more catchy.

The WebKit control is capable of handling most HTML and JavaScript, but I've found a few things it won't do.
  • The mouse cursor doesn't change from an arrow to a hand when you mouse over a hyperlink, nor do the links change color to indicate they can be clicked. Some pages contain JavaScript snippets to perform similar animations (like changing the background color), and those appear to work. Even if the HTML control dispatched some sort of event like ON_LINK_ENTER and ON_LINK_EXIT, then an app could add a bit more affordance that most people expect from a browser.
  • There is no control over a right-click menu for the control, again something that most browsers offer.
  • Ironically, the WebKit control does not run Flash apps. If a web page attempts to load a .SWF, the page thinks that Flash is not installed. Maybe this is a security sandbox issue, but it doesn't seem to work.
  • There are no events raised for page-load timeouts or server-not-found.
Maybe these issues will be fixed by the time the Apollo runtime gets out of beta.

Inside DryerFox - Part 2: Web 2.0 is all about transparency

Transparent System Chrome

Yeah, that sounds like something that Scotty might complain about to captain Kirk. "We've run out of transparent system chrome, captain!"

I wanted to make DryerFox run without a normal window frame and live as a dryer/browser mashup floating on the desktop. It just seemed funnier that way.

In Apollo-speak, the outer window that contains the app is called the chrome. The chrome window behaviour is OS dependent, but it usually includes the window title, plus buttons for closing, moving, and minimizing the app.

An Apollo application has a choice of either using the OS chrome (default behaviour), or disabling the system chrome completely. If you disable the system chrome, your app will need to handle window movement, sizing, and closing in some other way.

Thankfully, the Apollo samples include the WeatherStation app as an example of how to do this.

Hidden Gotchas

If you skim the documentation, it seems like all you need to do is tweak the -app.xml file to remove the system chrome, but it is a little more subtle than that.

Here are the steps I used:
  1. Create a new Apollo project in the Flex Builder IDE. Let's assume the app is called "NoChrome".
  2. Edit the NoChrome-app.xml file generated by the IDE. Change the systemChrome and transparent attributes of the node. should be changed to ="none" transparent="true" ...>.
  3. Run the app. Hey! It still has chrome! WTF? (why the frown *cough*)
  4. I was stuck at the previous step for about 30 minutes until I read the comments in the -app.xml file and remembered that Mike Chambers had said "now pay attention to this" in one of his ApolloCamp sessions..
  5. Change the type of the root application component from to (from which ApolloApplication derives). Then you're good to go.
  6. I also duplicated the Application sytle sheet from the WeatherStation app, but I'm not 100% sure if this is required.
Application {
/* make app window transparent */
padding: 0px;
Perhaps later releases of the Flex Builder Apollo extensions will provide an easier way of switching between systemChrome and noChrome modes. For an alpha release, it's still a pretty kick-ass offering.

Monday, April 16, 2007

Inside DryerFox - Part 1: Creating the media assets

Just in case my DryerFox post didn't make it apparent, I'm not a graphic artist. But I can hack away with Adobe Fireworks with the best of them, so that's what I did. I googled for the biggest image I could find of a front loading dryer, and I found the image on the left.

Here's what I did to get the one on the right:

I spent a bunch of time learning & fiddling with Fireworks. At least 50% of this project time was due to my lack of design skillz.
  1. The black background was easy to turn transparent.
  2. I then split the image into 4 layers: the control panel, the lid, the frame, and the drum.
  3. I stretched the lid and frame to make the dryer more squarish.
  4. I repositioned the unstretched control panel appropriately.
  5. I made the drum as large as possible, even making the rim thinner, to maximize the portion of the browser window that will show inside the drum.
  6. I got rid of the squarish reflection on the glass bubble. I used the "magic wand" selector in Fireworks to find all the similar connected pixels, and then I just lowered the brightness.
  7. Then I realized that the image was actually a top-load washer, not a dryer. Agh! Darn you inaccurate search engine metadata! But my result looked pretty, so on I went ...
Sound Effects
OK, now I that I had graphics, I needed some decent sound FX. Here I have a bit more of a background, having spent 6 years designing digital audio equipment. Normally, I'd hop on over to Sound Dogs (think iStockPhoto, but for sounds), since they have such a huge library.

But one of the main inspirations for this project is the nagging sound of my own dryer, which is right next to my home office. So I just brought my MacBook Pro into the laundry room and recorded it directly using the built-in mic.

I needed to disable the "Use ambient noise reduction" setting, since ambient noise was exactly what I was after.

I cranked up the input volume and recorded a 40 second run of good heavy load of towels, complete with the wonderful clunk of the relays kicking in when the dryer shut off.

Alrighty, I had all my media assets, so then it was off to Flex Builder to create the app, covered in the next post.

DryerFox - It's like Firefox, but inside a dryer!

Long-time listener, first-time coder! Here's my first Apollo app ...

I was lucky enough to attend the original ApolloCamp event in March, and I've been spending the last while learning the Flex & Apollo environments.

One of the cooler things about the Apollo framework is the addition of an HTML control based on the WebKit engine. This is the HTML engine used for Apple's Safari browsers, and others too, including the Nokia S60 mobile platform.

Since the Apollo mx:HTML component is rendered as part of the Flash display list, this allows any Flash effects to be applied to an active web page. Blurs, tweens, rotations, it all works.

Presenting ... DryerFox!
I knew I wanted to do something fun with HTML, but the question was: do what? Inspriration hit las Thursday, and I decided to create DryerFox - A rotating browser window wrapped by a dryer image.

You can type any URL into the app, and the page will be loaded and rendered. As the page is loading, the dryer's drum turns, and therefore so does the page. You can also manually rotate the drum using push buttons. The page remains fully interactive, no matter what the rotation. You can read your webmail, surf the net, or whatever. There is even a button to reset the drum rotation back to normal, so that you don't strain your neck.

Installing the demo

  1. Install the Apollo runtime framework on your Mac or PC, if you haven't already done so. It is an alpha release, but still pretty solid.
  2. Download the DryerFox demo .AIR file. (.AIR is the extension for Apollo apps, but it is just a ZIP file)
  3. Double-click the downloaded .AIR file, and the Apollo runtime will lead you through the rest of the installation process.
The source for the hack is available here, in case you want to hack it further yourself. You'll need the Flex development environment to do that.

I'll describe the making of DryerFox in a future post, but I wanted to get this out there for feedback.

printf( "Hello world!\n" );

Why do I have the nagging feeling that blogging has suddenly become unhip?

Thanks for showing up anyway. I hope to use this blog to write up some of the fun things I'm learning as I make the leap from diehard C++ developer to a Web 2.0 GUI guy.

I've recently started developing rich internet apps running on the Flash platform, using Adobe's Flex Builder 2 and the Apollo desktop framework. I'm especially intrigued by how easy it is to develop useful apps using Flex.

There is a great body of Flex & Flash work online, and I hope I can contribute some worthwhile stuff as well. Some of that contribution depends on your, dear reader, so let's try and make this blog into a useful conversation.