The AdvancedTree component allows for any of its skins or icons to be overridden with either symbols in your FLA's Library or through external classes that extend MovieClip. What follows is a step by step for replacing the skins in the tree using ActionScript class files. See Creating Library Skins and Icons for using Library symbols for replacing skins.
All skins and icons must extend MovieClip. For resizable skins, you can either draw your graphics and create a scale9Grid to define how it should be resized, or you can implement a setSize(width:Number, height:Number) to redraw your graphic when the size changes. Any skins that need to define states, like the scroll slider, scroll buttons or selection highlight, should implement a changeState(state:String) method to draw a different state. State names include "_Up", "_Over" and "_Down". Icons with multiple graphics must override MovieClip's gotoAndStop() method and use that to draw each specific graphic. For the open/close and branch icons, graphics include "open" and "closed". The vertical scroll arrow icon needs "up" and "down" graphics. The horizontal scroll arrow icon needs "left" and "right" graphics. All other non-state icons (the leaf, an empty branch) don't need to override gotoAndStop().
The following describes the steps for replacing skins using ActionScript classes. The example, classSkins.fla, can be found in the samples downloaded with the component. These steps create the same result as that found in librarySkins.fla and with the Creating Library Skins and Icons tutorial, so the steps below just show the classes needed to implement the same result.
package {
import flash.display.MovieClip;
public class Invisible extends MovieClip {
public function Invisible() {}
}
}
The class extends MovieClip, but does not draw anything.
package {
import flash.display.MovieClip;
import flash.geom.Rectangle;
public class RoundedRect extends MovieClip {
public function RoundedRect() {
graphics.clear();
graphics.beginFill(0x521D1D);
graphics.drawRoundRect(0, 0, 100, 100, 5, 5);
graphics.endFill();
scale9Grid = new Rectangle(10, 10, 80, 80);
}
}
}
This creates a rounded rectangle that can be resized (because of the scale9Grid). This is all that is needed for a resizable skin with no states.
package {
import flash.display.GradientType;
import flash.display.MovieClip;
import flash.geom.Matrix;
public class GradientRoundedRect extends MovieClip {
private var _state:String;
private var _width:Number;
private var _height:Number;
public function GradientRoundedRect() {
_width = 10;
_height = 10;
}
private function redraw():void {
graphics.clear();
drawBorder();
drawFace();
}
private function drawBorder():void {
graphics.beginFill(0x521D1D);
graphics.drawRoundRect(0, 0, _width, _height, 5, 5);
graphics.endFill();
}
private function drawFace():void {
var colors:Array;
switch (_state) {
case "_Over":
colors = [0xD49696, 0xC47575];
break;
case "_Down":
colors = [0x7F2C2C, 0x944E4E];
break;
default:
colors = [0x944E4E, 0x7F2C2C];
}
var matrix:Matrix = new Matrix();
matrix.createGradientBox(_width, _height, Math.PI/2, 2, 2);
graphics.beginGradientFill(GradientType.LINEAR, colors, [1, 1], [0, 255], matrix);
graphics.drawRoundRect(2, 2, _width-4, _height-4, 5, 5);
graphics.endFill();
}
public function setSize(width:Number, height:Number):void {
_width = width;
_height = height;
redraw();
}
public function changeState(state:String):void {
_state = state;
redraw();
}
}
}
In this class, both the changeState() and setSize(), after changing properties of the class, call a redraw method which redraws both the border and the face. In the drawFace() method, the colors to use are determined by the current state. This skin will now respond to mouse over and down events in addition to its default up state.
package {
import flash.display.MovieClip;
import flash.display.Shape;
public class VerticalScrollArrow extends MovieClip {
private var _hit:Shape;
public function VerticalScrollArrow() {
_hit = new Shape();
_hit.graphics.beginFill(0, 0);
_hit.graphics.drawRect(0, 0, 7, 4);
_hit.graphics.endFill();
addChild(_hit);
}
override public function gotoAndStop(frame:Object, scene:String=null):void {
graphics.clear();
graphics.beginFill(0);
if (frame == "up") {
graphics.moveTo(3.5, 0);
graphics.lineTo(7, 4);
graphics.lineTo(0, 4);
graphics.lineTo(3.5, 0);
} else if (frame == "down") {
graphics.lineTo(7, 0);
graphics.lineTo(3.5, 4);
graphics.lineTo(0, 0);
}
graphics.endFill();
}
}
}
The first thing that is done is that a transparent rectangle is created in the constructor. This MUST be done in order for the tree to be able to center the icon based on its dimensions (if no graphics are drawn, then the icon will be seen to have 0 width and 0 height). In the gotoAndStop() override, either an up arrow or a down arrow is drawn.
package {
import flash.display.MovieClip;
import flash.display.Shape;
public class HorizontalScrollArrow extends MovieClip {
private var _hit:Shape;
public function HorizontalScrollArrow() {
_hit = new Shape();
_hit.graphics.beginFill(0, 0);
_hit.graphics.drawRect(0, 0, 4, 7);
_hit.graphics.endFill();
addChild(_hit);
}
override public function gotoAndStop(frame:Object, scene:String=null):void {
graphics.clear();
graphics.beginFill(0);
if (frame == "left") {
graphics.moveTo(0, 3.5);
graphics.lineTo(4, 0);
graphics.lineTo(4, 7);
graphics.lineTo(0, 3.5);
} else if (frame == "right") {
graphics.lineTo(4, 3.5);
graphics.lineTo(0, 7);
graphics.lineTo(0, 0);
}
graphics.endFill();
}
}
}
package {
import flash.display.MovieClip;
import flash.display.Shape;
public class OpenCloseIcon extends MovieClip {
private var _rect:Shape;
private var _icon:Shape;
public function OpenCloseIcon() {
_rect = new Shape();
_rect.graphics.beginFill(0);
_rect.graphics.drawRect(0, 0, 11, 11);
_rect.graphics.endFill();
_rect.graphics.beginFill(0xD8AFAF);
_rect.graphics.drawRect(1, 1, 9, 9);
_rect.graphics.endFill();
addChild(_rect);
_icon = new Shape();
addChild(_icon);
gotoAndStop("closed");
}
override public function gotoAndStop(frame:Object, scene:String=null):void {
_icon.graphics.clear();
_icon.graphics.beginFill(0);
_icon.graphics.drawRect(3, 5, 5, 1);
_icon.graphics.endFill();
if (frame == "closed") {
_icon.graphics.beginFill(0);
_icon.graphics.drawRect(5, 3, 1, 5);
_icon.graphics.endFill();
}
}
}
}
This is only slightly more complex in that a rectangle with border and fill is first drawn in the constructor as opposed to the transparent rectangle. These are graphics that will remain constant in the icon. The gotoAndStop() override draws the proper plus or minus icon.
import com.flashloaded.ui.tree.graphic.TreeSkins;
import com.flashloaded.ui.tree.graphic.TreeStyles;
tree.setSkin(TreeSkins.LEAF_GRAPHIC, Invisible);
tree.setSkin(TreeSkins.BRANCH_GRAPHIC, Invisible);
tree.setSkin(TreeSkins.HORIZONTAL_SCROLL_WELL_GRAPHIC, RoundedRect);
tree.setSkin(TreeSkins.VERTICAL_SCROLL_WELL_GRAPHIC, RoundedRect);
tree.setSkin(TreeSkins.HORIZONTAL_SCROLL_BACK_GRAPHIC, RoundedRect);
tree.setSkin(TreeSkins.VERTICAL_SCROLL_BACK_GRAPHIC, RoundedRect);
tree.setSkin(TreeSkins.INNER_BACK_GRAPHIC, GradientRoundedRect);
tree.setSkin(TreeSkins.OUTER_BACK_GRAPHIC, GradientRoundedRect);
tree.setSkin(TreeSkins.HORIZONTAL_SCROLL_BUTTON_GRAPHIC, GradientRoundedRect);
tree.setSkin(TreeSkins.VERTICAL_SCROLL_BUTTON_GRAPHIC, GradientRoundedRect);
tree.setSkin(TreeSkins.HORIZONTAL_SCROLL_SLIDER_GRAPHIC, GradientRoundedRect);
tree.setSkin(TreeSkins.VERTICAL_SCROLL_SLIDER_GRAPHIC, GradientRoundedRect);
tree.setSkin(TreeSkins.HORIZONTAL_SCROLL_ARROW_GRAPHIC, HorizontalScrollArrow);
tree.setSkin(TreeSkins.VERTICAL_SCROLL_ARROW_GRAPHIC, VerticalScrollArrow);
tree.setSkin(TreeSkins.OPEN_CLOSE_GRAPHIC, OpenCloseIcon);
tree.setStyleProperty(TreeStyles.ICON, 0xFFFFFF);
tree.setStyleProperty(TreeStyles.ROLLOVER_ICON, 0x000000);
tree.setStyleProperty(TreeStyles.SELECTED_ICON, 0xFFFFFF);
tree.setStyleProperty(TreeStyles.TEXT_COLOR, 0xFFFFFF);
tree.setStyleProperty(TreeStyles.HIGHLIGHT_TEXT_COLOR, 0x000000);
tree.setStyleProperty(TreeStyles.SELECTED_HIGHLIGHT, 0x521D1D);
tree.setStyleProperty(TreeStyles.ROLLOVER_HIGHLIGHT, 0xD8AFAF);
tree.setStyleProperty(TreeStyles.CONNECTOR_LINE_COLOR, 0x000000);
For a full list of skins that can be set, see TreeSkins class. Styles can be found in TreeStyles class. If you publish your movie now, you will see the new skins applied.