Why and when to break out of the browser

"A web app can do what a computer from 15 years ago, without a disk can do" Daniel Jalkut
While Daniel Jalkut was sort of kidding when making this statement on "Core Intuition 17", he wasn't really kidding. The fact remains that desktop applications sport a lot more features, both UI, functionality and user friendly vise compared to Web 2.0 applications. But, when does it make sense to move something onto the desktop, and to what desktop?

With the advent of the real iPhone SDK and the AppStore, Apple managed to light a spark in the idea of creating applications once again. It's nothing new, this idea of creating applications instead of webpages, however the distribution model(AppStore) is "new". Suddenly everybody, designers, web-developers, marketing people.. the list goes on.. everybody is making iPhone applications. In most cases they are good apps, however in other cases there seem to be a lack of planning/thought ahead of launching xcode.

Why and when should you consider making your project into an application instead of a web-application? I always ask myself the following questions before making such a decision:
  • Does the application need to access local resources on the users computer?
  • Does the application need to exist outside the web-browser? Why?
  • Does the application rely on server storage completely?
  • Does the functionality ask for a custom UI?
  • What solution handles the users frustration level in the best way?
  • Does the IA need a page-based layout?
  • What's the degree of interaction required?
While contemplating these questions you would probably form an idea as to what is needed for your application to succeed. But, bear in mind that most of the questions above result in solutions that can and will run fine in a browser. Trough RIA tools like Flex and SproutCore, the most demanding UI demands can be met. But, if your application needs to do a lot of local file access, or it needs to exist outside a browser session... Imagine a chat client running only in the browser, it would be no good because you'd go offline when you closed the window.

My advice would be this: Think about it.. are you presenting information that constantly updates, like a news site, why in gods green acres would you do that in an application, it screams web page! Remember that users pick their applications(no matter the platform) with much greater consideration and care than they pick websites to read/use. An application on the computer desktop or on any device needs to satisfy a need or solve a problem, be it something practical or a just game. An application exists forever, because you don't own it like you own your webpage. A webpage can be revoked and it will for all intense and purposes be gone from this world. An application is downloaded and cannot be removed unless the user decides to delete it.
Don't try to emulate a desktop application in a webpage if the application actually needs to exist on the users computer. Try to see if you idea fits into the following boxes, in this order:
  1. Can I solve this using HTML/CSS?
  2. Can I solve this using HTML/CSS and JavaScript
  3. Should I solve this using SproutCore/Flex(or similar)?
  4. Can I solve this without platform specific APIs?
Here is what I would do:
  1. Create a webpage
  2. Create an advanced webpage
  3. Create a RIA application running in the browser
  4. Create a RIA/RAD application running in a cross platform runtime(AIR or Java)
  5. Create a platform application
Now, go do some real work, until next time.. cheerio!

Generating a thumbnail and saving it to disk

This quicktip will show you how to load an image from wherever and how to generate a thumbnail from that image and save it to the disk. In fact, you can use this method to generate screen dumps from any visual component from within Flex.
There are some considerations, first the actual scaling of an image can be done in several ways, the most used trough a scale Matrix. However, in this example I'll be utilizing the Flex library in order to scale the image using smoothing, thereby accomplishing a better result than with simply a Matrix.

Let's say I have loaded an image into a Flex Image component(myImg) and wish to generate a widescreen(16/9) thumbnail for it.
Load the image
myImg.source = "http://graphics8.nytimes.com/images/2006/12/28/business/28dog.xlarge1.jpg";

When the image is finished loading(Event.COMPLETE) we generate the thumb at a size of 200x112
var orgBitmap:BitmapData = new BitmapData(myImg.contentWidth,myImg.contentHeight);
var thumb:BitmapData = new BitmapData(200,112);
orgBitmap.draw(myImg);//Get the orginal image

var scaleImg:Image = new Image();
scaleImg.load(new Bitmap(orgBitmap,"auto",true));//Set smoothing to true
scaleImg.content.width = 200;
scaleImg.content.height = 112;

thumb.draw(scaleImg);//Here we have the scaled image data

Now we have scaled the image using the Image component in Flex which actually does smoothing on the image when scaled. Now we need to convert the bitmapdata into valid JPEG format.
var myjpeg:JPEGEncoder = new JPEGEncoder(80);//Set quality to 80
var thumbdata:ByteArray = myjepeg.encode(thumb);

Now we need to save it to disk(to desktop)
var fl:File = File.desktopDirectory.resolvePath("myimage.jpg");
var fls:FileStream = new FileStream();
fls.open(fl,FileMode.WRITE);
fls.writeBytes(thumbdata);
fls.close();

There you have a smoothed thumbnail waiting for you on the desktop.

Coding the DocumentClass in Flex Builder

Since the dawn of Flash CS3, developers have been given the grace of the DocumentClass(explained). The DocumentClass effectively replaces the «lets write all our code on frames» approach which, frankly was more of a hackers approach to coding within the Flash IDE. The main advantage of the DocumentClass is it's life outside of the Flash IDE, it's a separate .as file.
However, there are some things to consider when jumping in to a project using the DocumentClass. One of these considerations must be, that the built in code editor in the Flash IDE, well..it's not the best environment in to be writing code. Alternative ActionScript editors exists, like TextMate(OS X) or FlashDevelop(Win). But the far superior cross platform alternative in my opinion, is Flex Builder. FB is great for many reasons, mainly because it utilizes the power of the Eclipse platform, an environment well known to Java and CF developers.
In short, Flex Builder is a powerful coding environment. But there are some considerations to take when working with a DocumentClass to be exported trough Flash.. one of them is that Flex cannot see your instance names(objects on the stage) and give you code completion on them..in fact, it will complain and claim it's an error. This can be fixed in a jiffy..

  • In Flash, open the project settings.

  • Click the «Settings» button to the right of the «script» drop down

  • Unckeck «Automatically declare stage instances»

Now Flex will let you declare your own instances from within the DocumentClass, like they where properties of the DocumentClass itself(which they are). However, you will need to define the instances as «public» properties/variables, so the Flash compiler can see them. Okay, time for an example.

Let's say I have a blue movieclip on the stage with an instance name of "cheeseball". Here is how I access this movieclip from within my DocumentClass.

package{
import flash.display.Sprite;
import flash.display.MovieClip;

public class MainClass extends Sprite{

public var cheeseball:MovieClip;//<-----

public function MainClass(){
trace("The name of the clip is "+cheeseball.name);
}
}
}


As you can see, the «cheeseball» movieclip on the stage is now accessed by defining it as a public property, making it visible to both Flash and Flex, giving you code completion, error checking and all kinds of wonderful things. Do this and your day will be shinier!

QuickTip: MOUSE_OVER vs ROLL_OVER

So, what is the difference between the MouseEvents, MOUSE_OVER and ROLL_OVER? The short answer is that MOUSE_OUT triggers when mousing over a child of the listener object, ROLL_OUT only triggers when leaving the listener objects bounding box. Consider the following code:

var sp:Sprite = new Sprite();
sp.graphics.beginFill(0xFF0000);
sp.graphics.drawRect(0,0,200,200);
sp.graphics.endFill();

var inner:Sprite = new Sprite();
inner.graphics.beginFill(0x00FF00);
inner.graphics.drawRect(0,0,50,50);
inner.x = 75;
inner.y = 75;
sp.addChild(inner);
addChild(sp);

sp.addEventListener(MouseEvent.MOUSE_OVER, report);
sp.addEventListener(MouseEvent.MOUSE_OUT, report);
sp.addEventListener(MouseEvent.ROLL_OVER, report);
sp.addEventListener(MouseEvent.ROLL_OUT, report);

function report(evt:MouseEvent):void{
trace(evt.type);
}


The sprite "inner" is a child of "sp". When rolling over "sp", both the MOUSE_OVER and the ROLL_OVER will trigger. However, when rolling over "inner", MOUSE_OUT will trigger, succeeded by MOUSE_OVER again. ROLL_OUT will not trigger when rolling over "inner". Test it out and it will all become clear!