Flexlib's SuperTabNavigator and Truncated Labels

A quick `uh-oh, bug fix!' post here. We've been using the SuperTabNavigator from flexlib for some of our tabbing needs, and recently realized we had run into a bug: if your navigator is set to limit the width of tabs to a certain amount, thus causing labels to get truncated, then you will have trouble editing the labels on those tabs.

The SuperTabNavgiator provides, amongst other features, the ability to edit a tab label in line. This is pretty cool, and the way it is implemented is even cooler: basically the same textField that is used by the Tab to display the actual label then has its type property set to TextFieldType.INPUT to make it editable. Pretty slick.

The troubles come when the label is truncated. By default, what tabs do when they have to truncate their labels is keep their label property the same, set their tooltip to their full label text, and then set their textField's text to a truncated version of the label with a `...' on the end. This works out nicely, as it means that you have a truncated label for width purposes, and can get the full label by looking at the tab's tooltip. But! Since SuperTabNavigator uses that same text field for editing, when you go to edit the text, it's the truncated version! That is to say, if I had a label title that was `This is a cool tab', that was truncated to `This is a coo...', when I went to edit it, I would be editing the text `This is a coo...', not my real label text!

This is a pretty huge problem, but it's also relatively easy to work around. When the SuperTab is switched into edit mode, we basically set its textField's text back to the value of the tab's label (remember that it is never truncated, only the text in the field is). When the text is updated, the field will get truncated again by the Tab class's own handling of the label property. Thus, we have the right editing functionality and the right viewing functionality.

Implementing this fix is a bit complicated, however. Basically, you need to implement it in a subclass of SuperTab. That's easy enough. The trouble comes with the fact that we need the SuperTabBar to use that subclass of SuperTab. Ok, so we create a subclass of SuperTabBar that instantiates FixedSuperTabs instead of SuperTabs. Now the problem is getting the SuperTabNavigator to use the FixedSuperTabBar instead of the SuperTabBar. So we need a trivial subclass of that. The solution is a set of three classes: FixedSuperTabNavigator, FixedSuperTabBar, and FixedSuperTab, with the real work done in the last one. We'll have a quick look at the code for the fix in FixedSuperTab:

We override the setter for editableLabel (which is where we are switched into editing mode). We let SuperTab do its thing, and then, if we need to, we do our own overriding of the textField's text. Then we also redo the selection of the text -- SuperTab selects the full text when the tab is made editable, but we've just changed the text in the field, so the selection will at best be off and at worst non-existent. Thus, we redo it so that it is correct.

Here is a ZIP file with the three necessary files for a fixed editing experience. I need to submit a patch for this to the flexlib folks, but this will do as a stopgap.

UPDATE: I went ahead and posted a patch to the appropriate issue at http://code.google.com/p/flexlib/issues/detail?id=82