Tag Cloud

Did a little bit of vanilla Flex work recently, and I needed a Tree component to display an object hierarchy. Everyone, by now, hopefully knows that mx:DataGrid and mx:Tree are two of the crappiest, bug ridden, worst performing components from Flex 3. And, everyone by now, has left the buggy world of Flex 3 behind and entered the world Flex 4 and the vastly improved Spark components. With the arrival of Flex 4.5 this summer, Adobe finally gave us a rewritten Spark-based DataGrid. Alas, no updated Tree yet, so I had to write my own. So once again, I turned to the trusty combo of List plus custom ItemRenderer to make pure-Spark custom TreeList component that doesn’t suck.

Alex Harui is the guru of turning a Flex 4 Spark List into a look-alike for the old Flex 3 component using skins and a custom ItemRenderer. Alex has used List + ItemRenderer to make a DataGrid, DateField, ColorPicker, Menu + MenuBar, and even an XML-based TreeList. Unfortunately, Alex’s TreeList assumes incoming XML, and I needed a TreeList that could display a simple object hierarchy (root node with children, and those children have children, etc.). Since I couldn’t find exactly what I wanted, I decided to build it myself.

Flattener

The key step to getting a hierarchy of objects to display as a list is: flatten the list, duh! Or at least flatten the part of the tree you wish to display. So, I built a simple adapter class that turns an object hierarchy into an ArrayList that can be given directly to a List‘s dataProvider.

There’s really not much to it. When instantiated with a root object, the object hierarchy is walked recursively to build a flattened list of all the open nodes. Once the initial list is built, openItem() can be called to open a node, and add all its children to the list. Alternately, closeItem() can be called to close a node, and remove all its children from the list.

Design

I used some basic styling and skinning, but the ItemRenderer does the majority of the work. Here’s the abbreviated version of MyObjRenderer.mxml with all the boring stuff edited out:

Each rendered item has a background Rect and a Label. But most importantly, each row has either a ToggleButton (if the object has children) or some non-interactive visuals (if the object doesn’t have children it just gets a dot). The toggle button is the key interactive element used to open or close the node, everything else is part of the visual gravy added to make the list look good.

Focusing on the functional stuff, if you look in the script block, you’ll see two functions: a data() setter and a toggleHandler() to handle toggle button clicks. As expected, clicking the toggle button calls openItem() or closeItem() on the flattener adapter which adds or removes children from the flattened list, respectively. The setter mostly sets up the local variables, but it notably computes if the object has children or not, and also sets the initial state of the toggle button.

Conclusion

With just a little effort, we can have a nice usable Spark TreeList component that looks decent. More importantly, we have total control and can make the TreeList look like anything our designer can throw at us. As is always the case, the combo of List + ItemRenderer proves to be awesome. I tried to cover all the interesting pieces, but for the details, you’ll need to check out the source code.

At the core of the Clock component is a single timer. When the timer fires, it uses the current date to compute the angle of the hour hand, minute hand, and second hand. The actual motion of the hands is managed via the awesome proxy functionality in Grant Skinner’s GTween library.

All the interesting FXG action takes place in the skin, so let’s check it out:

Getting data to the skin is done via the standard binding to hostComponent. There is no need for the more complicated partAdded() and partRemoved() mechanism, because the Clock component is not intended for general use, unlike my previous components: Terrific TabBar, SuperTextInput, and Drawer.

The skin has a big block of programmatic FXG skinning, done in actionscript code inside the complete() handler which is fired by the creationComplete event. It also has a big block of vanilla MXML declarative FXG skinning, which, most importantly, includes the clock hands and the previously mentioned binding to hostComponent.

By its nature, a clock has a lot of identical elements that are positioned in a circle. The obvious attack is to put the repeated elements in a loop, or set of loops, and go the programmatic route to construct the skin. For example, the long thin ticks along the outer ring are constructed with a double loop. Here’s the relevant snippet of code from inside the complete() handler:

A new Path element is created and its data property is set. Our tick mark is 10px long, but only 1px wide. With each iteration, a tick mark is created and rotated into place. There are two important tricks in this code that are worth pointing out. First, the rotation origin is at (0,0) for each element, so we must construct our path from -0.5 to 0.5 for it to rotate correctly. Second, we must use addElementAt() to place each element into the proper layer of the drawing because the programmatic FXG code runs after all the vanilla (aka non-programmatic) FXG has been drawn.

