June 9, 2009
New version of PixelWindow
PixelWindow (was PixelPerfect) was one of the first AIR applications I wrote, and has turned out to be one of the most useful. I wrote it primarily as a test case for multi-window, custom chrome, transparent, pure ActionScript AIR applications, and I've been using it almost daily ever since.
If you're unfamiliar with PixelWindow, it's a simple, light-weight AIR application for measuring things on your screen. It creates a translucent window that acts like a pixel ruler with its width and height reported in the center. Just drag it around and resize it to measure whatever you want.
I finally got around to updating PixelWindow, and creating its own site and installer badge. I also added a few new features:
- You can now measure down to 15x15 pixels. When the ruler gets too small to display the dimensions, they jump outside the window.
- The ability copy dimensions to your clipboard.
- The ability to use your keyboard to move rulers by one or five pixels at a time.
- A help window to remind you of the keyboard shortcuts.
If you use an old version of PixelWindow (probably installed as PixelPerfect), I recommend that you grab the new version. And if you don't use it, it's an extremely useful app for any designer or developer to have around. And remember that PixelWindow is open source, so feel free to grab the code to fix bugs, add features, or just to see how it works.
Posted by cantrell at 9:53 AM. Link | Comments (2) | References
January 30, 2009
ShareFire: a new feed reader for Adobe AIR
Over the summer, I built a feed reader called Apprise with my intern, Dan Koestler. Dan is now working with me full-time, and the first thing he did when he started at Adobe was update the application and release a new version. The following changes were made for 1.5:
- Renamed the application to ShareFire. It's all about sharing news, after all.
- Enabled shorter update intervals. You can now updated as frequently as every 15 minutes.
- On OS X, the number of unread posts now appears in the dock icon.
In case you're new to ShareFire, here are some other interesting features:
- Share articles via Twitter, AIM, email, Facebook, Delicious, Digg, Newsvine, and more right from the application.
- Automatic categorization by author and topic.
- Create "smart topics" to easily find posts on topics you're interested in.
- Get "toast" notifications of new posts.
- OPML import and export.
- Realtime search.
- "Site view" (switch between the summary, and the site itself).
- Automatic feed resolution. Rather than entering a feed URL, you can now enter a site URL, and Apprise will automatically find and aggregate the feed associated with it.
- Support for 16 languages.
- Lots lots lots more.
If you already have Apprise installed, you will get the update automatically (if you want to update manually, go to Settings > Application Updates > Check Now). If you don't have it installed, check it out here.
Let us know what you think!
Posted by cantrell at 9:44 AM. Link | Comments (8) | References
November 11, 2008
Revisiting Linux
It's been a long time since I've used Linux on a daily basis. Back in those days, my development tools were vim, make, and CVS. I ran an early free version of Red Hat with the best windowing manager there was at the time: FVWM. My browser was Netscape, my multi-protocol IM client was the text-based CenterICQ, and my mail client was Pine running inside of Screen. (My cell phone was a big plastic Nextel clamshell which the IT guys called the construction worker phone.)
But like many Linux users at the time, I was trying to exist in a Windows world. I used VMWare for testing web sites on IE, and various command line tools for converting Word documents that people insisted on emailing me into watered-down PDFs. So when OS X came out, I rejoiced and immediately jumped ship (before it even supported CD burning), and I've never looked back.
But when builds of AIR for Linux started appearing, I decided it was time to revisit Linux (specifically Ubuntu) to see what had changed. I made the mistake of installing it under VMWare on my MacBook initially which didn't impress me all that much since it wasn't able to access the graphics card directly, so yesterday I decided to set aside some time and install Ubuntu natively on my Mac.
From the time I got it in my head to give it a try to the time I was running AIR apps was probably about an hour. That included downloading Ubuntu 8.10, burning the ISO, using Boot Camp to make my Mac think I wanted to install Windows, and more or less following these instructions for installing Ubuntu on a new partition. Although I used an internal build of AIR for Linux, a public beta build is available here.
The experience of running Ubuntu natively really blew me away. The windowing effects are beautiful, and after using the OS for a few hours, I began to realize that Ubuntu even does a few things better than OS X. All my AIR apps ran beautifully (here's a screenshot of three of them running), and I began to realize that with Flex Builder for Linux, AIR for Linux, a few strategic AIR apps (Apprise Reader, TweetDeck, etc), Firefox, and with the amount of data that's moving to "the cloud," I could very easily start using Linux again day-to-day. I did encounter a few incompatibilities running Ubuntu on Mac hardware, but if I could get my hands on a decent ThinkPad, I think I just might be able to make the switch. Of course, I'll have to keep my Mac around for synching my iPhone since I did finally give up that Nextel i1000.
Posted by cantrell at 12:25 PM. Link | Comments (10) | References
September 2, 2008
Apprise 1.1: More sharing, more features, and more languages
We just released Apprise 1.1 with several new features:
- In addition to AIM and Twitter, now you can share posts via email, as well.
- Post links directly to Facebook, Delicious, Digg, Newsvine, MySpace, Google Bookmarks, and Windows Live Bookmarks.
- Smart topics. Only posts containing specific keywords will show up in your smart topics.
- Configurable notifications.
- Support for 16 languages: English, German, Spanish, French, Italian, Japanese, Korean, Portuguese, Russian, Swedish, Dutch, Czech, Turkish, Polish, and both Traditional and Simplified Chinese. Apprise will use the language of your OS, or you can change languages dynamically from the settings window.
- Improved aggregation. We now show you post content, if it's available, rather than just a post summary.
We've also added some smaller features and polish, and fixed several bugs. If you're already running Apprise, it will auto-update. Otherwise, go check it out.
Posted by cantrell at 9:14 AM. Link | Comments (5) | References
August 6, 2008
How do you want to share with Apprise 1.1?
We're working Apprise 1.1, and we'd like some feedback. Apprise 1.0 allows you to share articles via AIM and Twitter, and for 1.1 (not out yet), we're adding the ability to share via email, as well. We're also adding Facebook, del.icio.us, Google Bookmarks, and Windows Live Favorites. What other services would you like to see us support? MySpace? Newsvine? Mixx? Let us know what you're using, and we'll do our best to get it in.
Posted by cantrell at 8:40 AM. Link | Comments (14) | References
July 28, 2008
Share stories right from your news reader
Over the summer, my intern Dan Koestler and I decided to get serious about Apprise, a news reader written for AIR. There are a lot of news readers out there, so the natural question is what sets Apprise apart? Here's a summery of what I believe are our most compelling features:
- AIM integration. Send stories to your AIM buddies from Apprise rather than copying and pasting URLs into your AIM client. Apprise doesn't replace your AIM client -- it works alongside it to make sharing stories easier and more efficient.
- Twitter integration. Post URLs to Twitter directly from Apprise. Again, Apprise doesn't replace your Twitter client, but it makes posting stories to Twitter much faster and easier.
- Folders. We finally broke down and added folders, our #1 feature request. We now have folders for you to organize your own feeds, but Apprise still automatically organizes posts by author and topic, as well.
- Automatic feed resolution. It's surprising how many sites don't make it easy to find their RSS or Atom feeds. Now you can just enter the URL of the site that you want to aggregate, and Apprise will find the feed for you.
Apprise has several other cool features like realtime search accross all feeds, OPML import and export, Vi keys, and site view. And it finally even got a nice design so it no longer looks like a developer designed it.
You can find Appirse at apprisereader.com. If you already have an earlier version of Apprise installed, you should be able to click on the badge and replace it, but you also might need to uninstall the old version first. This version of Apprise adds auto-updated, so from now on, you'll get new features and bug fixes automatically.
Update: I should have mentioned that you should export your feeds before upgrading to the new version of Apprise so you can easily import them again. In future versions, all your feeds will be preserved.
Posted by cantrell at 8:04 AM. Link | Comments (4) | References
July 2, 2008
Closing all your application windows in AIR
Here's a little snippet of code I sometimes use in AIR applications to make sure all windows close when the main application window closes. I usually put it in the main application MXML file (the main window of the application). It stops the main window from closing, and closes any other opened application windows first in the opposite order in which they were opened (more recent windows first). Without code like this, if you have any other windows open, even little utility windows, and your main application window is closed, your application will not exit, even if NativeApplication.autoExit is set to true.
this.nativeWindow.addEventListener(Event.CLOSING,
function(e:Event):void
{
e.preventDefault();
for (var i:int = NativeApplication.nativeApplication.openedWindows.length - 1; i >= 0; --i)
{
NativeWindow(NativeApplication.nativeApplication.openedWindows[i]).close();
}
});
Posted by cantrell at 9:28 AM. Link | Comments (3) | References
June 16, 2008
AIR 1.1 and Apprise 1.5
Note: Apprise is now available at apprisereader.com.
With the release of AIR 1.1 comes a new version of Apprise, a feed aggregator written for AIR. Apprise is a work in progress with lots of additional features to come, but here's what we have so far:
- Support for all versions of RSS and Atom.
- Automatic categorization by author and topic.
- OPML import and export.
- Realtime search.
- "Site view" (easily switch between the summary, and the site itself).
- Check marks. Put a check mark next to posts that you want to keep track of and easily find again later.
- Advanced sorting. Sort feeds, authors, and topics by name, or by number of unread posts.
Apprise 1.5 adds the following features:
- Support for 11 languages. Apprise now supports German, English, Spanish, French, Italian, Japanese, Korean, Portuguese, Russian, Simplified Chinese, and Traditional Chinese. By "support" I mean the UI is localized into these 11 languages — the aggregator itself will support any written language.
- Automatic feed resolution. Rather than entering a feed URL, you can now enter a site URL, and Apprise will automatically find and aggregate the feed associated with it.
- Improved search. The search algorithm in Apprise 1.5 is much more advanced. Both the title and the summary are searched, and you can search for multiple terms in any order.
- Improved "new post" heuristics. Apprise 1.5 is more intelligent about figuring out which posts are new in order to eliminate duplicates.
- General polish. We added several little improvements like focusing the cursor where appropriate, and updating individual feeds' unread count during the aggregation process rather than updating them all at the end.
If you check the code out and build Apprise yourself, you can get even more features:
- Copy support. You can copy post URLs to our clipboard for easy sharing.
- Drag and drop. Drag posts into an IM or email window to share stories.
- Vi keys. Well, J and K, anyway.
My new intern, Daniel Koestler, and I will be working on adding new features to Apprise this summer. And, of course, it's all cross-platform and open source, so anyone who wants to contribute features can.
The next version of Apprise (2.0) will enable the auto-update feature so you'll be able to pick up new features automatically. We consider 1.0 and 1.5 to be betas, so they have to be manually installed. Click on the badge below to have a look at what we have so far, and let us know in the comments what features you want to see next.
Posted by cantrell at 8:38 AM. Link | Comments (2) | References
April 23, 2008
The latest version of PixelPerfect (with screencast)
PixelPerfect is a simple AIR application for measuring things on your desktop. If you want to see how it works, check out this screencast. If you want to see the code, check out the PixelPerfect Google Code project. And finally, if you just want to install it, click on the badge below.
Posted by cantrell at 9:12 AM. Link | Comments (4) | TrackBack | References
April 9, 2008
Maptacular 2.0: a desktop mapping application for AIR
Maptacular was one of the first applications I wrote for AIR. The first version parsed vCards from your local file system, and let you map the addresses it found inside. That was back when AIR was in still in alpha, so I didn't have APIs for things like drag and drop or copy and paste. Now that AIR 1.0 has shipped, I decided to rewrite Maptacular to to have the functionality that I originally envisioned.
I created a screencast of Maptacular 2.0 which you can watch here. If you want to install the app, just click on the badge below. If you want to see the source, it's all available on Google Code.
Maptacular is a good example of the following:
- Custom chrome with transparency.
- Custom application menus (implemented for the Mac only -- when Maptacular runs on Windows, there are no application menus).
- Context menus.
- Drag and drop.
- Copy and paste (system clipboard access).
- Yahoo! Maps for ActionScript 3 (with custom markers).
Posted by cantrell at 9:43 AM. Link | Comments (3) | TrackBack | References
April 2, 2008
Lineup: an Exchange calendar viewer for AIR
I did a screencast of an Exchange calendaring application I wrote for AIR. Click here to watch it.
It's one of the most useful applications I've written so far, and probably the most popular within Adobe. It lets you view your Exchange calendar, and it notifies you of upcoming meetings. It also works offline, so you can view your calendar and get meeting details while you're between internet connections.
Lineup uses all the following open source ActionScript 3 libraries:
- as3corelib: various utilities like advanced date parsing.
- as3exchangelib: talks to Exchange servers.
- as3nativealertlib: a modal alert that appears in its own native window.
- as3notificationlib: creates notification windows, and provides a layer of abstraction on top of OS-specific notifications.
- as3preferenceslib: manages application preference persistence, including encryption when necessary.
The complete source code for Lineup itself is also available on Google Code, or you can simply click on the badge below to install it.
Posted by cantrell at 9:39 AM. Link | Comments (10) | References
March 26, 2008
Tips on getting a code signing certificate
I got my own certificate for signing AIR applications a couple of weeks ago, so I thought I'd share my experience in order to help others more easily navigate the process. My intention is not to provide an exhaustive tutorial on code signing or the process of obtaining a certificate (if that's what you're looking for, see Todd Prekaski's article entitled Digitally Signing Adobe AIR Applications). Rather, I just want to list a few things you should know about before starting the process in order to ensure that it goes smoothly.
I decided to get my certificate from Thawte, but you can also use VeriSign (and soon other Certificate Authorities who Adobe is working with). Both Thawte and VeriSign issue code-signing certificates to organizations as opposed to individuals, so the tips below assume that you already have a corporate entity established. We are currently working with CAs who can issue personal certificates, so if you don't have a business, you will soon be able to get a certificate issued in your own name.
If you decide to get your certificate through Thawte, here are some important things to know:
- Use Firefox. Firefox has a certificate manager that allows you to easily export your certificate as a P12 file which is what you need in order to sign your applications. Yes, it's sort of a strange requirement, but it makes the process much easier.
- Use an email address other than Gmail, Hotmail, or Yahoo. Thawte will not issue a certificate to anyone using an address from a free email service. I tried to talk them into it (I love Gmail), but they wouldn't budge. I ended up having to use my Watch Report email address which they eventually accepted, however they would have rather I used an email address associated with the company's domain.
- Set up a corporate web page. My main business is Watch Report, but my company is called Cantrell Media Company. Since Watch Report is well established, I never bothered setting up a separate corporate web site. Thawte wanted one, so I threw together christiancantrell.com in about five minutes. It's not pretty, but it met the requirement.
- Get a business phone number, and list it publicly. I work out of my home, so I have a business line (I almost always use my mobile phone, but it's nice to have a landline to fall back on). However, when I got the second line, I didn't bother to create a corporate account with Verizon. Rather, I have both my home and business lines listed under my personal name. Thawte doesn't like this. They either want to see a phone bill with your business number and business name on it (which I couldn't produce), or they want to see your business and your business number listed in a public directory. I listed Cantrell Media Company on yellowpages.com which took a few days, but is completely free. Thawte was happy with that. (Here's the listing.)
Those are all the specific issues that caused me problems. If you own a business, and take all four points above into account when applying for your code-signing certificate, you should be able to obtain one within a couple of days with no problem at all.
Posted by cantrell at 10:48 AM. Link | Comments (8) | References
March 13, 2008
Apprise: an RSS aggregator written for AIR
Note: Apprise is now available at apprisereader.com.
I did a screencast of the RSS aggregator called Apprise that I wrote for AIR. Click here to watch it. I didn't put any effort into designing the app, so it looks pretty plain, but it's very functional.
All the source code for apprise is available here on Google Code. You can install Apprise by clicking on the badge below.
Posted by cantrell at 7:06 AM. Link | Comments (8) | References
March 11, 2008
Detecting network connections in AIR
One of the biggest benefits of AIR is that applications can be written to easily function whether online or off. Features like file access and a local SQL database give developers the functionality they need to write applications that can pull data from remote data sources while connected, but can also rely on cached data while disconnected. Of course, writing an application that functions seamlessly both online and offline requires that you be able to reliably detect whether you have a connection or not. This article will tell you everything you need to know to reliably determine not only if your application is connected or not, but also whether it can reach the services it requires.
Let me start by saying that this isn't as simple and straightforward as it might sound. In fact, in today's world of VPNs and 3G wireless networks and virtual network interfaces, it's actually pretty complicated. We didn't realize how complicated it was until early on in AIR 1.0 development when the engineer who was responsible for the online/offline functionality in the runtime gave me a build to test. I started writing an application that needed to know whether it was connected or not, and the first time I yanked my network cable out, we were surprised to find that it didn't work as expected. The cable was disconnected, my AirPort card was turned off, but for some reason, my computer (and the AIR runtime) thought it was still connected. After some investigation, we realized that the problem was a couple of virtual network interfaces that Parallels set up in order to be able to manage networking between OS X and Windows.
What ensued was an almost philosophical discussion about what it meant to be online and offline. Theoretically, my application might have been trying to talk to a service on my Windows virtual machine which would have meant that my computer actually was connected even though I pulled my cord out. Or I might have had an internet connection, but the server my application needed to talk to might only be accessible while connected to a VPN. Or I might be on a public network that blocks certain services, packets, or ports that my application relies on in order to access data. Or you might be sitting in an underground concrete bunker with no connection to the outside world whatsoever, but you're developing an application the retrieves data from a server running on your local computer which means, from the application's point of view, it's online.
We eventually arrived at the conclusion that there really is no such thing as online or offline, or at least no simple and practical definition that worked for AIR developers, and that meant there was no way we were going to get away with a simple online/offline API (the first version of this API allowed for the simple registration of online and offline events on the static NativeApplication instance). In fact, we realized that it doesn't even matter if you're online or not which meant we were trying to answer the wrong question. All that matters is whether you can successfully access a particular service. And to figure that out, we were going to have to deliver a couple different APIs, and probably some best practices around using them.
The two APIs we decided to deliver with the runtime are the networkChangeEvent, and the ServiceMonitor class. You register for networkChangeEvents on the NativeApplication static instance. Each time a networkChangeEvent is thrown, you know that network connectivity has somehow changed, but you don't know how it's changed. For instance, the user might have connected, disconnected, logged into a VPN, joined a wireless network, etc. That's where the ServiceMonitor class comes in. Since we determined that there really is no absolute concept of online or offline, you can use the ServiceMonitor class to tell you something which is much more interesting: whether or not you can actually reach a specific service.
The ServiceMonitor class has two subclasses: SocketMonitor and URLMonitor. The SocketMonitor is for monitoring services that you connect to directly with a TCP socket like a mail or an XMPP server. The URLMonitor class is for monitoring HTTP services like REST based services. Both can be configured to listen for networkChangeEvents for you, or they can can be activated manually by calling the checkService method. Both also have various ways to configure them to work with your specific service. The service event thrown by the ServiceMonitor has a code property which indicates whether or not communication with the service was successful.
This is a pretty complete solution, but there's still one more scenario that we haven't accounted for. Let's say the end user plugs in a network cable which causes the networkChangeEvent to fire which, in turn, causes the ServiceMonitor to check the state of the service. And let's say the service responds favorably which causes the ServiceMonitor to throw its status event with a code property of "service.available". Your application responds by showing a big green light indicating to the end user that all is well, and that it's safe to submit data to or pull live data from your remote service.
The problem is that the service might go down between the time you last checked it and the time your application needs to interact with it. Or your ISP might have suddenly gone out of business. Or an underwater transatlantic cable could have been cut. Any number of things could prevent your application from successfully talking to its services. The ServiceMonitor can't help you now, so it's up to you to catch the IOErrorEvents and handle them gracefully. Since I typically use the Cairngorm Flex framework, I have a single boolean property in my ModelLocator called online which any part of my code can access. I set the online property inside of my ServiceMonitor event handlers and also within my IOErrorEvent handlers, as well (and I also set it to true every time I successfully interact with a service). That way, whether the end user has no connectivity or the service the application is trying to access is down, the application behaves consistently and appropriately.
Of course, having a robust solution to reliably determining whether you're online or not is only half the challenge since your application also has to know how to behave in both circumstances. Writing a complete online/offline application is beyond the scope of this article, but I will say that hinging application logic on the ModelLocator's online property is the key. If you want a detailed real-world example, I recommend taking a look at Lineup, my Exchange calendaring application. It works both online and off, and demonstrates all the principles described in this article.
Posted by cantrell at 10:12 AM. Link | Comments (1) | References
February 25, 2008
What you might not know about AIR (yet)
If you're reading my blog, I'm going to assume that you already know what AIR is. If you don't, have a look at the official AIR product page before reading any further. Rather than tell you what you probably already know about AIR, I'd like to mention a few things that people might not have realized yet.
AIR isn't just another Adobe product. It isn't just a new tool or utility. It's an entirely new way to develop, deploy, install, and use desktop applications. Entirely new. I really can't stress this point enough. In the world of software, new products are launched all the time (if you don't believe me, just follow TechCrunch for a few days — it's staggering), each with a marketing team that wants you to believe that their technology is nothing less than revolutionary. So when something completely different does come along, it's sometimes hard to distinguish. How successful AIR will be and how quickly the technology is adopted is an entirely different topic, but there is absolutely no doubt that it's new and disruptive. I could easily write an entire white paper on the importance of AIR, but for the sake of brevity, I'll focus on three main points:
- Web technology on the desktop really makes sense. When I first heard the concept of running web technology on the desktop, I was admittedly skeptical. This was several years ago when my perspective on web applications was that we were all willing to sacrifice things like usability, richness, offline support, and features for the convenience of not having to host and update the apps ourselves, and the power of having your data accessible from any computer. That isn't even close to a valid assessment anymore. Thanks to Flash, Flex, and some truly amazing work done around JavaScript and Ajax, there are many applications on the web today that completely blow away most desktop experiences. The old adage of necessity being the mother of invention helped the web transition from a handful of HTML form controls and slow page refreshes to a rich, interactive, intuitive experience. The idea of unleashing those technologies and the developers working with this technologies on the desktop started making more and more sense, especially since it finally gives the final advantages that desktop applications had over web applications to web developers: local APIs, and offline support. The one thing web apps couldn't do were things like local file access, system notifications, native drag and drop, etc., and of course, no matter how great the web application was, if you didn't have an internet connection, you couldn't access it. This is what we mean by bridging the gap between the desktop and the web. AIR lets you have the richness of the web and the power of the desktop, and you can still do things like easily update your applications and store your data remotely. And you can do it all whether you're online or off.
- Cross-platform is real. For a long time, the idea of running the same applications and getting the same experiences on Mac, Windows, and Linux was a little bit like the idea of world peace. Everyone seemed to agree that it would be great, but it never seemed all that realistic. I think it's safe to say that AIR is the first technology to really get the idea of cross-platform right. I shouldn't over-idealize this aspect of AIR, however. To be perfectly frank, there are still challenges with building 100% cross-platform applications. Menuing systems work differently on Mac and Windows, and all platforms have concepts and conventions that other platforms don't have (system tray, dock, etc.). But I have written at least a dozen fairly full-featured AIR applications since we started working on the runtime, and I have never come across a cross-platform problem that I couldn't solve. In some cases, I've had to write layers of abstractions, and in some cases I've opted to completely avoid things like menus and focus instead on making functionality better integrated in the UI (which I believe is the trend in software development anyway — look at Microsoft Office 2007, the iPhone, and many of the best Mac applications). But the extra work I've had to put into making sure my apps ran seamless across platforms was often nothing more than an afterthought, and certainly negligible compared to the advantages of anyone on almost any desktop system being able to run my app. This point was really driven home when I first started using AIR on Linux. I'm a big Linux fan, and the idea of not just being able to run the same apps on Linux that I run on Windows and Mac, but actually develop those apps on Linux as well, is incredible satisfying and liberating.
- Today there are millions of new desktop developers. The last thing I want to mention is that I feel like we just opened the floodgates on the desktop. I feel like we just did to the desktop what the printing press did to education, or what flexible emulsion film did to photography. I don't know how many web developers there are out there, but I'm guessing there has to be millions. However many there are, there are now that many more desktop developers. Take a second to think about what that means. Someone with knowledge of HTML, JavaScript, Flash, or Flex can now build applications for the web, for Mac, for Linux, and for Windows, and all they have to do is learn a few new simple APIs. (I don't want to speculate too much in this post, but there are plans to bring AIR to even more places in the future.) Not only can they developer for all those different platforms, but they can develop on all those different platforms using all the same IDEs and tools they used before, and they can get everything they need (SDKs, etc.) entirely for free. Web developers have just been given an entirely new world, and everything they want is there for the taking.
I've been in the software business for 10 years, and I've worked on all kinds of projects. I've been fortunate that I've never had to work on a project that I didn't like or believe in. But I believe AIR is the most important project I've ever had the good fortunate to be involved with. I can't wait to see what the world does with it.
Posted by cantrell at 9:38 AM. Link | Comments (6) | TrackBack | References
February 21, 2008
AIR Development on Linux
I used to use Linux every day for about four years before coming to work for Macromedia/Adobe (over five years ago). My favorite tools were Screen, Pine, Centericq, XMMS, and Vim. My window manager of choice was FVWM which was doing fast and stable virtual desktops before anyone even knew what virtual desktops were. But I had to leave all that behind when I moved over to the world of Flash and Flex development. Fortunately I had OS X to help me make the transition, but as much as I've come to love Macs, I still sometimes miss the good old days of Linux.
So a couple of weeks ago when I heard that the Linux version of AIR was ready for testing, I dropped everything I was working on and set up Ubuntu, Flex Builder on Linux, and installed AIR. I keep all of my AIR application code on Google Code, so I installed SVN, checked out the latest versions of all my projects, and started running my AIR applications completely unchanged on Linux.
I use a MacBook Pro for development now, and I have Windows XP and Ubuntu virtual machines set up. I now have complete development environments including Flex Builder, AIR, and SVN on all three virtual machines, and all of my apps run across all three different operating systems (with the exception of some apps which use features we haven't implemented yet on Linux — it's still in pre-beta).
It's amazing enough that I'm writing desktop applications using web technologies like Flex, ActionScript, JavaScript, and HTML, but to be able to deploy them with no changes across Mac, Linux, and Windows is seriously revolutionary. The idea that I can actually go back to using Linux day to day, and still be able to do AIR and Flex development is very liberating. And now wherever there are gaps in Linux applications, I can just build them myself in AIR (like Lineup, an Exchange calendaring client that will enable me to view my meeting schedule on Mac and Linux as easily as on Windows).
As I said, the Linux version of AIR still needs more work, and is currently in pre-beta. If you're a Linux user, and you're interested in getting your hands on early builds and helping us do some testing, check out this post by James Ward to find out how to get involved.
Posted by cantrell at 12:14 PM. Link | Comments (6) | TrackBack | References
February 20, 2008
Transparent HTML in AIR
I keep forgetting how to do this, so I'm going to blog it once and for all.
First of all, it's possible to have transparent HTML in AIR. I don't just mean changing the alpha of the HTML Flex component. That's one way to do it, but that's not terribly useful. I'm talking about entirely knocking out the background of an HTMLLoader (formerly know as the HTMLControl) so that you can do very cool things like custom HTML chrome. I like it because I often use the HTMLLoader to render large amounts of text in AIR, like "help" or "about" pages, so making the background transparent can let me do some cool effects and presentations.
There are three things you need to know about making HTML transparent in AIR:
- Set the
paintsDefaultBackgroundproperty of the HTMLLoader to false. This specifies whether the background of the HTML document is opaque or not. If you're using the Flex HTML component, you can do this using thepaintsDefaultBackgroundattribute on the HTML MXML tag. - Make sure that your HTML document does not have a background color explicitly specified. For instance, setting
background-colorto anything will prevent this from working. - If you're using the Flex HTML component, make sure the
backgroundAlphaproperty is set to 0 (this is the one I always forget). Also, don't mess with theopaqueBackgroundproperty.
Ok, now that I have saved cumulative years of searching and trial and error, I expect that time to be reinvested into building even more cool AIR apps!
Posted by cantrell at 9:31 AM. Link | Comments (7) | TrackBack | References
February 14, 2008
How to Make Application Icons Appear During AIR Development
If you've started building an AIR application, you probably noticed that your application icons don't appear when launching your app via ADL (ADL is the AIR Debug Launcher, and is what Flex Builder uses to launch and debug your apps). Platform specific icons are created from the PNG files referenced in your application descriptor file at install time which means they aren't available during development. It would obviously be too costly to generate those icons every time you wanted to launch or debug your code.
This typically isn't an issue because you usually don't need to see your application icons during development. However, there are times when you do. For instance, if your application uses a dynamic dock icon, it's nice to be able to see the "before" icon before seeing the "after" version. I've also found that it's nice to be able to try an icon out for a while during the development process to see how you like it over time which means it should appear every time you debug or launch your app.
Fortunately, I've found an easy way to make this work. Here's what you do:
- Make a copy of your application icon and name it something different. One version should be referenced by your application descriptor file, and the other will be compiled into your application. (You don't technically have to make a copy of the icon, but when generating a release build of your application, Flex Builder doesn't copy over embedded resources which means your application icon will be missing. Trust me when I tell you that it's easier to create a copy and avoid this whole issue.)
- Compile the copy of your application icon into your application using code like this:
[Embed(source="assets/application.png")] public var appIconClass:Class; - In your application's initialization code, create a Bitmap instance of your icon like this:
var appIcon:Bitmap = new appIconClass(); - Set your icon like this:
InteractiveIcon(NativeApplication.nativeApplication.icon).bitmaps = [appIcon];
This code is a little oversimplified because it doesn't take platform differences into account. A more complete implementation might do something like this:
- Check to see what kinds of icons the client supports. You can do this with the
NativeApplication.supportsDockIconandNativeApplication.supportsSystemTrayIconAPIs. - Scale the Bitmap to the appropriate dimensions for the platform.
- Set the icon(s) using the NativeApplication's icon property.
Since I usually use the Cairngorm framework, I like to create an UpdateIconsCommand which takes care of creating and setting dynamic icons for me. I also like using the as3notificationlib project to help encapsulate some of the platform differences in setting icons.
For a real world example of setting dynamic icons, see my Exchange calendaring application called Lineup (currently being updated to work with Exchange 2007). It sets icons at runtime and even dynamically generates custom icons, all in a way that works well across platforms.
Posted by cantrell at 9:50 AM. Link | Comments (5) | References
January 23, 2008
Update on my AIR Applications and Libraries
The most important part of my job is writing AIR applications, and I've written quite a few. In addition to applications, my team and I have written a great deal of reusable ActionScript library code (Amazon S3 APIs, Exchange APIs, etc.). Everything I've written is completely free and open source.
The problem is that I haven't done a very good job in keeping these applications and libraries synchronized with the the publicly available version of AIR. It's not that I'm lagging behind, though. In fact, I have the opposite problem: most of this code has been updated to work with the the latest internal versions of AIR so that I can keep banging on, testing, and exercising the latest and greatest runtime.
I just wanted to let everyone know that I will be releasing all my apps the day we release AIR 1.0. If you can't wait that long, the source code is all available here in Google Code. In theory, all of the libraries should work with the public AIR beta (beta 3), and the applications should all work, as well, as long as the application descriptor's namespace is set to 1.0.M6 rather than 1.0. Anything that doesn't work, or any bugs that you find, will be fixed in the final 1.0 release.
Below is a list of almost everything I've written that's worth releasing (I've written dozens of test applications that will never see the light of day).
Applications:
- Apprise: A simple but powerful RSS aggregator.
- Lineup: A application for viewing your Exchange calendar, and receiving meeting notifications.
- PixelPerfect: Measure things on your screen in pixels.
- S3E: Easily manage your Amazon S3 objects and buckets.
- SPF (Screen Protection Factor): A multi-monitor screen saver.
- ScreenBoard: Draw on your screen during presentations.
- HTMLScout: A tool for inspecting the DOM of an HTML page.
- Timeslide: A simple but useful countdown timer with good visual feedback.
Libraries:
- as3corelib: The corelib project is an ActionScript 3 Library that contains a number of classes and utilities for working with ActionScript 3.
- as3fedexlib: A wrapper on top of some of the FedEx XML APIs.
- as3syndicationlib: Use the syndication library to parse Atom and all versions of RSS easily. This library hides the differences between the formats so you can parse any type of feed without having to know what kind of feed it is.
- as3awss3lib: This is an AS3 library for accessing Amazon's S3 service.
- as3notificationlib: This project makes it easy to add cross-platform notifications to your AIR application. It handles "native system notifications" like the dock icon bouncing and the taskbar icon flashing, and it allows you to easily create alert "pop-ups".
- as3exchangelib: This is an ActionScript 3 library for talking to Exchange servers. (Currently only supports retrieving meeting information.)
- as3preferenceslib: An AIR library for storing preferences. It worries about persistence and even encryption for you.
- as3nativealertlib: This project creates Flex-like alerts, but they are native windows so they can appear outside the bounds of your application.
The source code for all these applications and libraries is available here. You will need to use subversion to download the source.
Posted by cantrell at 9:45 AM. Link | Comments (14) | TrackBack | References
January 18, 2008
Converting Stage Coordinates to Screen Coordinates
In the Exchange calendaring application I'm working on (called Lineup), when the user double-clicks on an appointment, I open up an appointment detail window which shows you things like the location, full description, etc. Initially, I was just opening a utility window (a native window with smaller chrome), but after seeing the newest version of iCal, I was inspired to do something more creative. I still open a new window, but it's a customized transparent window which looks more like a dialog bubble extending from the exact point where the user clicked.
In order for the effect to work properly, I needed to place the window at very precise screen coordinates so that the window was clearly associated with the appointment that was clicked on. At first, I tried doing my own coordinate calculations using the stage x/y coordinates of the double click, and the coordinates of the application window. The problem was that I had no way to take native window chrome into account, so although I got it working on Mac, the window placement was off on Windows.
Fortunately, AIR has an API that does the work for you by taking the coordinates from a "local" mouse event (relative to the window stage) and converting them into screen or global coordinates. The function is NativeWindow.globalToScreen(), and it fixed my problem perfectly. Now, Lineup has iCal-like detail windows that appear right where they are supposed to on Mac, Windows, and eventually on Linux, as well.
Posted by cantrell at 10:12 AM. Link | Comments (1) | TrackBack | References
January 10, 2008
Managing Symbolic Links in AIR
I recently wrote an AIR application called SPF, or Screen Protection Factor. It's a screen saver that will fill however many monitors you have attached to your computer with random pictures from a specified directory. The specified directory is recursively traversed so SPF will find all supported file types (jpg, png, and gif), no matter how deeply nested they are.
While writing SPF, I realized that a carelessly placed symbolic link could easily put my directory traversal code into an infinite loop. Symbolic links (as they are known on Unix systems, including OS X) and junction points (as they are known on Windows) are pointers to files or directories which are mostly indistinguishable from whatever they point to. I use them frequently when doing web development when I don't want to keep my source code in my web root. Instead, I create a symbolic link in my web root which points to my source tree, and assuming my web server is configured correctly, it's just like having the same code in two places. Put a symbolic link in the wrong place, however, and you've created a circular reference on the file system. Normally this isn't a problem, until you have a piece of code that is recursively traversing that portion of your file system.
I tried a few stopgap measures to guard against circular references in my SPF code, but there really was no way to gracefully handle the problem without specific APIs. Fortunately, those APIs now exist.
To handle symbolic links, you need two File APIs: the isSymbolicLink property, and the canonicalize function.
isSymbolicLink simply returns a boolean which tells you if the File instance is a symbolic link or a junction point. Simple enough. But what does the symbolic link actually point to? That's where canonicalize comes in. Call canonicalize, and suddenly the file reference now points to the actual file referenced by the link. Call nativePath, and you get the path of the original file, not the link.
So how does this solve my SPF problem? While traversing the file system, I keep a map of file paths, and before adding a new image to the queue, I check to see if it is already in the map. Before I was able to resolve symbolic links, a circular reference would have me adding the same files infinitely because the path continued to grow. Now, I simply check to see if the file reference is a symbolic link, and if it is, I call canonicalize before adding it to the map. Problem solved.
These two APIs don't work on Mac aliases or Windows shortcuts, however they don't have to. AIR will not follow aliases or shortcuts like it will symbolic links, so they cannot get you into the same kind of trouble.
Posted by cantrell at 9:48 AM. Link | Comments (2) | TrackBack | References
January 3, 2008
Manual Data Binding in Flex
I'm currently working on an Exchange calendaring client for AIR (more details to come), and I decided early on to use the Cairngorm Flex framework. I'd worked on Cairngorm projects in the past, but I hadn't ever used Cairngorm in one of my own projects from start to finish. I decided it was time to put it to use, and to make sure it was 100% AIR friendly.
One of the first things you realize about Cairngorm is that it relies very heavily on data binding. Data binding is one of my favorite features of Flex, so I was very happy with how my application was coming together. But then I ran into a snag. I found myself needing to execute a block of code in response to a property change rather than just display the new property value, or update a component's data provider. Fortunately, Flex has anticipated this issue, and allows you to set up binding manually in a very flexible (naturally) way.
So here's the scenario:
I have a ControlBar component which has a busy, and a notBusy state. In the busy state, I show a progress bar, and in the notBusy state, the progress bar goes away, and in its place, I show the date and time of the last update. My ModelLocator has a busy property which makes it easy for me to to maintain a global "busy" state for my entire app. Whenever that properly changes, I want to change the state of the ControlBar component, as well as execute a small block of UI-related code.
The key to making this work is the mx.binding.utils.ChangeWatcher class. In the creationComplete handler of my component, I have the following code:
ChangeWatcher.watch(ModelLocator.getInstance(), "busy", onBusyChange);
Believe it or not, that's it. In my onBusyChange function, I change the state of my component, and do a couple of other small UI-related things. Now whenever the busy property of the ModelLocator changes, my app just does the right thing.
I found that the ChangeWatcher was really the key to making Cairngorm flexible enough to build any type of application. It allowed my team to throw together a pretty nice little Exchange Calendar viewer and notifier which I think will be a big hit with those who use Exchange in a corporate environment, but who aren't big fans of Outlook. I will release the application and the code with the next public release of AIR.
Posted by cantrell at 9:39 AM. Link | Comments (8) | References
December 4, 2007
Mapping File Extensions to MIME Types
When writing Salsa (an Amazon S3 client), I ran into a situation where I needed to map MIME types to file extensions and vice versa. So I wrote a simple but very handy utility to do it for me. The ActionScript code is here if you just want to copy it, or it's available in as3corelib if you want grab the entire library (with tons of other useful APIs).
Posted by cantrell at 8:57 AM. Link | Comments (1) | TrackBack | References
December 3, 2007
Multi-monitor Support in AIR
I've seen several people ask about multi-monitor support in AIR. The answer is: it's there, and it's very good.
Take a look at the flash.display.Screen class (AIR only -- not available in the Flash Player). It contains the following properties:
boundscolorDepthmainScreen(for getting a Screen reference to the main screen when there are multiple monitors)screens(an array of Screen objects for all attached monitors)visibleBounds(returns a Rectangle that excludes unusable portions of the screen like the taskbar, menu bar, and the dock)
The Screen class also contains a very cool function called getScreensForRectangle that returns an array of screens that intersect the specified Rectangle.
We've also added a ScreenMouseEvent that is dispatched by SystemTrayIcon and gives you the coordinates of a click relative to the main screen as opposed to an application window.
For a relatively simple example of the Screen APIs in action, check out SPF on the Adobe Labs Sample Application page.
Posted by cantrell at 10:35 AM. Link | Comments (5) | TrackBack | References
October 19, 2007
AIR is Desktop 2.0
As I was putting together an Introduction to AIR presentation yesterday, something struck me about AIR that I hadn't fully realized before: AIR is desktop 2.0.
To me, web 2.0 means a new wave of innovation and attention to things like user experience. It's not just the technology (Ajax, Flex, etc.) or things like user-generated content or social networks. Rather, it's what all these things represent: a commitment to more effective, efficient, and engaging user experiences.
But why should such an important evolutionary step in application development be confined to the web? What about the desktop? In many ways, desktop applications have stagnated worse than pre web 2.0 applications. In general, they tend to be bloated, and it doesn't seem to matter how fast my processor is or how much memory my computer has -- most desktop applications seem to find a way to use just about all available resources. They have too many features that not enough people use, and since updates are such a big deal, bug fixes are few and far between. Worst of all, convention seems to have replaced innovation. Just like on the web, we have certain expectations of how desktop applications should work, and we tend to forget to demand more.
That's not to say there hasn't been any innovation on the desktop. OS X was a huge step forward, and although Windows Vista doesn't represent any type of fundamental change in the desktop model, it's certainly the nicest looking OS Microsoft has ever released. I finally installed Office 2007 the other day, and I was impressed with Microsoft's obvious desire to break away from 17 years of user interface history in order to provide Office users with a more streamlined and intuitive experience.
So I believe the desire is there to create better desktop experiences, but not necessarily the tools. That's where I think AIR is really going to shine. In fact, I believe that AIR is going to be the catalyst for desktop 2.0.
The reason I'm coming to this realization now is that I've had enough time to really see what AIR can do. Of course, there are the most salient examples like the new eBay Desktop and AMP, but there are a lot of other smaller, more subtle clues that foreshadow the types of experiences we have in store for us. The other day, I wrote an application called AIRPressure just to see how hard it would be to generated dynamic dock and system tray icons using Flash drawing APIs. The little timer that appears in the dock or system tray is being drawn completely dynamically, and is updated once per second. The application took about a day to write (mostly because I had to familiarize myself with the Flash drawing APIs and enough trigonometry to to draw a dynamic pie chart) and it works perfectly on both Mac and Windows. The app itself isn't anything revolutionary, but the ease with which I was able to do something that has traditionally been difficult, and to do it in a cross-platform way, really starts to illuminate the possibilities.
My team has been working on an open source AIR notification framework and we decided the other day to see how far we could push it. Among many other things, the notification framework allows you show notification windows like "toasts" on Windows or the Google Notifier on Mac. Just for the fun of it, we decided to see if we could extend the AbstractNotification class and create a custom notification with a video in it. It took Prabs (an engineer on my team) about half a day to get it working beautifully, and most of his time was spent familiarizing himself with the Flash video APIs which he had never used before. (There's a sample in the Google Code project -- you just need an FLV on your machine to point the sample application to.)
And there are examples like the Allurent Desktop Connection, AOL's Top 100 Video application, all the amazing apps built for the Adobe AIR Developer Derby, and one of my personal favorites, Snippage.
In developing AIR, it was easy to get caught up in specific AIR APIs, and to think of AIR's capabilities in terms of those APIs. However, I've recently realized that those APIs don't even come close to defining what AIR is and what it can do. AIR's true capabilities lie somewhere in the intersection of all the breathtaking and innovative things millions of designers and developers can do with Flash, Flex, and Ajax, the power of desktop APIs, and the functionality unique to AIR like the embedded database. I think AIR is going to completely redefine our expectations of both developing for and interacting with desktop applications, and I think it's going to far exceed even our own expectations.
Posted by cantrell at 9:18 AM. Link | Comments (6) | References
October 10, 2007
Generating Dynamic Dock and System Tray Icons in AIR
Someone asked me the other day if AIR applications can generate dynamic dock and system tray icons. The use case is something like Mail.app on Mac which always shows you the number of unread messages as part of the dock icon.
I'm happy to report that this is perfectly possible in AIR, and I created a sample application called AIRPressure to demonstrate. AIRPressure is a countdown timer which shows a dynamically generated timer icon in your dock or system tray to let you know how much time is left. It also has some other cool features:
- It will optionally show a notification window when the timer is complete.
- It will optionally open a URL in your browser when the timer is complete.
- The dock icon bounces or the task bar icon flashes when the timer is complete.
- All your settings are saved between uses.
The code for AIRPressure is probably more interesting than the application itself. For notifications (notification windows, bouncing the dock icon, flashing the task bar entry), and for changing the dock and system tray icons in a cross-platform manner, I use the as3notificationlib project that my team has been working on which makes it extremely simple. And for persisting preferences, I use the new as3preferencelib that my team also wrote which handles all file IO, encryption, and serialization automatically. AIRPressure is a pretty useful and comprehensive cross-platform application, and the entire app is only about 300 lines of code (thanks to all these libraries doing a lot of the heavy lifting).
AIRPressure works with the publicly available AIR Beta 2. If you want to check it out, click on one of the links below, or click on the install badge at the bottom of the post.
- Download AIRPressure.air (view source enabled).
- Download the source code for AIRPressure (requires as3notificationlib and as3preferencelib).
Posted by cantrell at 1:11 PM. Link | Comments (15) | References
October 4, 2007
Make Text Fade in Flash Without Embedding Fonts
My team is working on a notification framework for AIR. It provides a cross platform API for managing notification windows, changing the dock or system tray icon, attaching menus to the dock or system tray icon, and bouncing the dock or flashing the task bar icon. It's open source and free, and available now on Google Code if you're interested in an early preview.
One of the challenges we ran into was getting the notification text to fade along with the notifications. My first reaction was that we were going to have to embed a font which is how I have gotten text to fade in Flex applications in the past. However, I didn't want to have to include a font in an open source project for both technical and legal reasons. Fortunately, one of the engineers on the AIR team (Stan Switzer) pointed me to one of the first AIR applications ever written called ApolloClock in which he had partially transparent dynamic text.
It turns out the answer is to apply a filter to the text. Applying a filter to a TextField results in the runtime generating a bitmap out of the device font which means you can change its alpha, rotation, etc. This was a huge help, and resulted in a very cool and smooth fade effect. It also allows the notification library to remain very small since it's written in 100% ActionScript (no Flex), and now does not contain an embedded font. (It might also be possible to use cacheAsBitmap to make this work, but I was happy enough with the filter approach that I didn't investigate further.)
I'll post more about the notification framework as we add features. I'll also post more about the application we're working on that we wrote the notification framework for. It, too, will be be free and open source, and will make Mac users who have to use Exchange calendaring very happy.
Posted by cantrell at 11:35 AM. Link | Comments (15) | References
August 21, 2007
My Embedded Database Presentation From the Bus Tour
I just finished my portion of the bus tour. I went from Atlanta through DC, presenting a total of about 7 or 8 times (I lost track). In addition to several demos, I presented a talk called "Introduction to the AIR Embedded Database".
It was a great trip, and and I really enjoyed hanging out with all the AIR developers here on the east coast. Every event was well attended and full of energy. The audience was engaged, enthusiastic, and had some very good questions and comments. In general, I would say the onAIR Bus Tour is by far the best developer event I've ever been a part of, and I'm very glad I was able to contribute.
We're going to post videos of all the presentations shortly, but I wanted to go ahead and get my slides and demo apps posted. A Flash version of my slides are available here, and a zip file of all my sample code is available here.
Keep in mind that my samples were built using a "daily build" rather than the public AIR beta. SQLExample2 should work in the public beta, but SQLExample and SchemaTest won't work until the next public drop (around the MAX timeframe). I've decided to include all the code anyway, however, to give you a sense of what's coming.
I'll post the URL to the video of my presentation when it's available.
Posted by cantrell at 10:36 AM. Link | Comments (5) | References
August 7, 2007
on AIR Bus Tour Picks Up Again Next Week
The second leg of the on AIR bus tour starts next week in Atlanta, and this time, I'll be there (I wasn't able to make the first leg). We're going to hit Atlanta, St. Luis, Cincinnati, Pittsburgh, Washington DC, Baltimore, Philadelphia, and Boston. I live outside of Washington DC now, so I'm going to head home after the DC event, but I'll be there for most of it. I'm going to be giving a talk called "Introduction to the Embedded Database API".
If you live or around any of these areas, come on out. You can learn everything you ever wanted to know about AIR, and it's entirely free. I can pretty much guarantee that a good time will be had by all, so go sign up!
Posted by cantrell at 9:38 AM. Link | Comments (4) | References
August 3, 2007
Milti-window Programming in AIR
Multi-window programming is something we've never had to worry about in Flash or Flex until now. AIR has a NativeWindow object which lets you write true multi-windowed desktop applications. Of course, along with additional power comes additional responsibility.
I just finished writing a screen saver application in AIR which I call SPF (Screen Protection Factor). It works basically like the picture viewer screen saver on OS X with the following features:
- It iterates through all the jpg, gif, and png files in a specified directory (and all sub directories).
- You can pick the transition interval (the amount of time each image is shown).
- You can set the idle interval (the amount of time that you have to be idle before the screen saver kicks in).
- It works with any number of monitors simultaneously.
I wrote a ScreenSaver class which extends NativeWindow, and when the user has been idle for the specified amount of time, I create a new ScreenSaver for each available monitor and show it at full screen. The ScreenSaver class has a timer which picks images at random and displays them at the full resolution of the monitor. When input is detected again (when the user is no longer idle), the code iterates through the collection of ScreenSaver instances and closes each one.
Pretty straightforward. Except for one thing.
Thanks to some debug trace statements, I discovered that after all the ScreenSaver instances were closed, their timers were still running and trying to display images. I figured one of two things was happening:
- I found a bug.
- The timers had references to the window, which were preventing them from being garbage collected.
Turns out I was wrong on both counts.
When you close a window and null out your references to it, you are making it eligible for GC, but that doesn't mean it's immediately GCed. It might be GC right away, or it might be around for another hour. It just so happens that we're currently seeing unusually long intervals between collections on Mac right now (so to my credit, I did find partial bug, I guess), but regardless, AIR makes no guarantees of when your references are going to get cleaned up. That means you are still responsible for code that runs in those windows until they are finally reclaimed.
This should only be an issue for things like timers, or for asynchronous processes which might have been kicked off before the window was closed. If you working with any such code, be sure to listen for the closing event, and take care of any loose ends. Stop timers, and cancel all asynchronous processes that shouldn't have a chance to return. If you're extending NativeWindow, it's as easy as adding an event listener to yourself, and adding a few lines of housekeeping code.
I will release SPF with the next public beta along with a few other fun apps I've been tinkering with.
Posted by cantrell at 11:57 AM. Link | Comments (2) | References
June 12, 2007
Apollo (now AIR) Sample Applications
By now you have probably heard that:
- Apollo is now officially AIR (Adobe Integrated Runtime), and
- The AIR beta went live this week, and is available for download.
I did a lot more product definition for this release, and much less coding, but I did manage to write one interesting new application:
Salsa
Salsa is an Amazon S3 client which lets you easily manage your buckets and files in the S3 cloud. You can create and delete buckets as well as upload and download, drag and drop, and copy and past between your computer and Amazon S3. You can even manage multiple files at once. Salsa uses the open-source as3awss3lib ActionScript 3 S3 library that I wrote, so if you don't like the way Salsa works, you can write your own client.
Salsa, along with the other Adobe AIR sample applications (and their source code), is available here.
In addition to Salsa, I managed to update some of my old sample apps from the alpha:
MapCache
MapSnap is now MapCache. It lets you look up addresses using Yahoo! Maps, and save the maps for offline use. I used to call it MapSnap because all it let you do is create a snapshot of a map and save it, but now you can save the map, copy it to your clipboard, or drag and drop the map to your desktop. It's a simple but handy little app, and demonstrates the following:
- The AIR HTMLControl.
- Script bridging (calling JavaScript functions from ActionScript).
- Native file browsers.
- Drag and drop.
- Copy and paste from the clipboard.
Scout
I added forward and back buttons in Scout using the HTMLControl's new history management functionality. Otherwise, it's the same.
PixelPerfect
PixelPerfect is an example of a pure ActionScript 3 project (no Flex, no HTML, no JavaScript). I think it's actually the most useful AIR application that I've written so far, and I find myself using it on a regular bases. It pops up transparent rulers on your screen which you can use to measure things in pixels. For this release, I added multi-window support (you can open multiple rulers at once), and now the rules are always on top of other windows so they don't get lost. (I don't have a help dialog yet, but you can also change the transparency using your mouse wheel, move rulers with your arrow keys, and resize them with shift+arrow keys.)
All the beta sample apps, along with their source code, are available here on Adobe Labs.
Posted by cantrell at 6:48 AM. Link | Comments (20) | References
May 30, 2007
ActionScript Library for Amazon S3
I've been working on an Amazon S3 client in Apollo, and I finally got around to extracting the S3 library and making it its own project. I put it up on Google Code under the name as3awss3lib.
The library will only work in Apollo because there are too many restrictions in the browser player for it to work. Since I knew it wouldn't work in the browser anyway, I went ahead and used some Apollo APIs. It also has dependencies on As3Crypto, as3corelib, and Flex (you can use the free Flex SDK).
I haven't implemented everything S3 supports yet. Specifically, I haven't implemented access control (everything is private) and the bucket listing pagination functionality. But all the hard protocol work is there so the rest is easy to add. Right now, you can:
- Get a list of buckets.
- Create new buckets.
- Delete buckets.
- Upload objects.
- Download objects.
- Delete objects.
- Get a temporary public URL to an object.
I'll release the application I'm building on top of the library as soon as we update the public release of Apollo. It allows you to drag and drop and copy and paste files to and from S3.
Posted by cantrell at 8:46 AM. Link | Comments (27) | References
April 23, 2007
Important Information on Maptacular
Maptacular is an Apollo application I wrote that lets you map addresses on your desktop (in vCard format) using Google Maps. You can download the public alpha binary from the Apollo application page on the Adobe Labs wiki, and if you're interested in the source code, read the entry previous to this one.
Some important information on Maptacular (which I should have mentioned when I first released the app):
- Once the application is running, move your mouse over to the left side of the window. A drawer will open with contacts. You can click on the contacts for more information, and you can also expand the contacts into address cards.
- To map an address, drag it onto the map.
- To get driving directions between two points, "pin" the drawer open by clicking on the circle in the upper right-hand corner of the drawer, then drag your starting point onto the map. Once it has mapped, drag your destination address onto the map. You should get driving directions between the two points.
- Maptacular creates a directory in your documents directory (either "Documents" on Mac, or "My Documents" on Windows). Any vCard you put in that directory will get added to the list. Right now, you have to restart Maptacular for it to pick up new vCards. (I need to add some polling code one of these days.)
- When Maptacular runs, it puts a sample vCard in your Maptacular directory. I did this to make it easier to demo. If you don't want this behavior, you'll have to change the source. Just look in the init function -- it's very easy to disable. Someday, I'll take this out.
- For a demonstration of how Maptacular works, you can check out this Google video.
- All the addresses and phone numbers in the sample vCard are fake. I've gotten tons of emails and IMs from people asking me if I meant to reveal all this personal information about my coworkers. All of the addresses point to offices or restaurants around the city. They look real because they had to actually be mapable. Oh, and most of the pictures are real, except for mine, who is my favorite character from Homestar Runner.
Posted by cantrell at 11:11 AM. Link | Comments (4) | References
April 20, 2007
Apollo Sample Application Source Code
I finally got around to releasing the source code for my sample Apollo applications. Sorry it took so long. The applications and the source code can be downloaded here.
A couple of important notes:
- These apps are intended to work only the public alpha of Apollo, and they will not work with any earlier or later version (I will update them accordingly, though).
- Lookup requires corelib and the dictionary protocol library I wrote in order to compile. I included SWCs in the lib directory, so just link them in to your project, and it should compile just fine.
- I wasn't able to release the source code for Maptacular because it uses an embedded font that we don't have the rights to distribute. If you're really interested in how Maptacular works, you can download the source code here, but it doesn't have the fonts in it, so it won't compile. If you know what you're doing, you can fix it either by removing the dependency on the embedded font (which will screw up some of the effects), or by embedding another font (which is the easiest solution). Just drop the .ttf file in the assets directory, and you should be good to go. A quick glance at the top of Maptacular.mxml should make things clear.
- The Maptacular application has the vCard parsing code embedded in it which I have since extracted, improved, and moved into its own class in corelib.
- These are sample and demo applications which haven't been thoroughly tested, and probably aren't the most feature-rich, intuitive applications you have ever used. Most of them were designed to exercise and validate Apollo APIs rather than to solve real-world problems. That said, I think they're decent and fun little apps. I'm especially fond of PixelPerfect for some reason.
- Speaking of PixelPerfect, you will have to read through the source code to see all that it can do. Try right-clicking on a ruler, hitting shift+n, using the arrow keys to move the ruler, and using shift+arrows to scale the ruler.
Posted by cantrell at 11:27 AM. Link | Comments (5) | References
March 22, 2007
Constraining the Dimensions of an Apollo Application Window
I saw this issue come up on the Apollo forums the other day. If you want to constrain the dimensions of an Apollo application window, use the maxSize and the minSize properties of NativeWindow. I usually do it in an initialization function after setting the bounds of my window, like this:
var win:NativeWindow = systemManager.stage.window;
win.width = 800;
win.height = 600;
win.maxSize = new Point(800, 600);
win.minSize = new Point(800, 600);
win.visible = true;
You can also use the bounds property of NativeWindow to set its size and location at the same time.
Posted by cantrell at 2:13 PM. Link | Comments (30) | References
March 21, 2007
Using HTML and Script Bridging in Apollo
The video of the presentation I did at Apollo Camp the other day on using HTML and Script Bridging in Apollo is available on video.onflex.org. Props to Mike Chambers for enduring the extremely long encoding process.
I will be releasing the source code for all the applications I showed in this presentation shortly. I just need to find the time to clean up the code a bit, and to fix a couple of bugs.
Posted by cantrell at 10:40 AM. Link | Comments (2) | References
March 19, 2007
MapSnap: An Apollo Example Application
MapSnap was one of the first Apollo applications I wrote which incorporates HTML. It lets you look up addresses on a Yahoo map, and save the maps as a PNGs to your desktop. It's a very simple application, but I think it makes for an excellent example.
MapSnap demonstrates the following:
- The general structure of an Apollo application.
- The use of system chrome.
- Stopping a window from resizing.
- Loading local HTML content.
- Script bridging (calling into JavaScript from ActionScript).
- Encoding a PNG.
- Including an icon in your Apollo application.
- Using a native file browser (the technique I use in MapSnap is a hack, but it will get you through until we officially add this functionality to Apollo).
If you just want to run the app, all you need is the Apollo runtime, and the MapSnap AIR file. If you want to see the source code, here is the Flex Builder project. There's a lib directory in the project with corelib.swc in it which you need to link in to your project in order to get the PNG encoding support.
Posted by cantrell at 1:44 PM. Link | Comments (12) | References
March 18, 2007
Apollo alpha is live
The Apollo Alpha is now available on Labs, along with a lot of good resources on the Labs wiki.
Yes, I know my blog has been silent recently, but that's primarily because I've been working with technology that hadn't been released yet. Now that the Apollo Alpha is live, I can start posting all kinds of tips and tricks, sample applications, and code snippets.
Posted by cantrell at 11:23 PM. Link | Comments (4) | References
December 19, 2006
Apollo Application Demos
Mike Chambers interviewed me the other day about what I do on the Apollo team, and asked me to show a couple apps I've been working on. You can check it out the Google Video, or download the mp4.
Posted by cantrell at 1:01 PM. Link | Comments (27) | References