Tuesday, June 1, 2010

TitledBorderBox (Flex 4/Spark)

I've re-written my original TitledBorderBox class (Flex 3) to use Spark/Flex 4 components. It is slightly simpler, and hopefully more lightweight. It extends the SkinnableContainer class, and uses it's own skin (flex.utils.ui.TitledBorderBoxSkin).

Here are the properties on the component:
  • backgroundAlpha - the background alpha for the box (default: 1)
  • backgroundColor - the background color for the box (default: white)
  • backgroundVisible - if the background should be shown (default: true)
  • borderAlpha - the border alpha for the box (default: 1)
  • borderColor - the border color for the box (default: black)
  • borderWeight - the thickness of the border (default: 1)
  • borderVisible - if the border should be shown (default: true)
  • cornerRadius - the corner radius for rounded corners (default: 0)
  • dropShadowVisible - if a drop shadow is shown (default: false)
  • titleStyleName - the style name for the title label (default "windowStyles")
  • title - the title to show in the border
It also supports most of the layout properties too as styles (paddingLeft/Right/Top/Bottom, gap/horizontalGap/verticalGap, horizontal/verticalAlign, etc) for convenience.

The way the border is drawn is to simply draw a line over top of the border, but underneath the title that is the same color as the background. If you set borderVisible="false", then it will attempt to find the background color of the parent and use that instead.

Here it is in action (view source enabled, right click):

19 comments:

Dan Nelson said...

Great! Thanks for the example.

Softweb Solutions said...

nice examples and explanation i really like it
Flex Development

Anonymous said...

Thanks for the example.

I did have one issue with embedded fonts though as the mx.core.UIComponent.measureText(text:String) method can't be used with Spark components as stated in the documentation. I used the height and width of the Label component itself to determine the path data.

Vrushali said...

Very nice! Exactly what I was looking for. Maybe you should get it added to flexlib or some other community set of components.
I have a question. In Flex3 component, I see a TitleBorderWindow component which has a close button and status feature. Can we have this feature for Flex4?

Chris Callendar said...

Hi Vrushali,

It adds a bit of extra complexity to have the title status label, and a close button, so I left them out.

I don't have time to do it, but it shouldn't be too difficult by following the same way I did it in Flex 3.

In the Flex 4 version I made some optimizations, but it should still follow the same logic - it uses a Path this time, and draws the border. So with the status label and/or close button, you'd have to calculate how to draw the top line of the border.

If I find the time I'll be sure to post it here.
Chris

Dan Keff said...

Hi Chris.

Thanks for the flex4 spark version. I have one issue. The border does not leave a big enough gap for the text so I get the text written on top of the line and with a very small gap. Any ideas? Im guessing that it is probably something simple.

Tks

Dan

Chris Callendar said...

Hi Dan,

Do you mean that the border doesn't leave enough space for the title text? Or for text that is the content of the window?

Thanks,
Chris

Intoxopox said...

Swell component. However, I can't seem to get verticalAlign center to work. Any thoughts?

Chris Callendar said...

Hi Intoxopox,

What are you trying to set the verticalAlign style on?

Also, usually the verticalAlign style takes one of top, middle, and bottom properties, not center.

Intoxopox said...

My bad, Chris. Was multi-tasking (poorly) when I wrote that. What I meant was using a VerticalLayout, I can't get horizontalAlign="center" to work. I ended up band-aiding this issue by commenting out all the copyLayoutStyle method calls in the skin within updateDisplayList. Any thoughts?

Chris Callendar said...

Hi,
I think what you did is probably best.
This class is ported from Flex 3 when all the layout properties were available as CSS styles, and I was trying to support that.

But that isn't really how Spark is supposed to work, so I would either just remove all that styling stuff, or I would add a property to the TitleBorderBox host component called copyLayoutStyles, and in the skin only that value is true then copy the styles.

Chris Callendar said...

For what it's worth if you used the VerticalLayout you could also define the horizontalAlign style as well like this:
<spark:TitledBorderBox horizontalAlign="center"/>

Intoxopox said...

Much thanks

Dan said...

When I dynamically add or remove elements from the TitledBorderBox component its size does not change or at least it does not shrink. I also tried setting the 'includeInLayout' and 'visible' properties of the child elements to 'false' but this didn't work too. :-(
How can I update the child elements?

Chris Callendar said...

Hi Dan,
I see what you mean. When an element is removed the size of the box doesn't shrink back to the proper measured size.

Here is a very simple fix that works for me - edit the TitledBorderBoxSkin.mxml file, and edit the measure() function to add the includeInLayout lines around the super call (line 24). This way the border path is not used to determine the measured size of the skin.


border.includeInLayout = false;
super.measure();
border.includeInLayout = true;


Chris

Dan said...

Thanks, that worked.

Anonymous said...

Cool component:

i had to change:

var textWidth:Number = titleLabel.width;

to

var textWidth:Number = titleLabel.measuredWidth;

to make the border update correctly for dynamic title text changes..

Cheers

Anonymous said...

Thank you bro :)

Arun said...

Its really Very Usefull.... thank you For u post