Conclusion

No one in their right mind would ever build a clock skin like this. To do this the right way, you’d definitely want to use an image or two to construct the skin. The only reason I went the programmatic FXG skinning route was to verify to myself that it could be done. So, yes it can be done, and I enjoyed the trip.

Files

Another day, another custom component in Flex 4. This time it’s a closeable TabBar that I’m calling TerrificTabBar, because SuperTabBar is taken. This post is basically Part 2 of my previous post on SuperTextInput. And much like that post, TerrificTabBar follows the Enhanced Component Pattern by extending TabBar and adding some new functionality.

Extend TabBar and TabBarButton

I just want to build your average web browser tab in Flex 4, no more, no less. Browser tabs have two cool features: each tab has a close button, and the tabs can be reordered by dragging. Actually, I just lied about the no less part, because I’m going to ignore dragging and focus my attention on the closeable tab part. Please see my previous post on drag-and-drop in Flex 4 if you are interested in the dragging part.

A TabBar is just a bag of tabs, where each individual tab is a button, or a TabBarButton to be more precise. To create a closeable tab, we need to add a new button that can be clicked to close the tab, duh. And this is in addition to the default behavior of clicking the tab to select it. Since we are disciples of The Flex 4 Way of building custom components, we know this means we must extend TabBarButton and add a new ButtonSkinPart to it:

First, we have the closeButtonSkinPart and it’s closeHandler() event handler. Wiring the handler function to the button is done in the partAdded() override, and un-wiring in the partRemoved() override. The handler just bubbles a closeTab custom event which will be handled by the parent TabBar. Next, we use the closeable property to manage the close button’s visibility. Finally, an additional button visibility check is necessary in partAdded() to set the initial visibility.

There are two other interesting pieces of code. One, we must set mouseChildren = true in the constructor to enable our button within a button to receive and respond to mouse events. Two, in a somewhat hackish fashion, I add or remove padding from the tab’s label when the close button is present or not.

Now that we have a nice close button on the individual tabs, we extend TabBar to make a pretty API for managing tabs and their new functionality. Here is an abbreviated TerrificTabBar component showing the relevant public methods:

There is a public getter and setter for toggling the close-ability of individual tabs, setCloseableTab() and getCloseableTab(). And also a public method for closing a tab, closeTab(), which can be used to force close an un-closeable tab. Additionally, closeTab() is used internally to close a tab when its close button is clicked. As is standard, the wiring and un-wiring of the closeHandler() handler function is done in the partAdded() and partRemoved() overrides.

Very vanilla, but there is one interesting part worth mentioning. I made the decision to attach the listener to the dataGroup property of TabBar, this is the default container of individual tabs (aka TerrificTabBarButtons). Yes, I could just as easily have attached the handler directly to TabBar in the constructor and used weak references. But after having built enough custom Flex 4 components, it feels funny to me to do any event wiring outside of partAdded() and partRemoved(). Thus, I made the decision to attached to dataGroup. Without doing a bunch of testing (which I haven’t done), I can’t say if this is better or worse from a memory or performance perspective, I just like the way this code looks better.

Conclusion

I put a pretty skin on everything using some of my favorite drawing tricks, but that’s the subject of a future post. Some brief highlights include:

I used CSS to wire my components to my skins, so I minimize the use of skinClass attributes for better decoupling

I used a big negative gap in TerrificTabBarSkin to make the tabs overlap

I set a maxWidth and a minWidth on the individual tabs in TerrificTabBarButtonSkin, which in combination with maxDisplayedLines="1" on the Label, make the tabs truncate with ... when they get too big

The curved tab shape is drawn with a Path, but I wrap it with a Group and set the Group‘s scale-9 grid (scaleGridLeft, scaleGridTop, etc.) so it expands and contracts correctly

The close button’s x is drawn as a + around the coordinate origin, also known as (0,0), and then rotated 45 degrees

Files

I’ve been building a lot of Flex 4 custom components lately, including a sliding drawer, a multiple content area container, and now SuperTextInput. Nor will this be that last, because I think I have a few more in me (update: see TerrificTabBar). I thought it would be useful to spend some time in the details, explaining The Flex 4 Way and how I try to walk the path.

SuperTextInput is a prompting, clearable TextInput extension in Flex 4. It’s just an enhanced version of the default TextInput control, and as such, it follows a fairly standard pattern of custom component creation.

Enhanced Component Pattern

