Checking if an element is included in the current state in Flex 4

Checking if an element is included or excluded from the current state is a little more involved than just checking the visible property. This post demonstrates a method that returns true when the element is included in the current state.

Since the new “includeIn” states syntax in Flex 4 adds the element to the DisplayList when in that state and removes it for all other states, just checking the visible property of an element won’t be sufficient for checking if the element is actually in view. For example an element can have visible=true but not be shown since it isn’t on the DisplayList.

This method will return true if the element is included in the current state or false if it is excluded.

public function elementIsIncluded(e:IVisualElement):Boolean {
 
    // the element hasn't been instantiated yet so it isn't included
    if (!e)
        return false;
 
    // the element doesn't have a parent so it isn't included
    if (!e.parent)
        return false;
 
    // the element has been instantiated and has a parent, so it might be 
    // included if its DisplayObject has a non-null stage
 
    if (e is GraphicElement){
        var g:GraphicElement = e as GraphicElement;
        if (g.displayObject.stage){
            return true;
        }
    }
 
    if (e is DisplayObject){ 
        var d:DisplayObject = e as DisplayObject;
        if (d.stage){
            return true;
        }
    }
 
    return false;
}

You can test this method with this simple application:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark">
 
    <fx:Script>
        <![CDATA[
            import mx.core.IVisualElement;
            import spark.primitives.supportClasses.GraphicElement;
 
            private function test():void {
                trace('outer: ',elementIsIncluded(outer),'expected: true'); 
                trace('rect1: ',elementIsIncluded(rect1),'expected: false');
                trace('inner: ',elementIsIncluded(inner),'expected: false');
                trace('rect2: ',elementIsIncluded(rect2),'expected: false');
                trace('rect3: ',elementIsIncluded(rect3),'expected: false');
                trace('btn:   ',elementIsIncluded(btn),'expected: false'); 
            }
 
            /**
             * This method can be used to tell if a given element is currently included.
             * 
             * Returns true if the element is included in the current state
             */
            public function elementIsIncluded(e:IVisualElement):Boolean {
 
                // the element hasn't been instantiated yet so it isn't included
                if (!e)
                    return false;
 
                // the element doesn't have a parent so it isn't included
                if (!e.parent)
                    return false;
 
                // the element has been instantiated and has a parent, so it might be 
                // included if its DisplayObject has a non-null stage
 
                if (e is GraphicElement){
                    var g:GraphicElement = e as GraphicElement;
                    if (g.displayObject.stage){
                        return true;
                    }
                }
 
                if (e is DisplayObject){ 
                    var d:DisplayObject = e as DisplayObject;
                    if (d.stage){
                        return true;
                    }
                }
 
                return false;
            }
        ]]>
    </fx:Script>
 
    <s:controlBarContent>
        <s:Button label="toggle state" click="currentState=currentState=='state1'?'state2':'state1'" />
        <s:Button label="trace" click="test()" />
        <s:Label text="Instructions: Click 'toggle state' twice, then click 'trace'" />
    </s:controlBarContent>
 
    <s:states>
        <s:State name="state1" />
        <s:State name="state2" />
    </s:states>
 
    <s:HGroup id="outer">
        <s:Rect id="rect1" width="50" height="50" includeIn="state2"><s:fill><s:SolidColor color="red" /></s:fill></s:Rect>
 
        <s:Group id="inner" includeIn="state2">
            <s:Rect id="rect2" width="50" height="50"><s:fill><s:SolidColor color="blue" /></s:fill></s:Rect>
        </s:Group>
 
        <s:Rect id="rect3" includeIn="state2" width="50" height="50" rotation="45"><s:fill><s:SolidColor color="green" /></s:fill></s:Rect>
 
        <s:Button id="btn" label="btn" includeIn="state2" />
    </s:HGroup>
 
</s:Application>

The output of this application will be:

outer: true expected: true
rect1: false expected: false
inner: false expected: false
rect2: false expected: false
rect3: false expected: false
btn: false expected: false

This method handles the case where an element has it’s own DisplayObject (rect3) or if it is sharing with its parent (rect1).

Note: I came across SDK-26236 while writing this method.

One thought on “Checking if an element is included in the current state in Flex 4”

  1. Thank you. Although I was looking for some built in boolean variable for controls. It is kind of stupid to not have any to detect whether a control in included in current state or not.

Comments are closed.