Removing the border from the Halo Tree control in Flex 4

The following example shows how you can remove or modify the border on the Halo Tree control (with default Spark skin) in Flex 4 by setting the borderSkin style.

Full code after the jump.

The following example(s) require Flash Player 10 and the Adobe Flex 4 SDK. To download the Adobe Flash Builder 4 trial, see www.adobe.com/products/flex/. To download the latest nightly build of the Flex 4 SDK, see opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4.

For more information on getting started with Flex 4 and Flash Builder 4, see the official Adobe Flex Team blog.

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/08/28/removing-the-border-from-the-halo-tree-control-in-flex-4/ -->
<s:Application name="Halo_Tree_borderSkin_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo">
 
    <mx:Tree id="tree1"
            labelField="@label"
            showRoot="true"
            borderSkin="{null}"
            width="160"
            horizontalCenter="0" verticalCenter="0">
        <mx:XMLListCollection id="MailBox">
            <fx:XMLList>
                <folder label="Mail">
                    <folder label="INBOX"/>
                    <folder label="Personal Folder">
                        <Pfolder label="Business" />
                        <Pfolder label="Demo" />
                        <Pfolder label="Personal" isBranch="true" />
                        <Pfolder label="Saved Mail" />
                    </folder>
                    <folder label="Sent" />
                    <folder label="Trash" />
                </folder>
            </fx:XMLList>
        </mx:XMLListCollection>
    </mx:Tree>
 
</s:Application>

View source is enabled in the following example.

[GoogleAdsWide]

Or, you can modify the Halo Tree border skin, as seen in the following example:

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/08/28/removing-the-border-from-the-halo-tree-control-in-flex-4/ -->
<s:Application name="Halo_Tree_borderSkin_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo"
        backgroundColor="red">
 
    <mx:Tree id="tree1"
            labelField="@label"
            showRoot="true"
            borderSkin="skins.CustomBorderSkin"
            width="160"
            horizontalCenter="0" verticalCenter="0">
        <mx:XMLListCollection id="MailBox">
            <fx:XMLList>
                <folder label="Mail">
                    <folder label="INBOX"/>
                    <folder label="Personal Folder">
                        <Pfolder label="Business" />
                        <Pfolder label="Demo" />
                        <Pfolder label="Personal" isBranch="true" />
                        <Pfolder label="Saved Mail" />
                    </folder>
                    <folder label="Sent" />
                    <folder label="Trash" />
                </folder>
            </fx:XMLList>
        </mx:XMLListCollection>
    </mx:Tree>
 
</s:Application>

And the custom border skin, skins/CustomBorderSkin.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2009/08/28/removing-the-border-from-the-halo-tree-control-in-flex-4/ -->
<local:SparkSkinForHalo name="CustomBorderSkin"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:local="mx.skins.spark.*"
        implements="mx.core.IRectangularBorder">
 
    <fx:Script>
        <![CDATA[
        import mx.core.EdgeMetrics;
        import mx.core.IUIComponent;
        import mx.graphics.RectangularDropShadow;
 
        /* Define the skin elements that should not be colorized. */
        static private const exclusions:Array = ["background"];
        override public function get colorizeExclusions():Array {
            return exclusions;
        }
 
        /* 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;
        }
 
        /* Define the border item. */
        static private const borderItem:Array = [];
        override protected function get borderItems():Array {
            return borderItem;
        }
        override protected function get defaultBorderItemColor():uint {
            return 0x696969;
        }
 
        static private const metrics:EdgeMetrics = new EdgeMetrics(1, 1, 1, 1);
 
        private var dropShadow:RectangularDropShadow;
 
        public function get borderMetrics():EdgeMetrics {
            return metrics;
        }
 
        public function get backgroundImageBounds():Rectangle {
            return null;
        }
 
        public function set backgroundImageBounds(value:Rectangle):void {
        }
 
        public function get hasBackgroundImage():Boolean {
            return false;
        }
 
        public function layoutBackgroundImage():void {
        }
 
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
            graphics.clear();
 
            super.updateDisplayList(unscaledWidth, unscaledHeight);
 
            if (parent && parent is IUIComponent && !IUIComponent(parent).enabled)
                alpha = 0.5;
            else
                alpha = 1;
 
            // Draw drop shadow, if needed
            if (getStyle("dropShadowEnabled") == false ||
                getStyle("dropShadowEnabled") == "false" ||
                width == 0 ||
                height == 0) {
                return;
            }
 
            // Create a RectangularDropShadow object, set its properties,
            // and draw the shadow
            if (!dropShadow)
                dropShadow = new RectangularDropShadow();
 
            dropShadow.distance = 5;
            dropShadow.angle = 90;
            dropShadow.color = 0;
            dropShadow.alpha = 0.8;
            dropShadow.blurX = 20;
            dropShadow.blurY = 20;
 
            dropShadow.drawShadow(graphics, x, y, width, height);
        }
 
        private function getDropShadowAngle(distance:Number, direction:String):Number {
            if (direction == "left") {
                return distance >= 0 ? 135 : 225;
            } else if (direction == "right") {
                return distance >= 0 ? 45 : 315;
            } else { // direction == "center"
                return distance >= 0 ? 90 : 270;
            }
        }
        ]]>
    </fx:Script>
 
    <s:Group left="0" right="0" top="0" bottom="0">
        <!-- 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>
    </s:Group>
 