It’s almost too stupid to call this a pattern, but it’s so common in custom component creation that I’ll run with it. Also, I’ve found it to be worthwhile to distinguish between adding new functionality to a component already present in the framework (aka an enhanced component) versus creating a truly custom component.

The enhanced component pattern is just two simple steps:

Extend – extend some default component and add some new functionality

Skin – make it look good

In my version of reality, these steps carry equal weight, because almost all worthwhile functionality in Flex touches the UI in some fashion, so the design and UX (the look-and-feel, it’s usability, the integration into the rest of the app, etc.) are critical. Don’t forget or skimp on step #2 because it’s all the client, team, customer ever sees.

A Prompting TextInput

Since SuperTextInput has two new pieces of functionality (the prompt and the clear button), I’ll split them apart, and consider each part separately. First, the prompt is merely the text you see when the TextInput is empty. It often becomes a space saving label, because it can be used to tell the user what goes into the TextInput without costing the UI any screen real estate.

Thinking more about the prompt, we want the prompt text to be visible initially, but it should disappear when the user clicks (or tabs) to the control, and only returns when the control loses focus and is still empty. So this tells us that we need to communicate both the prompt text and it’s visibility to our skin. The prompt text can just be a simple LabelSkinPart, but it’s visibility is complicated enough that it makes sense to add a new promptingSkinState.

In addition to the promptDisplaySkinPart and the new promptingSkinState, there is a lot of other stuff going on in the above code. First, as is typical with data-driven SkinParts, we back the promptDisplay with a good old prompt property. The net is the fairly common pattern of: check if the SkinPart is not null, then do something to it. So in the prompt setter, we assign the incoming value to the private _prompt variable, then check if promptDisplay is available and if yes, set it’s text property. The setter does the job of updating the prompt, but only once everything is happily running. In order to get the data to the skin initially, we must use the partAdded() override to pass the local prompt to the promptDisplay‘s text property. And that’s it for the prompt text.

The prompt visibility part requires lots of event watching, and also SkinState stuff because we made the choice to push visibility via the promptingSkinState. First, we wire up both the programmatic text change events and the user text change events to a handler, textChangedHandler(), that does nothing more than invalidate the state. TextInput change events are a little wacky, but the code works fine. Next, instead of wiring the focus events to another handler (as seen in this prompting TextInput component by Andy McIntosh), we simply override the protected handlers in the parent and add our focus-tracking logic directly. Finally, we override getCurrentSkinState() to do the work of figuring out whether or not the prompt should be displayed.

A skin for PromptingTextInput is now trivial because our component does the work of pushing the important information to the skin. If we ignore all the pretty stuff, the skin is very simple:

We add the promptingState to the list of states and also add the promptDisplayLabel component. By using the standard inline state syntax, includeIn="prompting" our Label is shown only in the prompting state.

A Clearable TextInput

The second piece of SuperTextInput functionality is the clear button. The clear button appears when the TextInput has a value, and when clicked, it clears that value (which re-displays the prompt). Again, there are two pieces of information the need to be communicated to the skin to create the clear button functionality: the button itself and it’s visibility. In this case, since the visibility is so simple (on if TextInput has a value, otherwise off), we’ll just punt and manage it directly in the component. Therefore, the only a ButtonSkinPart for the clear button will be pushed to the skin.

After the PromptingTextInput, the ClearableTextInput is a little more straightforward. First, we have the clearButtonSkinPart and it’s clearClick() event handler. Wiring the handler function to the button is done in the partAdded() override, and un-wiring in the partRemoved() override. Next, button visibility is managed by watching for both programmatic text change events and user text change events. The handler, textChangedHandler(), sets the button as visible when the control has text in it.

As I mentioned above, I decided against pushing the clearButton‘s visibility down to the skin via a SkinState, and instead chose to manage it inside the component by setting clearButton.visible directly. I tend to favor the SkinState method when more than one thing needs to change in the skin or if I need advanced visuals (like transitions). If I need to do just one thing and I don’t care about visuals, I’ll do it inside the component. The two examples here aren’t the best to illustrate the two options, but that’s my general thought process when building a custom component and custom skin.

A skin for ClearingTextInput is super trivial. Again, ignoring all the pretty stuff, the skin is:

Fusion, Glorious Fusion

The fusion process of creating SuperTextInput from PromptingTextInput and ClearableTextInput is nothing more than copy and paste. SuperTextInput has lots of uses, but my favorite is to use it to capture text input to filter a list. It also works great as a search box, or in any smart form UI. Enjoy.

Files

Back in the days of Flex 3, if you wanted multiple content areas in your main application, you’d need to arrange some set of containers (Canvas, HBox, VBox) in the app and fill them with content. It was just your basic Flex 3 development process. The danger, of course, is that you are mixing content with presentation, aka bad separation of concerns. Today, with the power of Flex 4 skins, we can avoid this issue by moving the presentation layer into a skin (or set of skins). And thus, we can do a much better job achieving a happy level of separation of concerns.

The Flex 3 Way

To give a concrete example, I’ll build a blog layout (yes, another blog layout) with a header, footer, sidebar, and main content areas. But before we get started, let’s review the old Flex 3 way:

The above code comes from a previous post, Designing in Flex 3, but has been modified to make sense here. You’ve got you basic blog design: a box for the header, footer, and body, where body is subsequently is divided into a main content area and a sidebar.

The 3-in-4 Way, aka The Wrong Way

The unfortunate next step in a Flex developer’s evolution is what I like to call the Flex 3-in-4 way. This is a the way of neanderthals, which is to say, it is an evolutionary dead end. If you ever have the bad luck to see 3-in-4 code, you can be sure you are dealing with a novice Flex 4 developer. In general, the 3-in-4 way consists of making the simple transcription: Canvas → Group, HBox → HGroup, VBox → VGroup. But the most damning tipoff of a 3-in-4 developer is the assertion that one is now a Flex 4 developer and the learning curve wasn’t all that bad. While I do think Flex 4 is more of an evolutionary release than a revolutionary release, it’s different enough. And it is particularly different on the design side of the framework, how it handles skins, layout, etc.

If we just transcribe the above example, we get some classic 3-in-4 code:

As you can see, the main app is now a nice set of semantic buckets, one for each of the content areas. Header stuff goes in the headerContent bucket, footer stuff goes in the footerContent bucket, etc.

Building a Multi Content Area Container

Second, we need to create a custom container with the nice set of semantic buckets used in the above code. This is achieved by following a straightforward formula:

Add Buckets – add some content buckets (in the form of xxxContent) as Arrays. These become the MXML tags used to bucket components together. Each content bucket has a public getter, but most importantly a public setter that accepts an incoming Array of IVisualElements and uses the magical mxmlContent property to assign it to the associated SkinPart.

Add SkinParts – add some matching SkinParts (in the form of xxxGroup) as spark Groups. There are used in the custom skin to display the content. Also, I usually set required="false" to make everything optional.

The custom component code is actually easier to follow then the description. Here is a custom container with only one additional content bucket, sidebarContent, and its matching SkinPart, sidebarGroup:

Following the four steps: we extend Application, have a sidebarContent bucket and its associated sidebarGroupSkinPart, and override partAdded() and partRemoved() to wire everything together.

Skinning a Multi Content Area Container

Skinning in Flex 4 is awesome, and like everyone says, it’s easily one of the best new features in the framework. While I find the skinning process fairly straightforward, I would never call it trivial, mostly due to the depth and flexibility of the skinning system.

We need a custom skin for our custom multi content area component. This is probably the 10% case for skinning, but it’s also the coolest. In my experience, an average Flex 4 app has many Button skins (like 10 or even 20), a few default component skins (skins for List, DropDownList, TextInput, etc.), and maybe only two or three skins for custom components.

The skin itself is nothing special. To display our custom component’s SkinParts, we simply include a Group with the matching id attribute. For example, our skin will include a <s:Group id="sidebarGroup" /> to display the sidebarGroupSkinPart. Just rinse, wash, repeat, to add all of our custom content areas in the container to the skin.

In this trivial skin, we just shove all the content groups (including SkinnableContainer‘s default Group, contentGroup) into a VGroup. Also note, we correctly set HostComponent to our custom container. If you are thinking, "Hey, this skin looks similar to the Flex 3 and 3-in-4 example code, just minus the content" that’s exactly the point.

Using skinClass to wire a skin to a component is so 2009. The sample app has its CSS inline, but in any real app I’ll always put this in an external file.

Conclusion

After this, there’s really not much more to say. You can certainly create a more complicated arrangement of the multiple content areas by making a more complicated skin. I’ve done exactly this in the final sample, which includes three different skins and a skin switcher (click 1, 2, or 3 to switch skins).