Apollo Beta Sneak: System Icons June 4
Well, since the news about Apollo using SQLite as a local database has been released, I thought I’d go ahead and spill a few more beans. This may even become a trend, as it’s really hard keeping all these cool secrets. I thought I’d start with a little example that I really thought was exciting - support for system icons. Not being enough to simply stop there, this example will also save the images of the icons to the local disk as PNG files. Oh, and did I mention that this will be entirely HTML/JavaScript? Let’s get started!
I want to be clear up front here that I’m giving you a sneak peak of Apollo builds before it actually hits the beta milestone. There are no guarantees that the API’s will look exactly like this come time for the actual beta.
One of the first things I need to introduce is a new “aliases” JavaScript file that helps make code a lot more readable, and a lot easier to type. To use classes in the alpha version of the Apollo runtime (currently available on Adobe Labs) from JavaScript, you had to have a full reference to the class. That meant your code looked like:
var myFile = new window.runtime.flash.filesystem.File();
Over time that got downright tedious and messy. In the Apollo Beta, you’ll insert the alias file into your code via the HTML SCRIPT tag, and then that same line of code becomes:
var myFile = new File();
I’d say that looks a little cleaner! There are a number of core API classes in the alias file, not just the File class. Of course this is just a JavaScript abstraction, and nothing particularly tricky, so you can add your own aliases if there are classes in the API that aren’t represented in the alias file that will ship with the SDK. To be fair, what to include in the alias file, and what to not include, has been an area of much debate. If you have thoughts about the classes you use the most, it’d be great if you could leave a comment, so we can roll that into a future release.
Since the File class is still fresh in our minds, and since the title of the post has to do with icons, I should probably mention that there’s a new File.icon property. As you might guess, the File.icon property is of type Icon. The trick to icons is that there’s usually more than one size. To solve that problem there’s an Icon.bitmaps property which is an Array containing BitmapData objects. Those BitmapData objects are the raw data behind how the icons are represented by the operating system. Pretty cool, eh?
I know what you’re thinking - that’s great, but how do I get raw bitmap data into an HTML IMG tag? That’s where this discussion starts to get even more interesting!
The BitmapData class has been around in Flash for a while, since Flash Player 8, and it wasn’t long after it was released that people started writing image encoders. The most popular of these encoders are JPEG and PNG encoders. The HTML IMG tag supports both formats, but since JPEG is lossy, I thought I’d go the PNG route. I used Patrick Mineault’s PNG encoder as a base and ported it over to JavaScript. Using the Apollo file IO features, I then write the icon representations to the local disk, and use that file reference in the IMG tag’s “src” attribute.
The source code follows, and it’s pretty thoroughly commented. No application file is included because this is based on a runtime that’s not yet publicly available and wouldn’t work on the Apollo alpha. I have however included a screen recording of the application in action.
The exciting thing for me here is that historically, web-based applications (Flash or HTML) have had to fake the icon of a file. That meant that for the most part you could probably deduce what the user’s icon for a Word document might look like, but you couldn’t really be sure. With this functionality, an application developed using web technologies (HTML/CSS/JS) that’s deployed in Apollo, can now show what the user expects to see, and what’s registered on their specific operating system.
The second point to make is really an extension of the file IO features that were introduced in the Apollo alpha. The fact that JavaScript can now read and write local files ranging anywhere from text to binary opens a lot of doors. What files you choose to work with are limited only by your own imagination. In this case, I’ve used a PNG encoder based on work done from the community. Imagine seeing open source JavaScript libraries to work with other files types from images to Word and beyond!
<html>
<head>
<title>System Icons (and Bitmap Encoding)</title>
<!-- The Apollo aliases file to common classes in the API -->
<!-- Patrick Mineault's PNG encoder, ported over to JavaScript -->
<script type="text/javascript" src="ApolloAliases.js"></script>
<script type="text/javascript" src="KPNGEncoder.js"></script>
<script>
// One of the aliases not in the aliases file, so I make my own
var BitmapData = window.runtime.flash.display.BitmapData;
var file = null;
// Called when the browse button is clicked
function doBrowse()
{
// Browse for a file to get the icon(s)
file.browseForOpen( "Select a File" );
}
// Called when the document finishes loading
function doLoad()
{
// Instantiate a starter point for the browse operation
// Add an event listener for when a file is selected
file = File.applicationResourceDirectory;
file.addEventListener( Event.SELECT, doSelect );
// Add the event listener to tbe browse button
document.getElementById( "btnBrowse" ).addEventListener( "click", doBrowse );
}
// Called when the user has selected a file from the dialog
function doSelect()
{
// Variables that will be used in processing the bitmap data
var elem = null;
var encoder = new KPNGEncoder();
var img = null;
var largest = 0;
var move = File.applicationResourceDirectory;
var row = document.createElement( "div" );
var stream = new FileStream();
var temp = null;
// Put a little spacing between rows
row.style.marginBottom = "5px";
// Iterate through the available bitmaps (icons)
for( var i = 0; i < file.icon.bitmaps.length; i++ )
{
// Track the largest size for reference
if( file.icon.bitmaps[i].height > largest )
{
largest = file.icon.bitmaps[i].height;
}
// Encode the raw bitmap data into PNG
img = encoder.encode( file.icon.bitmaps[i], 0 );
// Create a temp file to put the image on disk
temp = File.createTempFile();
// Open the file, write the image bytes, and close the file
stream.open( temp, FileMode.WRITE );
stream.writeBytes( img, 0, 0 );
stream.close();
// Create a file reference to a known place on disk
// Move the temporary file to the known destination
move = File.applicationResourceDirectory.resolve( "icon_" +
file.extension + "_" +
file.icon.bitmaps[i].width + "x" +
file.icon.bitmaps[i].height + ".png" );
temp.moveTo( move, true );
// Insert images for the icons into a row (div
elem = document.createElement( "img" );
elem.setAttribute( "src", move.url );
row.appendChild( elem );
}
// Append the row of the images into the document
document.body.appendChild( row );
}
</script>
</head>
<body onload="doLoad()">
<!-- Allow the user to trigger the file browse -->
<input id="btnBrowse" type="button" value="Browse..." />
</body>
</html>







Mike Huntington Jun 4
I like the idea of adding the aliases file to make coding easier. And thanks for that very “detailed” video lol.
Vivekanand Jun 5
Hi Kevin,
I need your Help. Since yesterday I was doing some R&D on Apollo Applications, I am using Windows Vista (Home Edition) - I have downloaded all the required stuffs from the site and developed one example. I am successful in compiling through ADL command through command prompt - The example which I have did is perfect working fine. But my query is - when I tried to package the things to get .air file - at command prompt it is showing up an error like
D:\>adt -package RetrievePageApp.air RetrievePageApp.xml RetrievePage.html exPage.html loading.gif bg.gif
Unknown option: ûpackage
Usage: adt -package air_file app_xml [ file_or_dir | -C dir file_or_dir … ] ..
As I have mentioned above, it is showing up as Unknown option:ûpackage - and unfortunately I could able complete my task .air is not created.
It would be great if you can suggest me on this regard.
Please Please…. Help me out from this…..
Thanks,
Vivekanand