</local:SparkSkinForHalo>

[HaloSparkSkins]

You can also set the borderSkin style in an external .CSS file or <Style/> block, as seen in the following example:

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/08/28/removing-the-border-from-the-halo-tree-control-in-flex-4/ -->
<s:Application name="Halo_Tree_borderSkin_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo">
 
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/halo";
 
        mx|Tree {
            /* borderSkin: ClassReference(null); */
            borderSkin: ClassReference("skins.CustomBorderSkin");
        }
    </fx:Style>
 
    <mx:Tree id="tree1"
            labelField="@label"
            showRoot="true"
            width="160"
            horizontalCenter="0" verticalCenter="0">
        <mx:XMLListCollection id="MailBox">
            <fx:XMLList>
                <folder label="Mail">
                    <folder label="INBOX"/>
                    <folder label="Personal Folder">
                        <Pfolder label="Business" />
                        <Pfolder label="Demo" />
                        <Pfolder label="Personal" isBranch="true" />
                        <Pfolder label="Saved Mail" />
                    </folder>
                    <folder label="Sent" />
                    <folder label="Trash" />
                </folder>
            </fx:XMLList>
        </mx:XMLListCollection>
    </mx:Tree>
 
</s:Application>

Or, you can set the borderSkin style using ActionScript, as seen in the following example:

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/08/28/removing-the-border-from-the-halo-tree-control-in-flex-4/ -->
<s:Application name="Halo_Tree_borderSkin_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo">
 
    <fx:Script>
        <![CDATA[
            import skins.CustomBorderSkin;
 
            protected function btn_click(evt:MouseEvent):void {
                tree1.setStyle("borderSkin", CustomBorderSkin);
            }
        ]]>
    </fx:Script>
 
    <s:Button id="btn"
            label="Set Tree border skin"
            click="btn_click(event);"
            left="10" top="10" />
 
    <mx:Tree id="tree1"
            labelField="@label"
            showRoot="true"
            width="160"
            horizontalCenter="0" verticalCenter="0">
        <mx:XMLListCollection id="MailBox">
            <fx:XMLList>
                <folder label="Mail">
                    <folder label="INBOX"/>
                    <folder label="Personal Folder">
                        <Pfolder label="Business" />
                        <Pfolder label="Demo" />
                        <Pfolder label="Personal" isBranch="true" />
                        <Pfolder label="Saved Mail" />
                    </folder>
                    <folder label="Sent" />
                    <folder label="Trash" />
                </folder>
            </fx:XMLList>
        </mx:XMLListCollection>
    </mx:Tree>
 
</s:Application>

This entry is based on a beta version of the Flex 4 SDK and therefore is very likely to change as development of the Flex SDK continues. The API can (and will) change causing examples to possibly not compile in newer versions of the Flex 4 SDK.

3 thoughts on “Removing the border from the Halo Tree control in Flex 4

    1. @Aidan Mack,

      Ah, it’s a bit tricky. The main issue is that you’re comparing a Flex 3 example to a Flex 4 example, and the subtle difference is that the mx:Tree in Flex 4 sets the openDuration style to 0 milliseconds, whereas in Flex 3 the openDuration style was 250 milliseconds. You can add the following code to the application to verify:

      <mx:Button id="btn" click="btn.label = tree1.getStyle('openDuration');" />

      If you want to add the easing animation back in Flex 4, simply set the openDuration style to 250 milliseconds (or whatever you want) using the following snippet:

      <mx:Tree id="tree1"
              openDuration="250"
              labelField="@label"
              showRoot="true">
          <mx:XMLListCollection id="MailBox">
              <fx:XMLList>
                  <!-- nodes go here -->
              </fx:XMLList>
          </mx:XMLListCollection>
      </mx:Tree>

      Or you can change the openDuration for all mx:Tree controls in your Flex 4 application using a Style block, as seen in the following snippet:

      <fx:Style>
          @namespace s "library://ns.adobe.com/flex/spark";
          @namespace mx "library://ns.adobe.com/flex/mx";
       
          mx|Tree {
              openDuration: 250;
          }
      </fx:Style>

      Peter

  1. Superb, thanks for that Peter,
    Works a treat. I also noticed last night that if I change the theme to something other than “spark” then the tween starts to work.
    But I will use the above code as suggested.

    Cracking blog by the way! Its an absolute fountain of knowledge you have built here!

    Tar
    Aidan

Comments are closed.