Archive for the 'AgileAgenda' Category

A Flash Catalyst / Builder workflow method

Update: Check out the new post where I describe how to compile to a swc.

I’ve been playing around with the Flash Catalyst and Builder betas today and one thing that scares me a little is the built-in designer/developer workflow that’s implied.  From what I can gather, a designer uses a design tool, imports that into Catalyst, and then hands of a .FXP file that a developer then imports into Builder to work on.  Then the developer jumps into the files generated by Catalyst, and modifies them.

For smallish projects, that’s a slam-dunk.  If you don’t work on large projects, stop reading here and just stick with that.

But there’s a number of reasons I really don’t like this intended workflow for larger projects.

First, it’s not scaleable.  One catalyst file -> one Flash Builder project.  It’s awefully hard for a team of 5 designers to work on a single catalyst file.

It implies some exclusivity.  If the designer hands off the .FXP file, they really shouldn’t continue working on it because the developer will start modifying it.  It’s kind of like having a Word document that you pass back and forth between the designer and the developer.  If they both want to work on it at the same exact time, you’ll get race conditions.

Second, I don’t trust anybody to get a perfect Generated Code <-> User Edited Code tool to work perfectly all the time.  If Catalyst generates some code, I edit that, and then we bring it back into Catalyst, I just know that will break at some point.  (Sorry Adobe guys, I know you’ll do a rocking job with it, and I know it will almost always work, but it’s just too hard a problem)

So here’s a solution I’ve been playing with:

Step 1: Create your design comp

Here’s a Photoshop file I created with a pretty simple login form.  Make sure to name your layers so they’re easy to find later.

Step 2: Import it into Flash Catalyst just like you’re supposed to.  Edit it to your heart’s content.

There’s a bunch of tutorials out there (great one from Lee Brimlow here) that show how to actually use Catalyst.  But one difference from all those tutorials.  We won’t be using the Main root level item.  So don’t go crazy adding states to your base stage.  But DO go crazy creating sub-components and adding states and behaviors to those.

Here’s a screenshot of my Catalyst project.  This is showing off a LoginForm component that I created.  Notice it has a few states with transitions set up between those states.

Step 3: Save it as a .FXP

File->Save from Flash Catalyst.

For my example, I used FCTest.fxp as the name.

Step 4: Create an empty Flash Builder project (not importing anything here)

Just create a plain old Flash Builder project with a Flex based application in it.  (Make sure you’re using a Flex 4 SDK!)

Step 5: Take your .FXP from above, and unzip it somewhere

Here’s the sneaky part.  That .fxp file is really just a zip file that contains a Flash Builder project.  You can unzip it with any standard zip tool.  In OSX I just open a terminal and did a:

unzip FCTest.fxp

It creates a directory structure that looks something like this:

Notice the two folders with arrows pointing to them, they’re important in the next step.

Step 6: Take the components and assets folders from that unzipping and put them in a brand new folder.

We can take those two folders and use them in our Flash Builder project to get access to all of our custom components that we made in Flash Catalyst.  I’m planning ahead a little bit so I created a “CatalystAssets” folder, and a “FCTest.fxp” folder inside that, and placed them there.  This will allow me to have assets from many different catalyst files in the future someday.

Step 7: Link to that folder from your Flash Builder project

Flash Builder can link to source directories outside of the project.  To do that go to Project->Properties->Flex Build Path.  Click the “Add Folder…” button and add the FCTest.fxp folder (the folder we created, not the file Catalyst made).

In Flash Builder’s Package Explorer you’ll see something like this after you do that:

The developer should NEVER EDIT anything in the FCTest folder.  Consider that all auto-generated stuff that will wipe out anything you do in there.

The developer can and should work in the normal Flash Builder src folder, likely importing classes and assets from the FCTest folder and using them.

Step 8: Use the Flash Catalyst based assets!

