Friday, October 10, 2008

Skinning in Degrafa

I know, I'm way behind the times, but I had my first experience skinning in Degrafa on a project last week. My perception of Degrafa previously was that it was a nice framework to give you markup for skinning, but doesn't really add anything over the Flex drawing API. This is partially true -- Degrafa doesn't do anything you can't do on your own with the graphics package. However, in true component programming spirit, they've abstracted the graphics package to the point that its almost stupid-easy to use. For very simple tasks it might not be worth bringing in Degrafa. For example, on this project I needed to skin a radio button to be pill shaped. I could have used Degrafa, but with the drawing API this is all the code I needed (in a skin class):

protected override function updateDisplayList(w:Number, h:Number):void{
super.updateDisplayList(w, h);
graphics.clear();
if(name == "upSkin"){
graphics.beginFill(UP_COLOR);
graphics.lineStyle(1,UP_COLOR);
} else {
graphics.beginFill(DOWN_COLOR);
graphics.lineStyle(1,DOWN_COLOR);
}

graphics.drawCircle(w - h/2, h/2, h/2);
graphics.drawCircle(h/2, h/2, h/2);
graphics.endFill();
if(name == "upSkin"){
graphics.beginFill(UP_COLOR);
graphics.lineStyle(1,UP_COLOR);
} else {
graphics.beginFill(DOWN_COLOR);
graphics.lineStyle(1,DOWN_COLOR);
}
graphics.drawRect(h/2, 0, w - h, h);
graphics.endFill();
}

Not bad -- forget the repeated if statement and its only 13 lines of code. But later in the project I needed to put a gradient in the background of several components. I could have used the drawing API and a skin to accomplish this, or I could just add this inside the components MXML:

<degrafa:Surface height="100%" width="100%">
<degrafa:fills>
<degrafa:LinearGradientFill id="backgroundFill" angle="90">
<degrafa:GradientStop alpha="1" color="0x555555" ratio="0"/>
<degrafa:GradientStop alpha="1" color="0x787878" ratio="0.2"/>
</degrafa:LinearGradientFill>
</degrafa:fills>
<degrafa:GeometryGroup>
<degrafa:RegularRectangle height="{height}" width="{width}" fill="{backgroundFill}"/>
</degrafa:GeometryGroup>
</degrafa:Surface>

I prefer this way. Not only is it less code, but its easier to think about. And, in my opinion, that's what OO and component programming are all about: tackle a difficult task on the scale where its a simple task and create an abstraction so that the complex task becomes a series of easy tasks. Degrafa went down into the drawing API where each task is (relatively) easy and built up a framework so that we can do complex tasks as a series of completely intuitive easy tasks. Degrafa can also be used to make skin classes (as opposed to putting the Degrafa right in the component layout like I did in this case) and works great with CSS. They have tons of examples with source on their site and you can also get the SWC there.

0 comments: