flex spaghetti

Just another WordPress.com weblog

Archive for the ‘States’ Category

Creating states in a skin

Posted by rvollmar on June 21, 2009

You may want to change the attributes of a component’s skin depending on the state the component is in. In this case, we’re going to make a skin for the Application class which changes its background depending on the state it’s in:

happy: yellow background
sad: blue background
sophisticated: various shades of grey
bland: white background

1. Copy frameworks/projects/flex4/src/spark/skins/spark/ApplicationSkin.mxml to the directory you’re working in and rename it. I’m calling it SkinWithStates.mxml.

2a. Find the states section and add some states.
2b. Find the backgroundRect and make its fill stateful. Also, add a couple more Rects for the sophisticated state. Note that the subsequent Rects have left/right/top/bottom set to increasing numbers, so they will appear nested. Here is how the skin file should look when it’s done:

<?xml version="1.0" encoding="utf-8"?>

<!--- The default skin class for the Spark Application component. 
        
      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    alpha.disabled="0.5" >

    <fx:Metadata>
    <![CDATA[ 
        [HostComponent("spark.components.Application")]
    ]]>
    </fx:Metadata> 
    
    <s:states>
     <s:State name="normal" />
     <s:State name="disabled" />
        <s:State name="sad" />
        <s:State name="happy" />
        <s:State name="sophisticated" />
        <s:State name="bland" />
    </s:states>
    
    <s:Rect id="backgroundRect" 
        left="0" right="0" 
        top="0" bottom="0">
        <s:fill>
            <s:SolidColor color.sad="0x0000ff"
                          color.happy="0xffff00"
                          color.sophisticated="0x000000"
                          color.bland="0xffffff" />
        </s:fill>
    </s:Rect>
    
    <s:Rect id="backgroundRect2"
        left="20" right="20"
        top="20" bottom="20">
        <s:fill>
            <s:SolidColor color.sad="0x0000ff"
                          color.happy="0xffff00"
                          color.sophisticated="0x444444"
                          color.bland="0xffffff" />
        </s:fill>
    </s:Rect>

    <s:Rect id="backgroundRect3"
        left="40" right="40"
        top="40" bottom="40">
        <s:fill>
            <s:SolidColor color.sad="0x0000ff"
                          color.happy="0xffff00"
                          color.sophisticated="0x888888"
                          color.bland="0xffffff" />
        </s:fill>
    </s:Rect>
        
    <s:Group id="contentGroup" left="0" right="0"
    top="0" bottom="0"
    minWidth="0" minHeight="0"/>

</s:Skin>

3. Override the getCurrentSkinState() method in a subclass of Application. This method should do whatever analysis is needed to figure out what state the skin should be in, and return a string containing that state’s name. Here is an example which just returns the mood, which is the name of a state. Save it as TestApplication.as:

package{

    import spark.components.Application;

    public class TestApplication extends Application{
    
        public var mood:String;

        // Constructor.
        public function TestApplication():void{
            mood = "bland";
        }
    
        // Return the state the skin should be in.
        override protected function getCurrentSkinState():String{
            return mood;
        }   
    }
}

4. Make a main application file which uses the subclass and the skin just created:

<?xml version="1.0" encoding="utf-8"?>
<custom:TestApplication 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/halo" 
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:custom="*"
    skinClass="SkinWithStates" >

<fx:Script>
<![CDATA[

    private function doMoodChange(e:Event):void{
        this.mood = e.currentTarget.selectedValue;
        
        // This causes the skin's state to
        // be evaluated again.
        invalidateSkinState();
    }

]]>
</fx:Script>

<fx:Declarations>
    <s:RadioButtonGroup id="group1" 
        itemClick="doMoodChange(event)" />
</fx:Declarations>

<s:Group x="50" y="50">
    <s:layout>
        <s:VerticalLayout />
    </s:layout>

    <s:SimpleText text="Choose Mood:" />
    
    <s:RadioButton id="rbHappy" 
                   groupName="group1" 
                   label="happy" value="happy" /> 
    <s:RadioButton id="rbSad" 
                   groupName="group1" 
                   label="sad" value="sad" /> 
    <s:RadioButton id="rbSophisticated" 
                   groupName="group1" 
                   label="sophisticated" 
                   value="sophisticated" /> 
    <s:RadioButton id="rbBland" 
                   groupName="group1" 
                   label="bland" 
                   value="bland" 
                   selected="true" /> 
</s:Group>

</custom:TestApplication>

Advertisements

Posted in Application, Skins, States | Leave a Comment »