Skip to main content
April 6, 2009
Question

Styling skinnable components

  • April 6, 2009
  • 1 reply
  • 1186 views

                                   

I have analyzed Spark components code recently and have come to the point that there is something missing. We are developing two really great mechanisms Skinning and Advanced Styling but they don’t work together as they should. I can’t see a clear line between visual aspects controlled by styles and by skins. And I really don’t like SparkSkin with ActionScript code in MXML Skin files (hope it is a temporary sollytion).

I think we should think together and find a flexible solution which will allow us to take advantages of both Advanced Styling and Skinning.

I have identified a number of requirements which this solution should fulfill:

-        Styles should be used completely declaratively inside skin.

-        It should be easy to add new style to a component (without modification to skin base class).

-        One should be able to create skin ignoring styles (it is obvious that creating stylable skin will be more complicated than hardcode values inside skin).

-        The solution should support tooling (During visual modification of the skin one should be able to choose between hardcodding a value, let say color, into MXML skin, create new CSS selector or choosing to inherit value from other selector).

-        Finally the solution shouldn’t impact performance.

If you have any draft solutions could you please share it?

I don’t have a complete way out but I have a few ideas how styling and skinning integration could look from application developer point of view.

Currently we have:

SparkSkin code with hardcoded style names

+

    <fx:Script> 

        /* Define the content fill items that should be colored by the "contentBackgroundColor" style. */

        static private const contentFill:Array = ["bgFill"];

        override public function get contentItems():Array {return contentFill};

    </fx:Script>

+

    <!-- fill -->

    <s:Rect id="background" left="1" right="1" top="1" bottom="1" >

      <s:fill>

            <s:SolidColor id="bgFill" color="0xFFFFFF" />

      </s:fill>

    </s:Rect>

All this stuff to say that background should be filled with the color defined in CSS as “contentBackgroundColor”.

I think it would be much nicer to have mechanism to reach the same goal with something like:

    <!-- fill -->

    <s:Rect id="background" left="1" right="1" top="1" bottom="1" >

      <s:fill>

            <s:SolidColor id="bgFill" color="{hostComponent.styleValues.contentBackgroundColor}" />

      </s:fill>

    </s:Rect>

Where „contentBackgroundColor” could be any style declared on hostComponent. That way it would be easy to add new style to custom component without overriding SparkSkin.

Of course we doesn’t have to use “expensive” DataBinding, we may think of dedicated mechanism for applying styles to the skin like

    <!-- fill -->

    <s:Rect id="background" left="1" right="1" top="1" bottom="1" >

      <s:fill>

            <s:SolidColor id="bgFill" color="@StyleValue(contentBackgroundColor)" />

      </s:fill>

    </s:Rect>

What do you think about such approach?

Iwo Banas

This topic has been closed for replies.

1 reply

April 7, 2009

Hi Iwo. A great suggestion, and one that we considered (if you look at my original presentation on the Spark ideas from a year and a half ago, I think I had similar syntax in there).  It's not in the current flex 4 plans, mostly for scheduling reasons.  The good news is that it can be added incrementally in a future release without any backwards compatibility issues.

Ely.

Adobe Employee
April 7, 2009

Hi Iwo,

I'll just add to Ely's post to explain a bit about why we use ActionScript in our Spark skins.

Not all of our styles are implemented as simple mappings between style values and fill/stroke parameters. For example, the "baseColor" style is a color that becomes the basis for a computed colorTransform object. This transformation cannot be done with simple binding.

Some of the items in a skin need to be excluded from the baseColor transformation. Typically, these are items that are styled by some other means (ie text, content background, etc.). Our options here were either add an "exclude from baseColor transformation" property to all objects, or write a snippet of ActionScript code that returned the excluded objects.

Look at the SparkSkin class for details on how these are handled.

We opted to use code for the simple mappings due to concerns about the performance/memory impact of having a bunch of bindings in every skin.

Glenn