For simple components that you don’t need to add any functionality to, you can just use them in your MXML.  For example, I created a component called Background in my Catalyst file.  To use it in the Flex application you just do something like this:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3.  xmlns:s="library://ns.adobe.com/flex/spark"
  4.  xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
  5.  xmlns:components="components.*">
  6.  
  7.  <components:Background verticalCenter="0" horizontalCenter="0" />
  8.  
  9. </s:Application>

Notice the components namespace with the Background component name.

Adding non-interactive components isn’t all that interesting.  So what happens if you want to add functionality to components created in catalyst?  There’s two options here, either use the assets from the .FXP through composition or inheritance.  Here are two examples that show how to do them both:

Extending a Catalyst component through inheritance:

  1. package com.roguedevelopment.fctest
  2. {
  3.  
  4.   import components.LoginForm;
  5.   import flash.events.MouseEvent;
  6.   import flash.utils.setTimeout;
  7.   import mx.controls.Alert;
  8.   import mx.events.FlexEvent;
  9.  
  10.   public class InheritenceExample extends LoginForm
  11.   {
  12.     public function InheritenceExample()
  13.     {
  14.       super();
  15.       addEventListener(FlexEvent.CREATION_COMPLETE, creationComplete );
  16.     }
  17.     protected function creationComplete(event:FlexEvent):void
  18.     {
  19.       setTimeout( function():void{ currentState = "Normal"; }, 300 );
  20.       textinput2.displayAsPassword = true;
  21.       button1.addEventListener(MouseEvent.CLICK, onLoginButtonClick );
  22.       textinput1.setFocus();
  23.     }
  24.  
  25.     protected function onLoginButtonClick(event:MouseEvent):void
  26.     {
  27.       var correct:Boolean = ( textinput1.text == "marc" ) &amp;&amp;
  28.                       ( textinput2.text = "1234" );
  29.  
  30.       if( correct )
  31.       {
  32.         currentState = "Working";
  33.         setTimeout( success , 1500 );
  34.       }
  35.       else
  36.       {
  37.         currentState = "Error";
  38.         setTimeout( function():void{ currentState = "Normal"; }, 1500 );
  39.       }
  40.     }
  41.  
  42.     protected function success() : void
  43.     {
  44.       Alert.show("Correct log in!");
  45.       currentState = "Normal";
  46.     }
  47. }
  48. }

Or, if you want to use composition instead of inheritance you could do something like this:

  1. package com.roguedevelopment.fctest
  2. {
  3.   import components.LoginForm;
  4.   import flash.events.MouseEvent;
  5.   import flash.utils.setTimeout;
  6.   import mx.controls.Alert;
  7.   import spark.components.Group;
  8.  
  9.   public class CompositionExample extends Group
  10.   {
  11.     protected var loginForm:LoginForm;
  12.  
  13.     public function CompositionExample()
  14.     {
  15.       super();
  16.     }
  17.  
  18.     override protected function createChildren() : void
  19.     {
  20.       loginForm = new LoginForm();
  21.       addElement(loginForm);
  22.       width = 527;
  23.       height = 325;
  24.       setTimeout( function():void{ loginForm.currentState = "Normal"; }, 300 );
  25.       loginForm.textinput2.displayAsPassword = true;
  26.       loginForm.button1.addEventListener(MouseEvent.CLICK, onLoginButtonClick );
  27.       loginForm.textinput1.setFocus();
  28.     }
  29.  
  30.     protected function onLoginButtonClick(event:MouseEvent):void
  31.     {
  32.       var correct:Boolean = ( loginForm.textinput1.text == "marc" ) &amp;&amp;
  33.                  ( loginForm.textinput2.text = "1234" );
  34.  
  35.       if( correct )
  36.       {
  37.         loginForm.currentState = "Working";
  38.         setTimeout( success , 1500 );
  39.       }
  40.       else
  41.       {
  42.         loginForm.currentState = "Error";
  43.         setTimeout( function():void{ loginForm.currentState = "Normal"; }, 1500 );
  44.       }
  45.     }
  46.  
  47.     protected function success() : void
  48.     {
  49.       Alert.show("Correct log in!");
  50.       loginForm.currentState = "Normal";
  51.     }
  52.   }
  53. }

