Archive for the 'flex' Category

Bicycle Dashboard Update

I made some mods to my bicycle reporting dashboard last night and just pushed them live.  Highlights include being able to break down the charts by bike, route, or day of week, legends to support showing multiple series, control over the chart baseline (zero or autodetect), and formatting of the "elapsed time" axis labels.

Now that that's working right, multiuser is next on the list, and I'll probably throw a "route link" field in there as well so you can link to a map of your route if you have one.

Fun with Flash on Linux

So I got home this evening and wanted to record my commute with my new logger app, and guess what, it crashes Firefox. Roughly one-in-four loads of the app are successful, other attempts cause a segfault as the player tries to load the SWF. It seems to work better in SeaMonkey, but still not perfect. I know Linux is the "we don't really care" platform for Adobe (and Macromedia before), but I'd almost prefer no player at all to a crashy one. Anyone have any hints?

Bicycle Goodies (i.e. Info Porn)

While on my seemingly endless airplane rides, I finished up a first draft of my bicycle reporting app, and made it available at the seemingly random address of http://www.barneyb.com/bicycle/.  ; )  Yes, it's Flex, and yes, I chose that platform of my own volition.  It's still a little rough around the edges, but it's all functional, and I used it to record this morning's ride.  Much better than using the command line MySQL client.  Of primary interest is the graphs of the stats.  I haven't gotten very far into them yet (was having some issues - surprise - getting the charts to work right for the more complex cases), but they're there, and the average speed one has a positive slope (yah me!).

There's a couple "weird" characteristics to the UI, but they have sound backing.  First, the entire UI is modal-free excepting the login form.  I didn't want to be stuck editing something and realize that I hadn't created some related entity and have to cancel out to create it.  I also wanted to be able to view the listings while adding/editing entities, so all the forms show up in tabs along with the listings so you can easily switch back and forth.

Second, the whole UI is publicly available.  I didn't want to build a separate admin area, so the editing UI doubles as the detail view UI.  The "Save" buttons are disabled unless you're logged in, and that's backed up on the server-side, of course.

Last, while not easily apparent, is the security of the authentication without using SSL.  Part of the AS3 Core Lib is MD5 hashing capabilities, so when the password is entered client-side, it gets hashed before sending to the server.  This provided a nice solution to password transmission that didn't require an outward facing self-signed SSL certificate (which isn't very friendly) but also doesn't compromise passwords.

Once I get stuff a little cleaner, I'll post source.  I'm also thinking of making it multi-user, but there are some weird issues (like handling public browsing) that would need to be dealt with.  Time will tell what becomes of it.

I also added contextual ride history to the single-entry pages on my blog.  I'd added it to the listing pages a while ago, but realized that a large percentage of my audience reads my blog via the XML feeds, so they never see the listing pages.  So rides within 24 hours of a given entry will now show up on the single-entry pages.

Another Flex Weirdness/Gotcha

Another little gotcha to watch out for with Flex.  If you have an ArrayCollection of Objects that are backing a DataGrid, you can add/remove objects from the ArrayCollection and the DataGrid will update.  However, updating properties on the objects doesn't seem to update the DataGrid until you force a redraw via some other means (e.g. resorting the rows).  In my particular case, the Objects in question were non-dynamic instances of a custom class that are [Bindable] at the class level.

This was unexpected to me, but on further reflection seemed quite explicable (though not necessarily reasonable).  It seems that individual DataGrid cells ought to be bound to the property they're fronting, rather than only the rows being bound to the Objects.  But with the way the internals of DataGrid work, the property selection is dynamic (using [] notation), which is unbindable directly.  You can avoid it with a bindable function, of course, but it seems DataGrid (at least in Flex 2.0.1) doesn't do that.

I'll probably dig into this some more (since I really don't want to have a zillion executeBindings() calls all over the app).  If anyone has any insight into this behaviour, I'd be quite interested to hear it.

List/ComboBox Row Backgrounds in Flex

All the listy components in Flex (List, Datagrid, Tree, etc.) have a protected method called drawRowBackground which is in charge of drawing the background for a given row. You typically use it to color a given row based on some facet of the data the row represents (e.g. red background for rows with a negative bank balance).

With DataGrid, it's easy to use, just subclass DataGrid and override the method, parameterized so you can pass in a function to compute the color for each row based on the row index/data/original color/etc. With List (and since ComboBox uses a List, ComboBox too), it's a bit nastier.

For some reason, List will only call drawRowBackground if the 'alternatingItemColors' style is set for the List. So if you want to color your List rows, you have to supply that style, which you'll likely immediately be overriding.

With ComboBox, you use a ClassFactory for the dropdownFactory to instruct it to use your custom List implementation (that will do row coloring). In this case, however, it's not the List instance that needs the 'alternatingItemColors' style, but the ComboBox. The ComboBox passes all it's style attributes to the List that backs the dropdown when it's created.

Just for reference, here is my subclass of List to allow row coloring. The one for DataGrid is identical, except for the name and the class it's extending:

package views {
  import mx.controls.List;
  import mx.collections.IList;
  import flash.display.Sprite;

  public class RowColoringList extends List {

    [Bindable]
    public var rowColoringFunction:Function;

    protected override function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void {
      if (rowColoringFunction != null && IList(dataProvider).length > dataIndex) {
        color = rowColoringFunction(IList(dataProvider).getItemAt(dataIndex), dataIndex, color);
      }
      super.drawRowBackground(s, rowIndex, y, height, color, dataIndex);
    }

  }
}

The Woes of Flex

I've been working on a big Flex project for a while now, and boy is it a pain. I have to give Adobe credit for making straightforward quite simple (linked DataGrids with drag'n'drop selection is a snap), but once you get past the basics of the framework, it gets cumbersome quickly. Flex 3 (now that it's public - though still beta) promises to alleviate a number of the nagging problems, but from what I've experienced over the past few months, HTML-based UIs are faster to develop, are easier to maintain, and enormously easier to control the presentation of.

In particular, styling a Flex app is a joke. CSS stands for Cascading StyleSheets, but Flex has no cascade. You can't do contextual selectors. You can't have multiple class selectors on an element. And you can't even use existing CSS tooling, because all the style names are different (e.g. fontFamily instead of font-family). Very frustrating.

Flash does provide some nice things, like automated history management, and very straightforward use of view stacks (to use the Flex term). Not having to think about plumbing those is definitely nice, as they're cumbersome to get right. But by the time I got to wishing that AxisRenderer actually had a decent API for extending it's behaviour (instead of a pile of private helper methods), or DataGrid supported 'colspan' (which it does in Flex 3 via AdvancedDataGrid), etc., the benefits are a bit overshadowed. And that's even before considering the fact that a huge amount of base plumbing for HTML-based apps is available from various toolkits (just as it is for Flex).

Hopefully we can get things squared away to use Flex 3 for the project, as that'll ease a lot of headaches. Because I don't know how much more suffering I can take.