admin originally posted this on Saturnboy.
A while back I started digging into the WindowShade component in Flexlib. I really needed a set of cool collapsable buckets for a project at work, and WindowShade was perfect for the task. Alas, I couldn’t find too much info on styling a WindowShade other than Doug McCune’s awesome example of WindowShade and Degrafa. So, here is how I went about achieving the look and feel I needed with WindowShade.
Plain Vanilla
I started with an unstyled, super vanilla WindowShade wrapping a List. And of course, I get this super-vanilla output:
shade 1 (view source enabled)
The only styling magic was to add padding="0" to the WindowShade to get the child List component to suck up to the bottom of the WindowShade button.
My First Attempt
In the next pass, I ditched the lame WindowShade button, and went with Flexlib’s CanvasButton, which contains a simple Label plus a CheckBox skinned with a plus or minus graphic. The code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flexlibContainer="flexlib.containers.*"
xmlns:flexlibControl="flexlib.controls.*"
viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
[Bindable]
private var goodies:Array = [
{ header:'Ice Cream', items:['Vanilla', 'Chocolate', 'Strawberry', 'Cookies & Cream'] },
{ header:'Candy', items:['Twix', 'Snickers', 'Fire Balls', 'Hot Tamales', 'Mike & Ikes', 'Pez'] },
{ header:'Cookies', items:['Chewy Chips Ahoy', 'Mint Milano', 'Oreo', 'Nutter Butter', 'Fig Newtons'] }];
]]>
</mx:Script>
<mx:Style source="style.css" />
<mx:VBox width="140" styleName="container">
<mx:Repeater id="r" dataProvider="{goodies}">
<flexlibContainer:WindowShade width="100%" styleName="shade"
data="{r.currentItem.header}"
opened="{r.currentIndex == 0}">
<flexlibContainer:headerRenderer>
<mx:Component>
<flexlibControl:CanvasButton width="100%" height="30" styleName="shadeBtn">
<mx:Script>
<![CDATA[
import flexlib.containers.WindowShade;
]]>
</mx:Script>
<mx:Label id="header" top="3" left="4" text="{WindowShade(parent).data}" styleName="shadeHead"/>
<mx:CheckBox id="chk" top="9" right="6" selected="{WindowShade(parent).opened}" styleName="shadeChk"/>
</flexlibControl:CanvasButton>
</mx:Component>
</flexlibContainer:headerRenderer>
<mx:List width="100%" dataProvider="{r.currentItem.items}" rowCount="{r.currentItem.items.length}" styleName="shadeList"/>
</flexlibContainer:WindowShade>
</mx:Repeater>
</mx:VBox>
</mx:Application>
After throwing in some colors from a sweet Kuler theme and embedding Helvetica, we get this:
shade 2 (view source enabled)
At this point, I was really happy with look and feel, but there we still a few minor issues with the CanvasButton header that needed to be fixed before declaring victory.
Fixups
First, I needed the rollover event to flow down to the checkbox, so it would correctly show the overSkin on mouse over. Second, I wanted a color change on the Label on rollover to provide better visual feedback to the user. And lastly, I wanted the entire CanvasButton header to be clickable, not just the label text or the checkbox graphic.
Focusing just on the modified CanvasButton code, used in the headerRendered:
<flexlibControl:CanvasButton width="100%" height="30" styleName="shadeBtn"
rollOver="header.setStyle('color', 0xffffff); chk.dispatchEvent(event);"
rollOut="header.setStyle('color', 0xcccccc); chk.dispatchEvent(event);">
<mx:Script>
<![CDATA[
import flexlib.containers.WindowShade;
]]>
</mx:Script>
<mx:Label id="header" top="3" left="4" text="{WindowShade(parent).data}" styleName="shadeHead"/>
<mx:CheckBox id="chk" top="9" right="6" selected="{WindowShade(parent).opened}" styleName="shadeChk"/>
<mx:Canvas width="100%" height="100%" backgroundColor="#000000" backgroundAlpha="0" />
</flexlibControl:CanvasButton>
The final result, a nice styled WindowShade:
shade 3 (view source enabled)
I used the parent CanvasButton’s rollover event to set the child Label color and forward the event to the child CheckBox. To make the entire button clickable, I used one of my favorite Flex UI hacks: I added a space-filling transparent Canvas.
Comparison Shopping
And finally, a side-by-side comparison of all three WindowShade skins:
Flash is required.
Get it here!