Now that you have your components with some added functionality, you can use them in your main application like you would any other Flex based component. You can see a working demo, with view-source enabled here:

http://rogue-development.com/uploads/catalystWorkflow/FCTest.html

As you can tell, that seems like a LOT of extra work. But here’s the payoff:

  1. The designer is free to continue working in Flash Catalyst while the developer works in Flash builder.  Whenever he has changes, he just hands off a brand new .FXP, and the developer repeats steps 5 and 6 to replace some files and then refreshes the Flash Builder workspace.
  2. You can create multiple folders inside that “CatalystAssets” folder, and then use assets from multiple FlashCatalyst projects in a single Flash Builder project.
  3. You can add those Flash Catalyst assets to version control and easily distribute them to multiple developers. (Not to mention track changes!)

I did up a quick shell-script to unzip the .fxp file, make some directories, and copy the files to the appropriate place.  I can run this whenever the designer gives me a new .fxp. I think with a little work we could create a Eclipse “Builder” (that’s unrelated to the product name “Flash Builder”) that would completely automate this entire process.

  1. #!/bin/bash
  2.  
  3. rm -rf .tmp
  4. mkdir .tmp
  5. cd .tmp
  6.  
  7. unzip -o ../FCTest.fxp
  8.  
  9. cd ..
  10.  
  11. rm -rf CatalystAssets/FCTest.fxp/com/roguedevelopment/fctest
  12.  
  13. mkdir CatalystAssets/FCTest.fxp
  14. mkdir CatalystAssets/FCTest.fxp/assets
  15.  
  16. mv .tmp/src/components CatalystAssets/FCTest.fxp
  17. mv .tmp/src/assets/FCTest CatalystAssets/FCTest.fxp/assets

Some things I wish Flash Catalyst did:

  1. Let me select a package that components get created in. (maybe there’s a way to do that?)
  2. Make it easier to intelligently name the classes and property names that get generated
  3. Export a swc with everything in it so we don’t have to go through most of this.

Well anyways, I give Catalyst 2 thumbs up and even if we have to go through this process for a sane workflow it will save huge amounts of time in our shop.

P.S. I’m no Catalyst expert so maybe there IS a better workflow that I just haven’t seen yet.

AgileAgenda, Basecamp, and third party API’s

I haven’t blogged about AgileAgenda in a while on purpose since it seemed I was doing it far too often and was turning this blog into a big Ad instead of the resource for developers that I had meant it to be.  But I’ve done good with only a single post in the past five months, and I hope you’ll indulge me for a moment with this one.

We just released a new version, and it has a feature that a lot of customers have been asking for.  Far improved Basecamp integration! You can now connect to an SSL powered Basecamp install, and you can also now associate AgileAgenda resources with Basecamp contacts to automatically assign the Todo items. This is a huge jump in the integration between these two products and I’m really excited about it.  We also streamlined some of the synchronization so it all happens a bit faster.  You can read all about it here.

In the future, I’ll be exploring other services to integrate with.  At my day-job we’re beginning a QualityCenter rollout, so that may be on the list.  Along with that, I’ve always had plans to be able to export to Google Calendar.  Working with third party API’s really excites me since it’s a way to add a huge chunk of functionality (and customer value) very easily.  Any other ideas?

That really gets me thinking about interchangeable data on the web and how good it is for end users. With that in mind, I hope to be able to release the AgileAgenda integration API sometime this summer that would allow other applications to integrate with AgileAgenda.  That’s going to take some serverside rework, but that’ll need to happen eventually for other reasons. Before that, we’ll start publishing RSS feeds of schedules so external programs can at least start consuming data from AgileAgenda.

AgileAgenda on Linux

This was kind of neat.  I grabbed an Ubuntu VMWare image, installed the AIR Alpha, and then installed AgileAgenda on it.  It mostly worked, except for one crippling problem.  For some reason the hotkey for “Save” was set to “S” instead of “Ctrl-S”… so you couldn’t type any task name with an “S” in it.  I’ll have to look into that to see if it’s just an AIR Alpha bug, or if it’s a problem I need to fix with something I’m doing.  I can’t wait for the full Linux AIR to come out, it’ll be a great way for Linux users to get applications.

