views:

1294

answers:

2

I'm working with Flex 3.4 SDK.

I'm trying to programmatically(yep, must be this way) style/skin a VBox so that its top right corner is rounded, and it gets a two colors gradient brackground.

Modifying examples I found around I was able to accomplish both effects(corner and background) but only separately:

VBox with not all rounded corners: http://livedocs.adobe.com/flex/3/html/help.html?content=skinning_6.html

VBox with gradient background: http://butterfliesandbugs.wordpress.com/2007/06/08/generic-background-gradient-for-containers/

But what I need to do is to apply both at the same time. And all my coding attempts so far have failed silently.

Would anyone know how to go about doing this correctly?

+2  A: 

Follow the steps from your second link, but instead of using "drawRect", you should be able to use "drawRoundRectComplex". You may need to play around with some of the matrix settings though. I seem to remember having some problems.

Another option is to use degrafa. There can be a bit of a learning curve, but it's powerful and can do this.

Glenn
I'd definitely go with degrafa here
Joel Hooks
Thanks, that seems to be about it, similar to CapsNZ's solution. And I know about degrafa. As much as it seems to make things easier, I'd prefer not to use it.
Cameigons
+3  A: 

I have a post on my blog on how to make this exact component Here.

You create a basic custom MXML component (extending in this case, VBox). You specify a programmatic skin, which is where the bevel and gradient gets applied.

The programmatic skin does all it's drawing in the updateDisplayList function.

Here is some of the code (the rest is on my blog, with a demo)

   var g:Graphics = graphics;
   var cn:Number = this.getStyle("cornerRadius");
   var crtl:Number = this.getStyle("cornerRadiusTopLeft") > 0 ? this.getStyle("cornerRadiusTopLeft") : cn;
   var crtr:Number = this.getStyle("cornerRadiusTopRight") > 0 ? this.getStyle("cornerRadiusTopRight") : cn;
   var crbl:Number = this.getStyle("cornerRadiusBottomLeft") > 0 ? this.getStyle("cornerRadiusBottomLeft") : cn;
   var crbr:Number = this.getStyle("cornerRadiusBottomRight") > 0 ? this.getStyle("cornerRadiusBottomRight") : cn;
   var gradFrom:Number = this.getStyle("gradientFrom");
   var gradTo:Number = this.getStyle("gradientTo");

   var b:EdgeMetrics = borderMetrics;
   var w:Number = unscaledWidth - b.left - b.right;
   var h:Number = unscaledHeight - b.top - b.bottom;
   var m:Matrix = verticalGradientMatrix(0, 0, w, h);

   g.clear();
   g.beginGradientFill("linear", [gradFrom, gradTo], [1, 1], [0, 255], m);
   g.lineStyle(1,borderColor,1,true,LineScaleMode.NORMAL,CapsStyle.ROUND,JointStyle.ROUND);
   GraphicsUtil.drawRoundRectComplex(g, b.left, b.top, w, h, crtl, crtr, crbl, crbr);
   g.endFill();
  }

for a demo, look Here. Hope this helps.

CaspNZ
Thanks so you much! :) I never used GraphicsUtil, seems to be what did the trick.
Cameigons
You don't need the GraphicsUtil class. "drawRoundRectComplex" is a badly documented feature of the graphics object. http://livedocs.adobe.com/flex/3/html/help.html?content=Drawing_Vector_Graphics_5.html
Glenn
Good point - sometimes Adobe provides too many ways of doing something. This was some code from an old project of mine - I swear I'd know better now! - Casp
CaspNZ