first_page

Adobe Flex Design Diary: Skinning is Different from Displaying Vector Icons

One of the aspects of my personality that have made me completely annoying to manager types is my fanatical attention to detail (often coupled with goofy omissions of the obvious). The reason why most managers I have met in North America are managers in the first place is to get away from technical minutiae and get into political finery. Once you are into the world of politics—the belief in magic is not far behind. The scientific reality behind most magic—even Black Magic—is (you guessed it) a fanatical attention to detail.

I “wasted” your time reading the above paragraph when all I had to do is write this: I have spent days trying to generate vector icons inside a Button object. It turns out that there is a very simple solution to this problem: don’t do this. But the ‘annoying’ bit about me is that my person needs to know exactly why we should not do this (in Flex 2.x). Researching why this should not be done helped me understand what Adobe calls “skinning” is (to me).

First, to appease the American manager in all of us, let’s eliminate the clumsy, bulky, gross oversimplifications about “my problem”:

  • Oversimplification #1: “Dude, just use a SimpleButton.” This managerial decision is basically running away from Flex altogether and pining for the old salad days through the flash.display package. Yes, you get relatively straight-forward properties like, SimpleButton.upState, SimpleButton.``overState and SimpleButton.``downState. But you have to use rawChildren to display these things in ‘real’ Flex applications. I just can’t put my trust in the future of the rawChildren property and there is no language coming from Adobe (that I have found) encouraging me to trust that it won’t suddenly be deprecated as a “legacy” thing.
  • Oversimplification #2: “Dude, just use Adobe Illustrator and embed your vector icons.” This is spoken like a true authority figure at some goatee-shaven graphic design firm. This process is explored in “Adobe AIR, Flex 3 and Integration between Fireworks,Photoshop and Flash CS3 with Flex. All of these topics at the AdobeLive 2007.” For me, I risk the prejudiced accusation that I am a “typical developer” who is “scared” of Illustrator when I say that this approach makes too many moving parts (“assets”) for something as ‘simple’ as a damn button. I would rather write the code in one complicated place to draw the vectors—instead of spending the time to do the same in Illustrator.Other oversimplifications to “my problem” include embedding TrueType fonts (very limiting for visual designing) or embedding PNG files (almost the same as using Illustrator—but this can degenerate into using bitmaps, not vectors).

Okay, by a process of elimination, the ‘only’ solution to “my problem” is to use a ‘real’ Flex Button and its skinning technology. I avoided this topic because the very word “skinning” turned me off. It turns out that my feelings about this are now backed up with the horrible facts:

  • You use a Flex CSS declaration with ClassReference() in a Button type selector to call code that will ‘skin’ the button. This ClassReference() statement in CSS allows you run ActionScript code because of a CSS declaration. I am sure we can find an Adobe engineer shaking with anger, forged in the hard-earned knowledge about why this stupid shit has to be done.
  • In the Flex SDK, there is a default “halo” CSS file which calls mx.skins.halo.ButtonSkin. This refers to an ActionScript file (~/frameworks/source/mx/skins/halo/ButtonSkin.as) with 326 lines of code and comments. The folks building flexlib have ~/src/flexlib/skins/EnhancedButtonSkin.as with 615 lines of code and comments. Buy this book at Amazon.com!So it turns out that “my problem” occurs when the halo, button skin code runs a function override called updateDisplayList(). The first problem is that this.graphics.clear() is called. So whatever I may “draw” inside of my button via graphics will be erased.

My drawing code block can be run in case "upSkin" and works as expected. It seemed obvious to me that a similar pattern could be used in case "downSkin" or case "selectedDownSkin". This is just not the case (no pun intended)—this is my second problem. When I click and hold down the mouse button (to run the “down skin” case), the button is empty! There is something going on inside the button that is beyond the control of the button skin code.

Since the code and comments written by Adobe that controls a Button instance exceeds 2300 lines, the line must drawn—even I must play the manager and stop myself from losing hours of my vital life wading through Adobe intent. But at least here in my “little world” I have some idea about what’s going on with my buttons!

So my way out of this problem is to draw vector icons behind the button. Setting the Button.alpha property to reveal a vector drawing behind it avoids messing about inside the button. And the Adobe skinning code is ‘free’ to do what it clearly was designed to do: draw graphics that describe the entire button shape and surface.

Related Links

[flexlib—Google Code](http://code.google.com/p/flexlib/) “The FlexLib project is a community effort to create open source user interface components for Adobe Flex 2.”
[Flex Coders Mail Archive](http://www.mail-archive.com/flexcoders@yahoogroups.com/msg25000.html) “However you should able to add it as a non-content or ‘chrome’ child by doing `rawChildren.addChild(myButton)`. Non-content children don’t undergo automatic sizing and layout, so you’ll have to set the size and position of `myButton` yourself.”
“[Flash CS3: Missing ‘disabledState’ for the SimpleButton class](http://www.websector.de/blog/2007/08/22/flash-cs3-missing-disabledstate-for-the-simplebutton-class/)” “…overriding the setter method of its enabled property is a good way to solve this problem…”
“[SimpleButton—Adobe® Flex™ 2 Language Reference](http://livedocs.adobe.com/flex/2/langref/flash/display/SimpleButton.html)” This stuff written by some Adobe employee is confusing, misleading, and without appropriate context: “The `SimpleButton` class lets you control all instances of button symbols in a SWF file. After you create an instance of a button in the authoring tool, you can use the methods and properties of the `SimpleButton` class to manipulate buttons with ActionScript.”
“[SimpleButton Class in Actionscript 3.0](http://weblog.cahlan.com/2006/07/simplebutton-class-in-actionscript-30.html)” A better way to introduce the `SimpleButton`: “The `SimpleButton` class allows you to create—you guessed it—simple buttons. It’s basically a dynamic way to create Buttons with predefined states used in Flash.”
“[rawChildren.addChild() and it’s sneakyness](http://www.restlessthinker.com/blog/?p=59)” Provides some insight into why we should avoid the `flash.display` package for ‘real’ Flex applications.

rasx()