Sunday 21 June 2009

Skinning Panel with borderSkin

I spent far longer than I should have about a week ago trying to skin Panel. This should have been a simple task but it took me about 2 days.

What I was trying to achieve was to skin a Panel with an asset from Flash as a border skin. To begin with we have an un-styled Panel (all the below versions have view source enabled):

If we then add a borderSkin style we can see that the content of the Panel overlaps the titleBar and controlBar:

As we are using our own skin class in this example one possible fix is to make our skin class extend IRectangularBorder:

The problem is though that if we are using an asset to skin our panel we can’t make the asset implement IRectangularBorder. Looking at the code for Panel there is a get viewMetrics function that is supposed to calculate the border around the content area. In our case this is not working so it seems logical that we can override it as follows:

override public function get viewMetrics() : EdgeMetrics
{
    var metrics : EdgeMetrics = super.viewMetrics;
    if( titleBar )
    {
        metrics.top = titleBar.height;
    }
    if( controlBar )
    {
        metrics.bottom = controlBar.height
    }
    return metrics;
}

However if we do this we get this result:

We get extremely odd behaviour in all sorts of other view components even outside our panel. The extra top and bottom that we add to the view metrics seems to get progressively applied to buttons, other non styled Panels and all sorts of other view components.

The solution to this is to change the above code very slightly:

override public function get viewMetrics() : EdgeMetrics
{
    var metrics : EdgeMetrics = super.viewMetrics.clone();
    if( titleBar )
    {
        metrics.top = titleBar.height;
    }
    if( controlBar )
    {
        metrics.bottom = controlBar.height
    }
    return metrics;
}

And we get the following:

I can only guess that the layout class used by Panel retains references to the EdgeMetrics objects returned from super.viewMetrics and this somehow messes up the layout of other components.

I have submitted a bug here that you can vote on if you like.

I hope this blog post helps someone else out who comes across the same problem.

6 comments:

  1. Hi,

    there's a similar issue wich has been deferred: https://bugs.adobe.com/jira/browse/SDK-14806

    ReplyDelete
  2. Good solution, works well. Thanks.

    ReplyDelete
  3. if swc borderskin with this solution.
    how to use?

    SORRY MY BAD ENGLISH.

    but i find very good post(this post).

    ReplyDelete
  4. What about the Close Button for the Panel?

    ReplyDelete
  5. Excelent, that was the solution I was looking for, but it was more complex than I thought. Thanks a lot Roaders.

    ReplyDelete