One of the best things about AIR is it’s application distribution model.  It’s just so darned easy for people to install apps.  One of the worst things about Linux is application distribution.  There’s just too many package formats and different ways to install.  I really hope AIR can bring a single, simple, installation method for AIR apps to all of the popular distributions.  Something that my wife could sit down at a Linux computer and do.

 

AgileAgenda - New Version

Posted a new version of AgileAgenda over the weekend.  Fixed a few minor bugs, redesigned the opening screens, and put in our new logo.  The entire initial user experience should be better now.   Here’s a quick glimpse of what it looks like now:

AIR Badge installer + swfobject + ExpressInstall

I’ve put together a page to install AgileAgenda using SWFObject with the ExpressInstall feature and the AIR Installation Badge.

This means people with a Flash Player less than 9.0.115 should be able to first upgrade their flash player, and then use the easy badge installation method for AIR + the application. I gave it a try on Firefox + Safari on OSX and IE + Firefox on WinXP, all of them with a 9.0.47 flash player and it all seemed to work well. The code also displays a message suggesting people install Flash player or install the AIR application manually if they don’t have any version of Flash.

I’ve put together a small archive of the necessary files to make this work. It contains files from the swfobject guys released under the MIT license, and you can consider anything I wrote to make this work also under that license (which allows you to pretty much use it any way you like).

Thanks go to the swfobject guys, they really made this a no-brainer on how to implement!
Hope this helps some people.

AgileAgenda - New Version

For those of you new here, AgileAgenda is a project scheduling application built on Adobe AIR.

There’s a new version of AgileAgenda now available on the website.

It’s been updated for AIR Beta 3, and includes a lot of bug fixes and minor enhancements, with a couple large feature improvements thrown in for good measure. You can read the list on the project blog.

The biggest change for me is file open/save dialogs work on OSX Leopard! Yay.

AgileAgenda - new version

There’s a new version of AgileAgenda available over at http://www.agileagenda.com/download/index.html. For those of you who are visiting the blog for the first time, it’s a project planning and scheduling package written in AIR. I’m starting to get close to a 1.0 release as I’m down to a single feature I want to get in there, and only a handful of known bugs.

I’ve spent a bunch of time working on the PDF export and have really been pushing alivePDF to it’s limits. Last week I sent a bunch of changes having to do with page size and a couple bug fixes to Thibault, everyone should check his project out, it rocks.

Here’s a quick example
of the type of stuff you can do with AlivePDF.

Developer interface to schedules

I’ve been working on a project scheduling application, and have a sneak peek at a new feature.

Wouldn’t it be great if every developer on your team could go in to the schedule and update the tasks they’re responsible for? They could mark them complete when they finish them, suggest new estimates, or make comments. Or even just to look at the latest set of tasks they have.

But doesn’t it suck to have to worry about developers mucking around in your precisely laid out schedule?

Now, there’s a developer interface that lets them subscribe to your schedule, and then update and comment on tasks with a simplified user interface.

Using the interface, they can subscribe to multiple schedules using a special key you can generate from the AgileAgenda main interface.

Then they can synchronize their view with the network version and take a local copy with them.


Right now, it’s read-only, but I’ll be adding all that 2-way stuff soon. And don’t worry, any changes made through the dev interface will have to be approved by the project manager in the main AgileAgenda interface.

I’ll have to slap on a slick interface at some point as well.

New tutorials

There’s a new AgileAgenda tutorial showing off the basic functionality of the software. See it at this url:

http://www.agileagenda.com/help/createproject.html

You can view the previous tutorial on the light table at:

http://www.agileagenda.com/help/lighttable.html

AgileAgenda Light Table

The latest feature to AgileAgenda is the “Light Table”, where you can drag your tasks around to modify their priority, who they’re assigned to, and the estimated duration. I think this feature has the possibility to be a huge help to some people.

Take a look at a short video showing it.