Home > Flex 4 > Spark equivalent of DisplayObjectContainer.contains()

Spark equivalent of DisplayObjectContainer.contains()

In halo containers you could use the DisplayObjectContainer.contains() method to check if an element is a child, grandchild, great grandchild, … of a given container. This method might not always work as you expect when called on a spark container because not every element in a spark container is a DisplayObject.

There is currently no equivalent method for spark containers. There is a feature request to add this method here: SDK-24203. Please vote on that issue if you would like to see it added. In the mean time I threw together a workaround by climbing up the IVisualElement.parent property.

public static function sparkContains(container:IVisualElementContainer, element:IVisualElement):Boolean 
{
    while (element)
    {
        if (element == container)
        {
            return true;
        }
 
        if (element.parent is IVisualElement)
        {
            element = IVisualElement(element.parent);
        }
        else
        {
            return false;
        }
    }
 
    return false;
}

If you want to check if an element is a direct child of a container (and not a grandchild, great grandchild, etc.) then you can compare the parent/owner property of the element to the container:

public static function simpleContainment(container:IVisualElementContainer, element:IVisualElement):Boolean {
    return (element.owner == container);
}

Check out this blog post for more on the differences between parent and owner.

Here is a sample application that has a couple (simple) tests for these methods:

<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    creationComplete="runTest()">
 
    <fx:Script>
        <![CDATA[
            import mx.core.IVisualElement;
            import mx.core.IVisualElementContainer;
 
            public function runTest():void 
            {
                // compare sparkContains() to contains()
                trace(sparkContains(sc1, sc2), hc1.contains(hc2), 'expecting true');
                trace(sparkContains(sc1, sc3), hc1.contains(hc3), 'expecting true');
                trace(sparkContains(sc1, sc4), hc1.contains(hc4), 'expecting true');
                trace(sparkContains(sc1, sc1), hc1.contains(hc1), 'expecting true');
                trace(sparkContains(sc2, sc1), hc2.contains(hc1), 'expecting false');
 
                // test simpleContainment
                trace(simpleContainment(sc1, sc2), 'expecting true');
                trace(simpleContainment(sc3, sc1), 'expecting false');
            }
 
            public static function simpleContainment(container:IVisualElementContainer, element:IVisualElement):Boolean {
                return (element.owner == container);
            }
 
            public static function sparkContains(container:IVisualElementContainer, element:IVisualElement):Boolean 
            {
                while (element)
                {
                    if (element == container)
                    {
                        return true
                    }
 
                    if (element.parent is IVisualElement)
                    {
                        element = IVisualElement(element.parent);
                    }
                    else
                    {
                        return false;
                    }
                }
 
                return false;
            }
        ]]>
    </fx:Script>
 
    <s:Group id="sc1">
        <s:Group id="sc2">
            <s:Group id="sc3">
                <s:Rect id="sc4" />
            </s:Group>
        </s:Group>
    </s:Group>
 
    <mx:Canvas id="hc1">
        <mx:Canvas id="hc2">
            <mx:Canvas id="hc3">
                <mx:Button id="hc4" />
            </mx:Canvas>
        </mx:Canvas>
    </mx:Canvas>
 
</s:Application>

Note: This sample requires Flex SDK 4.0.0.12093 or higher. You can get the latest SDK builds from opensource.adobe.com.

  1. December 1st, 2009 at 06:22 | #1

    “because not every child of a spark container is a DisplayObject.”

    That line could be a little confusing for people. If its a child it has to be a DisplayObject. You talking specifically about visual elements, which cannot be a child, the child is its owner, where the info stored inside the element is actually drawn and displayed.

    I agree though that the API for elements seems somewhat incomplete due to an extremely easy method that could be implements by Adobe.

  2. Steven Shongrunden
    December 1st, 2009 at 23:30 | #2

    @Tink – You’re right that was poorly worded. I updated it to read “because not every element in a spark container is a DisplayObject”. Thanks for pointing that out. One of these days I’ll get around to writing a post on an explanation of DisplayObject sharing in spark containers.

  3. Ali
    December 4th, 2009 at 03:17 | #3

    Thx for the Tip :)

  1. No trackbacks yet.