You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by al...@apache.org on 2018/05/11 14:13:33 UTC
[royale-asjs] branch feature/MXRoyale updated: Tree.as Added
This is an automated email from the ASF dual-hosted git repository.
alinakazi pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/feature/MXRoyale by this push:
new e13cd97 Tree.as Added
e13cd97 is described below
commit e13cd978a57ff715aefd4d0f56bd8a3d6b4d6bf9
Author: alinakazi <AL...@GMAIL.COM>
AuthorDate: Fri May 11 07:13:30 2018 -0700
Tree.as Added
---
.../MXRoyale/src/main/royale/mx/controls/Tree.as | 3690 ++++++++++++++++++++
1 file changed, 3690 insertions(+)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as
new file mode 100644
index 0000000..9a52233
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/Tree.as
@@ -0,0 +1,3690 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.controls
+{
+
+/* import flash.display.DisplayObject;
+import flash.display.Graphics;
+import flash.display.Shape;
+import flash.display.Sprite;
+import flash.events.Event;
+import flash.events.KeyboardEvent;
+import flash.events.MouseEvent;
+import flash.geom.Point;
+import flash.geom.Rectangle;
+import flash.ui.Keyboard;
+import flash.utils.clearInterval;
+import flash.utils.getTimer;
+import flash.xml.XMLNode; */
+//import mx.collections.ArrayCollection;
+import mx.collections.CursorBookmark;
+import mx.collections.ICollectionView;
+//import mx.collections.ItemResponder;
+import mx.collections.IViewCursor;
+import mx.collections.XMLListCollection;
+//import mx.collections.errors.ItemPendingError;
+import mx.controls.listClasses.BaseListData;
+//import mx.controls.listClasses.IDropInListItemRenderer;
+//import mx.controls.listClasses.IListItemRenderer;
+//import mx.controls.listClasses.ListRowInfo;
+//import mx.controls.listClasses.ListBaseSelectionDataPending;
+//import mx.controls.treeClasses.DefaultDataDescriptor;
+//import mx.controls.treeClasses.HierarchicalCollectionView;
+//import mx.controls.treeClasses.HierarchicalViewCursor;
+import mx.controls.treeClasses.ITreeDataDescriptor;
+//import mx.controls.treeClasses.ITreeDataDescriptor2;
+import mx.controls.treeClasses.TreeItemRenderer;
+import mx.controls.treeClasses.TreeListData;
+import mx.core.ClassFactory;
+import mx.core.EdgeMetrics;
+import mx.core.EventPriority;
+//import mx.core.FlexSprite;
+//import mx.core.FlexShape;
+import mx.core.IDataRenderer;
+import mx.core.IFactory;
+import mx.core.IFlexDisplayObject;
+//import mx.core.IIMESupport;
+import mx.core.IInvalidating;
+import mx.core.UIComponent;
+//import mx.core.UIComponentGlobals;
+import mx.core.mx_internal;
+import mx.effects.Tween;
+import mx.events.CollectionEvent;
+import mx.events.CollectionEventKind;
+//import mx.events.DragEvent;
+import mx.events.FlexEvent;
+import mx.events.ListEvent;
+//import mx.events.ListEventReason;
+import mx.events.ScrollEvent;
+//import mx.events.TreeEvent;
+import mx.managers.DragManager;
+import mx.managers.ISystemManager;
+//import mx.managers.SystemManager;
+
+use namespace mx_internal;
+
+//--------------------------------------
+// Events
+//--------------------------------------
+
+/**
+ * Dispatched when a branch is closed or collapsed.
+ *
+ * @eventType mx.events.TreeEvent.ITEM_CLOSE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Event(name="itemClose", type="mx.events.TreeEvent")]
+
+/**
+ * Dispatched when a branch is opened or expanded.
+ *
+ * @eventType mx.events.TreeEvent.ITEM_OPEN
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Event(name="itemOpen", type="mx.events.TreeEvent")]
+
+/**
+ * Dispatched when a branch open or close is initiated.
+ *
+ * @eventType mx.events.TreeEvent.ITEM_OPENING
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Event(name="itemOpening", type="mx.events.TreeEvent")]
+
+//--------------------------------------
+// Styles
+//--------------------------------------
+
+//include "../styles/metadata/PaddingStyles.as";
+
+/**
+ * Colors for rows in an alternating pattern.
+ * Value can be an Array of two of more colors.
+ * Used only if the <code>backgroundColor</code> property is not specified.
+ *
+ * @default undefined
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="alternatingItemColors", type="Array", arrayType="uint", format="Color", inherit="yes")]
+
+/**
+ * Array of colors used in the Tree control, in descending order.
+ *
+ * @default undefined
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="depthColors", type="Array", arrayType="uint", format="Color", inherit="yes")]
+
+/**
+ * Specifies the default icon for a leaf item.
+ * In MXML, you can use the following syntax to set this property:
+ * <code>defaultLeafIcon="@Embed(source='c.jpg');"</code>
+ *
+ * The default value is the "TreeNodeIcon" symbol in the Assets.swf file.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+[Style(name="defaultLeafIcon", type="Class", format="EmbeddedFile", inherit="no")]
+
+/**
+ * Specifies the icon that is displayed next to a parent item that is open so that its
+ * children are displayed.
+ *
+ * The default value is the "TreeDisclosureOpen" symbol in the Assets.swf file.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="disclosureOpenIcon", type="Class", format="EmbeddedFile", inherit="no")]
+
+/**
+ * Specifies the icon that is displayed next to a parent item that is closed so that its
+ * children are not displayed (the subtree is collapsed).
+ *
+ * The default value is the "TreeDisclosureClosed" symbol in the Assets.swf file.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="disclosureClosedIcon", type="Class", format="EmbeddedFile", inherit="no")]
+
+/**
+ * Specifies the folder open icon for a branch item of the tree.
+ * In MXML, you can use the following syntax to set this property:
+ * <code>folderOpenIcon="@Embed(source='a.jpg');"</code>
+ *
+ * The default value is the "TreeFolderOpen" symbol in the Assets.swf file.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+[Style(name="folderOpenIcon", type="Class", format="EmbeddedFile", inherit="no")]
+
+/**
+ * Specifies the folder closed icon for a branch item of the tree.
+ * In MXML, you can use the following syntax to set this property:
+ * <code>folderClosedIcon="@Embed(source='b.jpg');"</code>
+ *
+ * The default value is the "TreeFolderClosed" symbol in the Assets.swf file.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+[Style(name="folderClosedIcon", type="Class", format="EmbeddedFile", inherit="no")]
+
+/**
+ * Indentation for each tree level, in pixels.
+ *
+ * @default 17
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="indentation", type="Number", inherit="no")]
+
+/**
+ * Length of an open or close transition, in milliseconds.
+ *
+ * The default value for the Halo theme is <code>250</code>.
+ * The default value for the Spark theme is <code>0</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="openDuration", type="Number", format="Time", inherit="no")]
+
+/**
+ * Easing function to control component tweening.
+ *
+ * <p>The default value is <code>undefined</code>.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="openEasingFunction", type="Function", inherit="no")]
+
+/**
+ * Color of the background when the user rolls over the link.
+ *
+ * The default value for the Halo theme is <code>0xB2E1FF</code>.
+ * The default value for the Spark theme is <code>0xCEDBEF</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="rollOverColor", type="uint", format="Color", inherit="yes")]
+
+/**
+ * Color of the background when the user selects the link.
+ *
+ * The default value for the Halo theme is <code>0x7FCEFF</code>.
+ * The default value for the Spark theme is <code>0xA8C6EE</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="selectionColor", type="uint", format="Color", inherit="yes")]
+
+/**
+ * Specifies the disabled color of a list item.
+ *
+ * @default 0xDDDDDD
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="selectionDisabledColor", type="uint", format="Color", inherit="yes")]
+
+/**
+ * Reference to an <code>easingFunction</code> function used for controlling programmatic tweening.
+ *
+ * <p>The default value is <code>undefined</code>.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="selectionEasingFunction", type="Function", inherit="no")]
+
+/**
+ * Color of the text when the user rolls over a row.
+ *
+ * The default value for the Halo theme is <code>0x2B333C</code>.
+ * The default value for the Spark theme is <code>0x000000</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="textRollOverColor", type="uint", format="Color", inherit="yes")]
+
+/**
+ * Color of the text when the user selects a row.
+ *
+ * The default value for the Halo theme is <code>0x2B333C</code>.
+ * The default value for the Spark theme is <code>0x000000</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+//[Style(name="textSelectedColor", type="uint", format="Color", inherit="yes")]
+
+//--------------------------------------
+// Other metadata
+//--------------------------------------
+
+//[AccessibilityClass(implementation="mx.accessibility.TreeAccImpl")]
+
+[DefaultBindingProperty(destination="dataProvider")]
+
+[DefaultProperty("dataProvider")]
+
+[DefaultTriggerEvent("change")]
+
+//[IconFile("Tree.png")]
+
+[RequiresDataBinding(true)]
+
+/**
+ * The Tree control lets a user view hierarchical data arranged as an expandable tree.
+ * Each item in a tree can be a leaf or a branch.
+ * A leaf item is an end point in the tree.
+ * A branch item can contain leaf or branch items, or it can be empty.
+ *
+ * <p>By default, a leaf is represented by a text label next to a file icon.
+ * A branch is represented by a text label next to a folder icon, with a
+ * disclosure triangle that a user can open to expose children.</p>
+ *
+ * <p>The Tree class uses an ITreeDataDescriptor or ITreeDataDescriptor2 object to parse and
+ * manipulate the data provider.
+ * The default tree data descriptor, an object of the DefaultDataDescriptor class,
+ * supports XML and Object classes; an Object class data provider must have all children
+ * in <code>children</code> fields.
+ * </p>
+ *
+ * <p>The Tree control has the following default sizing
+ * characteristics:</p>
+ * <table class="innertable">
+ * <tr>
+ * <th>Characteristic</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>Default size</td>
+ * <td>Wide enough to accommodate the icon, label, and
+ * expansion triangle, if any, of the widest node in the
+ * first 7 displayed (uncollapsed) rows, and seven rows
+ * high, where each row is 20 pixels in height. If a
+ * scroll bar is required, the width of the scroll bar is
+ * not included in the width calculations.</td>
+ * </tr>
+ * <tr>
+ * <td>Minimum size</td>
+ * <td>0 pixels.</td>
+ * </tr>
+ * <tr>
+ * <td>Maximum size</td>
+ * <td>5000 by 5000.</td>
+ * </tr>
+ * </table>
+ *
+ * @mxml
+ * <p>
+ * The <mx:Tree> tag inherits all the tag attributes of its superclass, and
+ * adds the following tag attributes:
+ * </p>
+ * <pre>
+ * <mx:Tree
+ * <b>Properties</b>
+ * dataDescriptor="<i>Instance of DefaultDataDescriptor</i>"
+ * dataProvider="null"
+ * dragMoveEnabled="true|false"
+ * firstVisibleItem="<i>First item in the control</i>"
+ * hasRoot="false|true"
+ * itemIcons="null"
+ * maxHorizontalScrollPosition="0"
+ * openItems="null"
+ * showRoot="true|false"
+ *
+ * <b>Styles</b>
+ * alternatingItemColors="undefined"
+ * backgroundDisabledColor="0xDDDDDD"
+ * defaultLeafIcon="<i>'TreeNodeIcon' symbol in Assets.swf</i>"
+ * depthColors="undefined"
+ * disclosureClosedIcon="<i>'TreeDisclosureClosed' symbol in Assets.swf</i>"
+ * disclosureOpenIcon="<i>'TreeDisclosureOpen' symbol in Assets.swf</i>"
+ * folderClosedIcon="<i>'TreeFolderClosed' symbol in Assets.swf</i>"
+ * folderOpenIcon="<i>'TreeFolderOpen' symbol in Assets.swf</i>"
+ * indentation="17"
+ * openDuration="250"
+ * openEasingFunction="undefined"
+ * paddingLeft="2"
+ * paddingRight="0"
+ * rollOverColor="0xAADEFF"
+ * selectionColor="0x7FCDFE"
+ * selectionDisabledColor="0xDDDDDD"
+ * selectionEasingFunction="undefined"
+ * textRollOverColor="0x2B333C"
+ * textSelectedColor="0x2B333C"
+ *
+ * <b>Events</b>
+ * change="<i>No default</i>"
+ * itemClose="<i>No default</i>"
+ * itemOpen="<i>No default</i>"
+ * itemOpening="<i>No default</i>"
+ * />
+ * </pre>
+ *
+ * @see mx.controls.treeClasses.ITreeDataDescriptor
+ * @see mx.controls.treeClasses.ITreeDataDescriptor2
+ * @see mx.controls.treeClasses.DefaultDataDescriptor
+ *
+ * @includeExample examples/TreeExample.mxml
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ * @royalesuppresspublicvarwarning
+ */
+public class Tree extends List
+{
+//implements IIMESupport
+ // include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ /* private var IS_NEW_ROW_STYLE:Object =
+ {
+ depthColors: true,
+ indentation: true,
+ disclosureOpenIcon: true,
+ disclosureClosedIcon: true,
+ folderOpenIcon: true,
+ folderClosedIcon: true,
+ defaultLeafIcon: true
+ };
+ */
+ //--------------------------------------------------------------------------
+ //
+ // Class mixins
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Placeholder for mixin by TreeAccImpl.
+ */
+ //mx_internal static var createAccessibilityImplementation:Function;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ public function Tree()
+ {
+ super();
+
+ /* itemRenderer = new ClassFactory(TreeItemRenderer);
+ editorXOffset = 12;
+ editorWidthOffset = -12;
+
+ addEventListener(TreeEvent.ITEM_OPENING, expandItemHandler,
+ false, EventPriority.DEFAULT_HANDLER); */
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Item is currently in the process of opening
+ */
+ //private var opening:Boolean;
+
+ /**
+ * @private
+ * The tween object that animates rows
+ */
+ //private var tween:Object;
+
+ /**
+ * @private
+ */
+ //private var maskList:Array;
+
+ /**
+ * @private
+ */
+ //private var _userMaxHorizontalScrollPosition:Number = 0;
+
+ /**
+ * @private
+ */
+ //private var eventPending:Object;
+
+ /**
+ * @private
+ */
+ //private var eventAfterTween:Object;
+
+ /**
+ * @private
+ */
+ //private var oldLength:int = -1;
+
+ /**
+ * @private
+ */
+ //private var expandedItem:Object;
+
+ /**
+ * @private
+ */
+ //private var bSelectedItemRemoved:Boolean = false;
+
+ /**
+ * @private
+ * Used to slow the scrolling down a bit
+ */
+ //private var minScrollInterval:Number = 50;
+
+ /**
+ * @private
+ */
+ //private var rowNameID:Number = 0;
+
+ /**
+ * @private
+ */
+ //private var _editable:Boolean = false;
+
+ /**
+ * @private
+ * Used to block giving focus to editor on focusIn
+ */
+ //private var dontEdit:Boolean = false;
+
+ /**
+ * @private
+ */
+ //private var lastUserInteraction:Event;
+
+ /**
+ * @private
+ * automation delegate access
+ */
+ //mx_internal var _dropData:Object;
+
+ /**
+ * An object that specifies the icons for the items.
+ * Each entry in the object has a field name that is the item UID
+ * and a value that is an an object with the following format:
+ * <pre>
+ * {iconID: <i>Class</i>, iconID2: <i>Class</i>}
+ * </pre>
+ * The <code>iconID</code> field value is the class of the icon for
+ * a closed or leaf item and the <code>iconID2</code> is the class
+ * of the icon for an open item.
+ *
+ * <p>This property is intended to allow initialization of item icons.
+ * Changes to this array after initialization are not detected
+ * automatically.
+ * Use the <code>setItemIcon()</code> method to change icons dynamically.</p>
+ *
+ * @see #setItemIcon()
+ * @default undefined
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ //public var itemIcons:Object;
+
+ /**
+ * @private
+ */
+ //mx_internal var isOpening:Boolean = false;
+
+ /**
+ * @private
+ * used by opening tween
+ * rowIndex is the row below the row that was picked
+ * and is the first one that will actually change
+ */
+ //private var rowIndex:int;
+
+ /**
+ * @private
+ * Number of rows that are or will be tweened
+ */
+ //private var rowsTweened:int;
+
+ /**
+ * @private
+ */
+ //private var rowList:Array;
+
+ /**
+ * @private
+ */
+ //mx_internal var collectionLength:int;
+
+ /**
+ * A hook for accessibility
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ //mx_internal var wrappedCollection:ICollectionView;
+
+ /**
+ * @private
+ */
+ //mx_internal var collectionThrowsIPE:Boolean;
+
+ /**
+ * @private
+ */
+ //private var haveItemIndices:Boolean;
+
+ /**
+ * @private
+ */
+ //private var lastTreeSeekPending:TreeSeekPending;
+
+ /**
+ * @private
+ */
+ //private var bFinishArrowKeySelection:Boolean = false;
+ //private var proposedSelectedItem:Object;
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // dataProvider
+ //----------------------------------
+
+ /**
+ * @private
+ */
+/* private var dataProviderChanged:Boolean = false;
+
+ [Bindable("collectionChange")]
+ [Inspectable(category="Data", defaultValue="null")]
+
+ */
+ /**
+ * An object that contains the data to be displayed.
+ * When you assign a value to this property, the Tree class handles
+ * the source data object as follows:
+ * <p>
+ * <ul><li>A String containing valid XML text is converted to an XMLListCollection.</li>
+ * <li>An XMLNode is converted to an XMLListCollection.</li>
+ * <li>An XMLList is converted to an XMLListCollection.</li>
+ * <li>Any object that implements the ICollectionView interface is cast to
+ * an ICollectionView.</li>
+ * <li>An Array is converted to an ArrayCollection.</li>
+ * <li>Any other type object is wrapped in an Array with the object as its sole
+ * entry.</li></ul>
+ * </p>
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ override public function set dataProvider(value:Object):void
+ {
+ // in all cases save off the original
+ /* if (_rootModel)
+ _rootModel.removeEventListener(
+ CollectionEvent.COLLECTION_CHANGE,
+ collectionChangeHandler);
+
+ // handle strings and xml
+ if (typeof(value)=="string")
+ value = new XML(value);
+ else if (value is XMLNode)
+ value = new XML(XMLNode(value).toString());
+ else if (value is XMLList)
+ value = new XMLListCollection(value as XMLList);
+
+ if (value is XML)
+ {
+ _hasRoot = true;
+ var xl:XMLList = new XMLList();
+ xl += value;
+ _rootModel = new XMLListCollection(xl);
+ }
+ //if already a collection dont make new one
+ else if (value is ICollectionView)
+ {
+ _rootModel = ICollectionView(value);
+ if (_rootModel.length == 1)
+ _hasRoot = true;
+ }
+ else if (value is Array)
+ {
+ _rootModel = new ArrayCollection(value as Array);
+ }
+ //all other types get wrapped in an ArrayCollection
+ else if (value is Object)
+ {
+ _hasRoot = true;
+ // convert to an array containing this one item
+ var tmp:Array = [];
+ tmp.push(value);
+ _rootModel = new ArrayCollection(tmp);
+ }
+ else
+ {
+ _rootModel = new ArrayCollection();
+ }
+ //flag for processing in commitProps
+ dataProviderChanged = true;
+ invalidateProperties(); */
+ }
+
+ /**
+ * @private
+ */
+ override public function get dataProvider():Object
+ {
+ /* if (_rootModel)
+ return _rootModel;
+ */
+ return null;
+ }
+
+ //----------------------------------
+ // maxHorizontalScrollPosition
+ //----------------------------------
+
+ /**
+ * The maximum value for the <code>maxHorizontalScrollPosition</code> property for the Tree control.
+ * Unlike the <code>maxHorizontalScrollPosition</code> property
+ * in the List control, this property is modified by the Tree control as
+ * items open and close and as items in the tree otherwise become
+ * visible or are hidden (for example, by scrolling).
+ *
+ * <p>If you set this property to the widest known item in the dataProvider,
+ * the Tree control modifies it so that even if that widest item
+ * is four levels down in the tree, the user can scroll to see it.
+ * As a result, although you read back the same value for the
+ * <code>maxHorizontalScrollPosition</code> property that you set,
+ * it isn't necessarily the actual value used by the Tree control.</p>
+ *
+ * @default 0
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* override public function get maxHorizontalScrollPosition():Number
+ {
+ return _userMaxHorizontalScrollPosition > 0 ?
+ _userMaxHorizontalScrollPosition :
+ super.maxHorizontalScrollPosition;
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function set maxHorizontalScrollPosition(value:Number):void
+ {
+ _userMaxHorizontalScrollPosition = value;
+ value += getIndent();
+ super.maxHorizontalScrollPosition = value;
+ } */
+
+ //----------------------------------
+ // dragMoveEnabled
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the dragMoveEnabled property.
+ * For Tree only, this initializes to true.
+ */
+ /* private var _dragMoveEnabled:Boolean = true;
+
+ [Inspectable(defaultValue="true")] */
+
+ /**
+ * Indicates that items can be moved instead of just copied
+ * from the Tree control as part of a drag-and-drop operation.
+ *
+ * @default true
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* override public function get dragMoveEnabled():Boolean
+ {
+ return _dragMoveEnabled;
+ }
+ */
+ /**
+ * @private
+ */
+ /* override public function set dragMoveEnabled(value:Boolean):void
+ {
+ _dragMoveEnabled = value;
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // firstVisibleItem
+ //----------------------------------
+
+ //[Bindable("firstVisibleItemChanged")]
+
+ /**
+ * The item that is currently displayed in the top row of the tree.
+ * Based on how the branches have been opened and closed and scrolled,
+ * the top row might hold, for example, the ninth item in the list of
+ * currently viewable items which in turn represents
+ * some great-grandchild of the root.
+ * Setting this property is analogous to setting the verticalScrollPosition of the List control.
+ * If the item isn't currently viewable, for example, because it
+ * is under a nonexpanded item, setting this property has no effect.
+ *
+ * <p>NOTE: In Flex 1.0 this property was typed as XMLNode although it really was
+ * either an XMLNode or TreeNode. In 2.0, it is now the generic type Object and will
+ * return an object of the same type as the data contained in the dataProvider.</p>
+ *
+ * <p>The default value is the first item in the Tree control.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* public function get firstVisibleItem():Object
+ {
+ if (listItems.length > 0 && listItems[0].length > 0)
+ return listItems[0][0].data;
+ else
+ return null;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set firstVisibleItem(value:Object):void
+ {
+ var pos:int = getItemIndex(value);
+ if (pos < 0)
+ return;
+
+ verticalScrollPosition = Math.min(maxVerticalScrollPosition, pos);
+
+ dispatchEvent(new Event("firstVisibleItemChanged"));
+ } */
+
+ //--------------------------------------------------------------------------
+ // dataDescriptor
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ mx_internal var _dataDescriptor:ITreeDataDescriptor;
+ // new DefaultDataDescriptor();
+
+ [Inspectable(category="Data")]
+
+ /**
+ * Tree delegates to the data descriptor for information about the data.
+ * This data is then used to parse and move about the data source.
+ * <p>When you specify this property as an attribute in MXML you must
+ * use a reference to the data descriptor, not the string name of the
+ * descriptor. Use the following format for the property:</p>
+ *
+ * <pre><mx:Tree id="tree" dataDescriptor="{new MyCustomTreeDataDescriptor()}"/>></pre>
+ *
+ * <p>Alternatively, you can specify the property in MXML as a nested
+ * subtag, as the following example shows:</p>
+ *
+ * <pre><mx:Tree>
+ * <mx:dataDescriptor>
+ * <myCustomTreeDataDescriptor></pre>
+ *
+ * <p>The default value is an internal instance of the
+ * DefaultDataDescriptor class.</p>
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ public function set dataDescriptor(value:ITreeDataDescriptor):void
+ {
+ _dataDescriptor = value;
+ }
+
+ /**
+ * Returns the current ITreeDataDescriptor.
+ *
+ * @default DefaultDataDescriptor
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ public function get dataDescriptor():ITreeDataDescriptor
+ {
+ return ITreeDataDescriptor(_dataDescriptor);
+ }
+
+ //--------------------------------------------------------------------------
+ // showRoot
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Storage variable for showRoot flag.
+ */
+ //mx_internal var _showRoot:Boolean = true;
+
+ /**
+ * @private
+ * Storage variable for changes to showRoot.
+ */
+ //mx_internal var showRootChanged:Boolean = false;
+
+ /**
+ * @private
+ * Flag to indicate if the model has a root
+ */
+ //mx_internal var _hasRoot:Boolean = false;
+
+ /**
+ * @private
+ * Storage variable for the original dataProvider
+ */
+ //mx_internal var _rootModel:ICollectionView;
+
+ //[Inspectable(category="Data", enumeration="true,false", defaultValue="false")]
+
+ /**
+ * Sets the visibility of the root item.
+ *
+ * If the dataProvider data has a root node, and this is set to
+ * <code>false</code>, the Tree control does not display the root item.
+ * Only the decendants of the root item are displayed.
+ *
+ * This flag has no effect on non-rooted dataProviders, such as List and Array.
+ *
+ * @default true
+ * @see #hasRoot
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* public function get showRoot():Boolean
+ {
+ return _showRoot;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set showRoot(value:Boolean):void
+ {
+ if (_showRoot != value)
+ {
+ _showRoot = value;
+ showRootChanged = true;
+ invalidateProperties();
+ }
+ } */
+
+ /**
+ * Indicates that the current dataProvider has a root item; for example,
+ * a single top node in a hierarchical structure. XML and Object
+ * are examples of types that have a root. Lists and arrays do not.
+ *
+ * @see #showRoot
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* public function get hasRoot():Boolean
+ {
+ return _hasRoot;
+ } */
+
+ //--------------------------------------------------------------------------
+ // openItems
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Used to hold a list of items that are opened or set opened.
+ */
+ private var _openItems:Object = {};
+
+ /**
+ * @private
+ */
+ //private var openItemsChanged:Boolean = false;
+
+ /**
+ * The items that have been opened or set opened.
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ public function get openItems():Object
+ {
+ var openItemsArray:Array = [];
+ for each(var item:* in _openItems)
+ {
+ openItemsArray.push(item);
+ }
+ return openItemsArray;
+ }
+
+ /**
+ * @private
+ */
+ public function set openItems(value:Object):void
+ {
+ /* if (value != null)
+ {
+ for (var uid:String in _openItems)
+ delete _openItems[uid];
+
+ for each (var item:* in value)
+ {
+ _openItems[itemToUID(item)] = item;
+ }
+ // openItemsChanged = true;
+ // invalidateProperties();
+ } */
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ /* override protected function initializeAccessibility():void
+ {
+ if (Tree.createAccessibilityImplementation != null)
+ Tree.createAccessibilityImplementation(this);
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function commitProperties():void
+ {
+ if (showRootChanged)
+ {
+ if (!_hasRoot)
+ showRootChanged = false;
+ }
+
+ if (dataProviderChanged || showRootChanged || openItemsChanged)
+ {
+ var tmpCollection:ICollectionView;
+ //reset flags
+
+ dataProviderChanged = false;
+ showRootChanged = false;
+
+ //we always reset the open and selected items on a dataprovider assignment
+ if (!openItemsChanged)
+ _openItems = {};
+
+ openItemsChanged = false;
+
+ // are we swallowing the root?
+ if (_rootModel && !_showRoot && _hasRoot)
+ {
+ var rootItem:* = _rootModel.createCursor().current;
+ if (rootItem != null &&
+ _dataDescriptor.isBranch(rootItem, _rootModel) &&
+ _dataDescriptor.hasChildren(rootItem, _rootModel))
+ {
+ // then get rootItem children
+ tmpCollection = getChildren(rootItem, _rootModel);
+ }
+ }
+
+ // at this point _rootModel may be null so we dont need to continue
+ if (_rootModel)
+ {
+ //wrap userdata in a TreeCollection and pass that collection to the List
+ super.dataProvider = wrappedCollection = (_dataDescriptor is ITreeDataDescriptor2) ?
+ ITreeDataDescriptor2(_dataDescriptor).getHierarchicalCollectionAdaptor(
+ tmpCollection != null ? tmpCollection : _rootModel,
+ itemToUID,
+ _openItems) :
+ new HierarchicalCollectionView(
+ tmpCollection != null ? tmpCollection : _rootModel,
+ _dataDescriptor,
+ itemToUID,
+ _openItems);
+
+
+ // not really a default handler, but we need to be later than the wrapper
+ wrappedCollection.addEventListener(CollectionEvent.COLLECTION_CHANGE,
+ collectionChangeHandler,
+ false,
+ EventPriority.DEFAULT_HANDLER, true);
+ }
+ else
+ {
+ super.dataProvider = null;
+ }
+ }
+
+ super.commitProperties();
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function updateDisplayList(unscaledWidth:Number,
+ unscaledHeight:Number):void
+ {
+ // Kill any animation before resizing;
+ // tween is null if there is no Tween underway.
+ if (tween)
+ tween.endTween();
+
+ super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+ //update collection length
+ if (collection)
+ collectionLength = collection.length;
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function styleChanged(styleProp:String):void
+ {
+ if (styleProp == null ||
+ styleProp == "styleName" ||
+ IS_NEW_ROW_STYLE[styleProp])
+ {
+ itemsSizeChanged = true;
+ invalidateDisplayList();
+ }
+
+ super.styleChanged(styleProp);
+ } */
+
+ /**
+ * @private
+ * Position indicator bar that shows where an item will be placed in the list.
+ */
+ /* override public function showDropFeedback(event:DragEvent):void
+ {
+ super.showDropFeedback(event);
+ // Adjust for indent
+ var vm:EdgeMetrics = viewMetrics;
+ var offset:int = 0;
+ updateDropData(event);
+ var indent:int = 0;
+ var depth:int;
+ if (_dropData.parent)
+ {
+ offset = getItemIndex(iterator.current);
+ depth = getItemDepth(_dropData.parent, Math.abs(offset - getItemIndex(_dropData.parent)));
+ indent = (depth + 1) * getStyle("indentation");
+ }
+ else
+ {
+ indent = getStyle("indentation");
+ }
+ if (indent < 0)
+ indent = 0;
+ //position drop indicator
+ dropIndicator.width = listContent.width - indent;
+ dropIndicator.x = indent + vm.left + 2;
+ if (_dropData.emptyFolder)
+ {
+ dropIndicator.y += _dropData.rowHeight / 2;
+ }
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function calculateDropIndex(event:DragEvent = null):int
+ {
+ if (event)
+ updateDropData(event);
+
+ return _dropData.rowIndex;
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function addDragData(ds:Object):void // actually a DragSource
+ {
+ ds.addHandler(collapseSelectedItems, "treeItems");
+ } */
+
+ /**
+ * @private
+ *
+ * see ListBase.as
+ */
+ /* override mx_internal function addClipMask(layoutChanged:Boolean):void
+ {
+ var vm:EdgeMetrics = viewMetrics;
+
+ if (horizontalScrollBar && horizontalScrollBar.visible)
+ vm.bottom -= horizontalScrollBar.minHeight;
+
+ if (verticalScrollBar && verticalScrollBar.visible)
+ vm.right -= verticalScrollBar.minWidth;
+
+ listContent.scrollRect = new Rectangle(
+ 0, 0,
+ unscaledWidth - vm.left - vm.right,
+ listContent.heightExcludingOffsets);
+ } */
+
+ /**
+ * @private
+ *
+ * Undo the effects of the addClipMask function (above)
+ */
+ /* override mx_internal function removeClipMask():void
+ {
+ } */
+
+ /**
+ * Creates a new TreeListData instance and populates the fields based on
+ * the input data provider item.
+ *
+ * @param data The data provider item used to populate the ListData.
+ * @param uid The UID for the item.
+ * @param rowNum The index of the item in the data provider.
+ *
+ * @return A newly constructed ListData object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* override protected function makeListData(data:Object, uid:String,
+ rowNum:int):BaseListData
+ {
+ var treeListData:TreeListData = new TreeListData(itemToLabel(data), uid, this, rowNum);
+ initListData(data, treeListData);
+ return treeListData;
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function itemToIcon(item:Object):Class
+ {
+ if (item == null)
+ {
+ return null;
+ }
+
+ var icon:*;
+ var open:Boolean = isItemOpen(item);
+ var branch:Boolean = isBranch(item);
+ var uid:String = itemToUID(item);
+
+ //first lets check the component
+ var iconClass:Class =
+ itemIcons && itemIcons[uid] ?
+ itemIcons[uid][open ? "iconID2" : "iconID"] :
+ null;
+
+ if (iconClass)
+ {
+ return iconClass;
+ }
+ else if (iconFunction != null)
+ {
+ return iconFunction(item)
+ }
+ else if (branch)
+ {
+ return getStyle(open ? "folderOpenIcon" : "folderClosedIcon");
+ }
+ else
+ //let's check the item itself
+ {
+ if (item is XML)
+ {
+ try
+ {
+ if (item[iconField].length() != 0)
+ icon = String(item[iconField]);
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ else if (item is Object)
+ {
+ try
+ {
+ if (iconField && item[iconField])
+ icon = item[iconField];
+ else if (item.icon)
+ icon = item.icon;
+ }
+ catch(e:Error)
+ {
+ }
+ }
+ }
+
+ //set default leaf icon if nothing else was found
+ if (icon == null)
+ icon = getStyle("defaultLeafIcon");
+
+ //convert to the correct type and class
+ if (icon is Class)
+ {
+ return icon;
+ }
+ else if (icon is String)
+ {
+ iconClass = Class(systemManager.getDefinitionByName(String(icon)));
+ if (iconClass)
+ return iconClass;
+
+ return document[icon];
+ }
+ else
+ {
+ return Class(icon);
+ }
+
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function drawRowBackgrounds():void
+ {
+ var rowBGs:Sprite = Sprite(listContent.getChildByName("rowBGs"));
+ if (!rowBGs)
+ {
+ rowBGs = new FlexSprite();
+ rowBGs.name = "rowBGs";
+ rowBGs.mouseEnabled = false;
+ listContent.addChildAt(rowBGs, 0);
+ }
+
+ var color:*;
+ var colors:Array;
+ var depthColors:Boolean = false;
+
+ colors = getStyle("depthColors");
+ if (colors)
+ {
+ depthColors = true;
+ }
+ else
+ {
+ var colorsStyle:Object = getStyle("alternatingItemColors");
+
+ if (colorsStyle)
+ colors = (colorsStyle is Array) ? (colorsStyle as Array) : [colorsStyle];
+ }
+ color = getStyle("backgroundColor");
+ if (color === undefined)
+ color = 0xFFFFFF;
+ if (!colors || colors.length == 0)
+ {
+ while (rowBGs.numChildren > n)
+ {
+ rowBGs.removeChildAt(rowBGs.numChildren - 1);
+ }
+ return;
+ }
+
+ styleManager.getColorNames(colors);
+
+ var curRow:int = 0;
+ var actualRow:int = verticalScrollPosition;
+ var i:int = 0;
+ var n:int = listItems.length;
+
+ while (curRow < n)
+ {
+ if (depthColors)
+ {
+ try
+ {
+ if (listItems[curRow][0])
+ {
+ var d:int = getItemDepth(listItems[curRow][0].data, curRow);
+ var rowColor:uint = colors[d-1] ? colors[d - 1] : uint(color);
+ drawRowBackground(rowBGs, i++, rowInfo[curRow].y, rowInfo[curRow].height, rowColor, actualRow);
+ }
+ else
+ {
+ drawRowBackground(rowBGs, i++, rowInfo[curRow].y, rowInfo[curRow].height, uint(color), actualRow);
+ }
+ }
+ catch(e:Error)
+ {
+ //trace("[Tree] caught exception in drawRowBackground");
+ }
+ }
+ else
+ {
+ drawRowBackground(rowBGs, i++, rowInfo[curRow].y, rowInfo[curRow].height, colors[actualRow % colors.length], actualRow);
+ }
+ curRow++;
+ actualRow++;
+ }
+ while (rowBGs.numChildren > n)
+ {
+ rowBGs.removeChildAt(rowBGs.numChildren - 1);
+ }
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Sets the associated icon for the item. Calling this method overrides the
+ * <code>iconField</code> and <code>iconFunction</code> properties for
+ * this item if it is a leaf item. Branch items don't use the
+ * <code>iconField</code> and <code>iconFunction</code> properties.
+ * They use the <code>folderOpenIcon</code> and <code>folderClosedIcon</code> properties.
+ *
+ * @param item Item to affect.
+ * @param iconID Linkage ID for the closed (or leaf) icon.
+ * @param iconID2 Linkage ID for the open icon.
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* public function setItemIcon(item:Object, iconID:Class, iconID2:Class):void
+ {
+ if (!itemIcons)
+ itemIcons = {};
+
+ if (!iconID2)
+ iconID2 = iconID;
+
+ itemIcons[itemToUID(item)] = { iconID: iconID, iconID2: iconID2 };
+
+ itemsSizeChanged = true;
+ invalidateDisplayList();
+ } */
+
+ /**
+ * @private
+ * Returns <code>true</code> if the specified item is a branch item. The Tree
+ * control delegates to the IDataDescriptor to determine if an item is a branch.
+ * @param item Item to inspect.
+ * @return True if a branch, false if not.
+ *
+ */
+ /* private function isBranch(item:Object):Boolean
+ {
+ if (item != null)
+ return _dataDescriptor.isBranch(item, iterator.view);
+
+ return false;
+ } */
+
+ /**
+ * @private
+ * wraps calls to the descriptor
+ * mx_internal for automation delegate access
+ */
+ /* mx_internal function getChildren(item:Object, view:Object):ICollectionView
+ {
+ //get the collection of children
+ var children:ICollectionView = _dataDescriptor.getChildren(item, view);
+ return children;
+ } */
+
+ /**
+ * Determines the number of parents from root to the specified item.
+ * Method starts with the Cursor.current item and will seek forward
+ * to a specific offset, returning the cursor to its original position.
+ *
+ * @private
+ */
+ /* mx_internal function getItemDepth(item:Object, offset:int):int
+ {
+ //first test for a match (most cases)
+ if (!collection)
+ return 0;
+
+ if (!iterator)
+ listContent.iterator = collection.createCursor();
+
+ if (iterator.current == item)
+ return getCurrentCursorDepth();
+
+ //otherwise seek to offset and get the depth
+ var bookmark:CursorBookmark = iterator.bookmark;
+ iterator.seek(bookmark, offset);
+ var depth:int = getCurrentCursorDepth();
+ //put the cursor back
+ iterator.seek(bookmark, 0);
+ return depth;
+ } */
+
+ /**
+ * @private
+ * Utility method to get the depth of the current item from the cursor.
+ */
+ /* private function getCurrentCursorDepth():int //private
+ {
+ if (_dataDescriptor is ITreeDataDescriptor2)
+ return ITreeDataDescriptor2(_dataDescriptor).getNodeDepth(iterator.current, iterator, _rootModel);
+
+ return HierarchicalViewCursor(iterator).currentDepth;
+ } */
+
+ /**
+ * @private
+ * Gets the number of visible items from a starting item.
+ */
+ /* private function getVisibleChildrenCount(item:Object):int
+ {
+ var count:int = 0;
+
+ if (item == null)
+ return count;
+
+ var uid:String = itemToUID(item);
+ var children:Object;
+ if (_openItems[uid] &&
+ _dataDescriptor.isBranch(item, iterator.view) &&
+ _dataDescriptor.hasChildren(item, iterator.view))
+ {
+ children = getChildren(item, iterator.view);
+ }
+ if (children != null)
+ {
+ var cursor:IViewCursor = children.createCursor();
+ while (!cursor.afterLast)
+ {
+ count++;
+ uid = itemToUID(cursor.current);
+ if (_openItems[uid])
+ count += getVisibleChildrenCount(cursor.current);
+ cursor.moveNext();
+ }
+ }
+ return count;
+ } */
+
+ /**
+ * Returns <code>true</code> if the specified item branch is open (is showing its children).
+ * @param item Item to inspect.
+ * @return True if open, false if not.
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* public function isItemOpen(item:Object):Boolean
+ {
+ var uid:String = itemToUID(item);
+ return _openItems[uid] != null;
+ } */
+
+ /**
+ * @private
+ */
+ /* private function makeMask():DisplayObject
+ {
+ var tmpMask:Shape = new FlexShape();
+ tmpMask.name = "mask";
+
+ var g:Graphics = tmpMask.graphics;
+ g.beginFill(0xFFFFFF);
+ g.moveTo(0,0);
+ g.lineTo(0,10);
+ g.lineTo(10,10);
+ g.lineTo(10,0);
+ g.lineTo(0,0);
+ g.endFill();
+
+ listContent.addChild(tmpMask);
+ return tmpMask;
+ } */
+
+ /**
+ * Opens or closes a branch item.
+ * When a branch item opens, it restores the open and closed states
+ * of its child branches if they were already opened.
+ *
+ * If you set <code>dataProvider</code> and then immediately call
+ * <code>expandItem()</code> you may not see the correct behavior.
+ * You should either wait for the component to validate
+ * or call <code>validateNow()</code>.
+ *
+ * @param item Item to affect.
+ *
+ * @param open Specify <code>true</code> to open, <code>false</code> to close.
+ *
+ * @param animate Specify <code>true</code> to animate the transition. (Note:
+ * If a branch has over 20 children, it does not animate the first time it opens,
+ * for performance reasons.)
+ *
+ * @param dispatchEvent Controls whether the tree fires an <code>open</code> event
+ * after the open animation is complete.
+ *
+ * @param cause The event, if any, that initiated the item open action.
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* public function expandItem(item:Object, open:Boolean,
+ animate:Boolean = false,
+ dispatchEvent:Boolean = false,
+ cause:Event = null):void
+ {
+ //if the iterator is null, that indicates we have not been
+ //validated yet, so we will not continue.
+ if (iterator == null)
+ return;
+
+ if (cause)
+ lastUserInteraction = cause;
+
+ expandedItem = item;
+
+ listContent.allowItemSizeChangeNotification = false;
+
+ var i:int;
+ var bSelected:Boolean = false;
+ var bHighlight:Boolean = false;
+ var bCaret:Boolean = false;
+ var newRowIndex:int;
+ var rowData:BaseListData;
+
+ var tmpMask:DisplayObject;
+
+ var uid:String = itemToUID(item);
+ // if this can't be opened, or shouldn't be, don't!
+ if (!isBranch(item) || (isItemOpen(item)==open) || isOpening)
+ return;
+
+ if (itemEditorInstance)
+ endEdit(ListEventReason.OTHER);
+
+ //we'll use the last recorded length not necessarily the current one
+ oldLength = collectionLength;
+
+ var bookmark:CursorBookmark = iterator.bookmark;
+
+ // sent to update the length in the collection
+ var event:CollectionEvent = new CollectionEvent(
+ CollectionEvent.COLLECTION_CHANGE,
+ false,
+ true,
+ CollectionEventKind.EXPAND);
+ event.items = [item];
+
+ // update the list of _openItems
+ if (open)
+ {
+ _openItems[uid] = item;
+ collection.dispatchEvent(event);
+ rowsTweened = Math.abs(oldLength - collection.length);
+ }
+ else
+ {
+ delete _openItems[uid];
+ collection.dispatchEvent(event);
+ //how many rows to move?
+ rowsTweened = Math.abs(oldLength - collection.length);
+ }
+
+ // will it affect the displayList?
+ if (isItemVisible(item))
+ {
+ // is the item on screen?
+ if (visibleData[uid])
+ {
+ //find the row index of the first row after the one that's opening/closing
+ var n:int = listItems.length;
+ for (rowIndex = 0; rowIndex < n; rowIndex++)
+ {
+ if (rowInfo[rowIndex].uid == uid)
+ {
+ rowIndex++;
+ // rowIndex is set to the row after the one opening/closing
+ // because that is the first row to change
+ break;
+ }
+ }
+ }
+ }
+ //if we're opening or closing a node that is not visible,
+ //we still need to dispatch the correct collectionChange events
+ //so that scroll position and selection properties update correctly.
+ else
+ {
+ var eventArr:Array = open ?
+ buildUpCollectionEvents(true) : buildUpCollectionEvents(false);
+ for (i = 0; i < eventArr.length; i++)
+ {
+ collection.dispatchEvent(eventArr[i]);
+ }
+ return;
+ }
+
+ var rC:int = listItems.length;
+ var tmpRowInfo:Object;
+ var row:Array;
+ // we will cap this with as many rows as can be displayed later
+ var rowsToMove:int = rowsTweened;
+ var dur:Number = getStyle("openDuration");
+ if (animate && rowIndex < rC && rowsToMove > 0 && rowsToMove < 20 && dur != 0)
+ {
+ // Kill any previous animation. tween is undefined if there is no Tween underway.
+ if (tween)
+ tween.endTween();
+
+ var renderer:IListItemRenderer = listItems[rowIndex - 1][0];
+ if (renderer is IDropInListItemRenderer)
+ {
+ var di:IDropInListItemRenderer = IDropInListItemRenderer(renderer);
+ var treeListData:TreeListData = TreeListData(di.listData);
+ treeListData = TreeListData(makeListData(treeListData.item,
+ treeListData.uid, treeListData.rowIndex));
+ di.listData = treeListData;
+ renderer.data = renderer.data; // this forces eval of new listData
+ }
+
+ // animate the opening
+ opening = open;
+ isOpening = true;
+
+ maskList = [];
+ rowList = [];
+
+ var xx:Number = getStyle("paddingLeft") - horizontalScrollPosition;
+ var ww:Number = renderer.width;
+ var yy:Number = 0;
+ var hh:Number;
+
+ // don't tween anymore than the amount of space we have
+ var delta:int = rowIndex;
+ var maxDist:Number = 0;
+ if (open)
+ {
+ newRowIndex = rowIndex;
+ // don't tween anymore than the amount of space we have
+ maxDist = listContent.height - rowInfo[rowIndex].y;
+ iterator.seek(CursorBookmark.CURRENT, delta);
+ var data:Object;
+
+ // create the rows now so we know how much to move
+ for (i = 0; i < rowsToMove && yy < maxDist; i++)
+ {
+ data = iterator.current;
+
+ if (freeItemRenderers.length)
+ {
+ renderer = freeItemRenderers.pop();
+ }
+ else
+ {
+ renderer = createItemRenderer(data);
+ renderer.owner = this;
+ renderer.styleName = listContent;
+ listContent.addChild(DisplayObject(renderer));
+ }
+ uid = itemToUID(data);
+ rowData = makeListData(data, uid, rowIndex + i);
+ rowMap[renderer.name] = rowData;
+ if (renderer is IDropInListItemRenderer)
+ IDropInListItemRenderer(renderer).listData = data ? rowData : null;
+ renderer.data = data;
+ renderer.enabled = enabled;
+ if (data)
+ {
+ visibleData[uid] = renderer;
+ renderer.visible = true;
+ }
+ else
+ {
+ renderer.visible = false;
+ }
+ renderer.explicitWidth = ww;
+
+ //from list
+ if ((renderer is IInvalidating) &&
+ (wordWrapChanged ||
+ variableRowHeight))
+ IInvalidating(renderer).invalidateSize();
+
+ UIComponentGlobals.layoutManager.validateClient(renderer, true);
+
+ hh = Math.ceil(variableRowHeight ?
+ renderer.getExplicitOrMeasuredHeight() +
+ cachedPaddingTop + cachedPaddingBottom :
+ rowHeight);
+ var rh:Number = renderer.getExplicitOrMeasuredHeight();
+ renderer.setActualSize(ww, variableRowHeight ? rh : rowHeight - cachedPaddingTop - cachedPaddingBottom);
+ renderer.move(xx, yy + cachedPaddingTop);
+ bSelected = selectedData[uid] != null;
+ bHighlight = highlightUID == uid;
+ bCaret = caretUID == uid;
+ tmpRowInfo = new ListRowInfo(yy, hh, uid, data);
+ if (data)
+ drawItem(renderer, bSelected, bHighlight, bCaret);
+ yy += hh;
+
+ rowInfo.splice(rowIndex + i, 0, tmpRowInfo);
+ row = [];
+ row.push(renderer);
+ listItems.splice(rowIndex + i, 0, row);
+
+ // due to issues in HCV with paging
+ // don't go looking for something unless you really
+ // need it
+ if (i < rowsToMove - 1)
+ {
+ try
+ {
+ iterator.moveNext();
+ }
+ catch(e:ItemPendingError)
+ {
+ rowsToMove = i + 1;
+ break;
+ }
+ }
+ }
+ rowsTweened = i;
+ // position the new rows;
+ var referenceRowInfo:ListRowInfo = rowInfo[rowIndex + rowsTweened];
+ for (i = 0; i < rowsTweened; i++)
+ {
+ renderer = listItems[rowIndex + i][0];
+ renderer.move(renderer.x, renderer.y - (yy - referenceRowInfo.y));
+ rowInfo[rowIndex + i].y -= yy - referenceRowInfo.y;
+ tmpMask = makeMask();
+ tmpMask.x = xx;
+ tmpMask.y = referenceRowInfo.y;
+ tmpMask.width = ww;
+ tmpMask.height = yy;
+ listItems[rowIndex + i][0].mask = tmpMask;
+ }
+ }
+ else // closing up rows
+ {
+ var more:Boolean = true;
+ var valid:Boolean = true;
+ var startY:Number = yy = rowInfo[listItems.length - 1].y + rowInfo[listItems.length - 1].height;
+
+ // figure out how much space was consumed by the rows that are going away
+ for (i = rowIndex; i < rowIndex + rowsToMove && i < rC; i++)
+ {
+ maxDist += rowInfo[i].height;
+ // retain a reference to the rows going away
+ rowList.push({item: listItems[i][0]});
+ tmpMask = makeMask();
+ tmpMask.x = xx;
+ tmpMask.y = listItems[rowIndex][0].y;
+ tmpMask.width = ww;
+ tmpMask.height = maxDist;
+ listItems[i][0].mask = tmpMask;
+ }
+ rowsToMove = i - rowIndex;
+ // remove the rows going away
+ rowInfo.splice(rowIndex, rowsToMove);
+ listItems.splice(rowIndex, rowsToMove);
+
+ iterator.seek(CursorBookmark.CURRENT, listItems.length);
+ more = (iterator != null && !iterator.afterLast && iteratorValid);
+
+ maxDist += yy;
+ // create the rows now so we know how much to move
+ for (i = 0; i < rowsToMove && yy < maxDist; i++)
+ {
+ //reset item specific values
+ uid = null;
+ data = null;
+ renderer = null;
+
+ valid = more;
+ data = more ? iterator.current : null;
+
+ if (valid)
+ {
+ if (freeItemRenderers.length)
+ {
+ renderer = freeItemRenderers.pop();
+ }
+ else
+ {
+ renderer = createItemRenderer(data);
+ renderer.owner = this;
+ renderer.styleName = listContent;
+ listContent.addChild(DisplayObject(renderer));
+ }
+ uid = itemToUID(data);
+ rowData = makeListData(data, uid, rC - rowsToMove + i);
+ rowMap[renderer.name] = rowData;
+ if (renderer is IDropInListItemRenderer)
+ IDropInListItemRenderer(renderer).listData = data ? rowData : null;
+ renderer.data = data;
+ renderer.enabled = enabled;
+ if (data)
+ {
+ visibleData[uid] = renderer;
+ renderer.visible = true;
+ }
+ else
+ renderer.visible = false;
+
+ renderer.explicitWidth = ww;
+
+ //from list
+ if ((renderer is IInvalidating) &&
+ (wordWrapChanged ||
+ variableRowHeight))
+ IInvalidating(renderer).invalidateSize();
+
+ UIComponentGlobals.layoutManager.validateClient(renderer, true);
+
+ hh = Math.ceil(variableRowHeight ?
+ renderer.getExplicitOrMeasuredHeight() +
+ cachedPaddingTop + cachedPaddingBottom :
+ rowHeight);
+ rh = renderer.getExplicitOrMeasuredHeight();
+ renderer.setActualSize(ww, variableRowHeight ? rh : rowHeight - cachedPaddingTop - cachedPaddingBottom);
+ renderer.move(xx, yy + cachedPaddingTop);
+ }
+ else
+ {
+ // if we've run out of data, we dont make renderers
+ // and we inherit the previous row's height or rowHeight
+ // if it is the first row.
+ // EXCEPT when variable row height is on since the row
+ // above us might be bigger then we are. So we'll get
+ // this row out of the rowList and check it.
+ if (!variableRowHeight)
+ {
+ hh = rowIndex + i > 0 ? rowInfo[rowIndex + i - 1].height : rowHeight;
+ }
+ else
+ {
+ if (rowList[i])
+ {
+ hh = Math.ceil(rowList[i].item.getExplicitOrMeasuredHeight() +
+ cachedPaddingTop + cachedPaddingBottom);
+ }
+ else
+ {
+ //default
+ hh = rowHeight;
+ }
+ }
+ }
+ bSelected = selectedData[uid] != null;
+ bHighlight = highlightUID == uid;
+ bCaret = caretUID == uid;
+ tmpRowInfo = new ListRowInfo(yy, hh, uid, data);
+ rowInfo.push(tmpRowInfo);
+ if (data)
+ {
+ drawItem(renderer, bSelected, bHighlight, bCaret);
+ }
+ yy += hh;
+
+ if (valid)
+ {
+ row = [];
+ row.push(renderer);
+ listItems.push(row);
+ }
+ else
+ {
+ listItems.push([]);
+ }
+
+ if (more)
+ {
+ try
+ {
+ more = iterator.moveNext();
+ }
+ catch (e:ItemPendingError)
+ {
+ more = false;
+ }
+ }
+ }
+
+ //make indicator masks
+ var maskY:Number = rowList[0].item.y - getStyle("paddingTop");
+ var maskX:Number = rowList[0].item.x - getStyle("paddingLeft");
+ for (i = 0; i < rowList.length; i++)
+ {
+ var indicator:Object = selectionIndicators[itemToUID(rowList[i].item.data)];
+ if (indicator)
+ {
+ tmpMask = makeMask();
+ tmpMask.x = maskX;
+ tmpMask.y = maskY;
+ tmpMask.width = rowList[i].item.width +
+ getStyle("paddingLeft") +
+ getStyle("paddingRight");
+ tmpMask.height = rowList[i].item.y +
+ rowList[i].item.height +
+ getStyle("paddingTop") +
+ getStyle("paddingBottom") -
+ maskY;
+ selectionIndicators[itemToUID(rowList[i].item.data)].mask = tmpMask;
+ }
+ }
+ }
+ // restore the iterator
+ iterator.seek(bookmark, 0);
+
+ rC = rowList.length;
+ for (i = 0; i < rC; i++)
+ {
+ rowList[i].itemOldY = rowList[i].item.y;
+ }
+ rC = listItems.length;
+ for (i = rowIndex; i < rC; i++)
+ {
+ if (listItems[i].length)
+ {
+ rowInfo[i].itemOldY = listItems[i][0].y;
+ }
+ rowInfo[i].oldY = rowInfo[i].y;
+ }
+ // slow down the tween if there's lots of rows to tween
+ dur = dur * Math.max(rowsToMove / 5, 1);
+
+ if (dispatchEvent)
+ eventAfterTween = item;
+
+ tween = new Tween(this, 0, (open) ? yy : startY - yy, dur, 5);
+ var oE:Function = getStyle("openEasingFunction") as Function;
+ if (oE != null)
+ tween.easingFunction = oE;
+
+ // Block all layout, responses from web service, and other background
+ // processing until the tween finishes executing.
+ UIComponent.suspendBackgroundProcessing();
+ // force drawing in case there's new rows
+ UIComponentGlobals.layoutManager.validateNow();
+ }
+ else
+ {
+ // not to be animated
+ if (dispatchEvent)
+ {
+ dispatchTreeEvent(open ? TreeEvent.ITEM_OPEN : TreeEvent.ITEM_CLOSE,
+ item,
+ visibleData[itemToUID(item)],
+ lastUserInteraction);
+ lastUserInteraction = null;
+ }
+ itemsSizeChanged = true;
+ invalidateDisplayList();
+ }
+
+ // If we're wordwrapping, no need to adjust maxHorizontalScrollPosition.
+ // Also check if _userMaxHorizontalScrollPosition is greater than 0.
+ if (!wordWrap && initialized)
+ {
+ super.maxHorizontalScrollPosition =
+ _userMaxHorizontalScrollPosition > 0 ?
+ _userMaxHorizontalScrollPosition + getIndent() :
+ super.maxHorizontalScrollPosition;
+ }
+ //restore ItemSizeChangeNotification flag
+ listContent.allowItemSizeChangeNotification = variableRowHeight;
+ } */
+
+ /**
+ * @private
+ */
+ /* mx_internal function onTweenUpdate(value:Object):void
+ {
+ var renderer:IFlexDisplayObject;
+ var n:int;
+ var i:int;
+ var deltaY:Number;
+ var lastY:Number;
+
+ n = listItems.length;
+ var s:Sprite;
+ for (i = rowIndex; i < n; i++)
+ {
+ //move items that are staying
+ if (listItems[i].length)
+ {
+ renderer = IFlexDisplayObject(listItems[i][0]);
+ lastY = renderer.y;
+ renderer.move(renderer.x, rowInfo[i].itemOldY + value);
+ deltaY = renderer.y - lastY;
+ }
+ //move selection graphics of the items that are staying visible
+ s = selectionIndicators[rowInfo[i].uid];
+
+ rowInfo[i].y += deltaY;
+
+ if (s)
+ {
+ s.y += deltaY;
+ }
+ }
+ //move the items that are going away.
+ n = rowList.length;
+ for (i = 0; i < n; i++)
+ {
+ s = null;
+ renderer = IFlexDisplayObject(rowList[i].item);
+ if (rowMap[renderer.name] != null)
+ {
+ s = selectionIndicators[BaseListData(rowMap[renderer.name]).uid];
+ }
+ lastY = renderer.y;
+ renderer.move(renderer.x, rowList[i].itemOldY + value);
+ deltaY = renderer.y - lastY;
+ //move selection graphic for items that are going away
+ if (s)
+ {
+ s.y += deltaY;
+ }
+ }
+ } */
+
+ /**
+ * @private
+ */
+ /* mx_internal function onTweenEnd(value:Object):void
+ {
+ UIComponent.resumeBackgroundProcessing();
+
+ onTweenUpdate(value);
+
+ var i:int;
+ var renderer:*;
+ var dilir:IDropInListItemRenderer;
+ var rC:int = listItems.length;
+ var itemUID:*;
+ var indicator:Object;
+
+ isOpening = false;
+
+ //dispatch collectionChange ADD or REMOVE events that correlate
+ //to the nodes that were expanded or collapsed
+ if (collection)
+ {
+ var eventArr:Array = opening ?
+ buildUpCollectionEvents(true) : buildUpCollectionEvents(false);
+ for (i = 0; i < eventArr.length; i++)
+ {
+ collection.dispatchEvent(eventArr[i]);
+ }
+ }
+
+ if (opening)
+ {
+ var firstDeletedRow:int = -1;
+ for (i = rowIndex; i < rC; i++)
+ {
+ if (listItems[i].length)
+ {
+ renderer = listItems[i][0];
+ var mask:DisplayObject = renderer.mask;
+ if (mask)
+ {
+ listContent.removeChild(mask);
+ renderer.mask = null;
+ }
+ rowMap[renderer.name].rowIndex = i;
+ if (renderer is IDropInListItemRenderer)
+ {
+ dilir = IDropInListItemRenderer(renderer);
+ if (dilir.listData)
+ {
+ dilir.listData.rowIndex = i;
+ dilir.listData = dilir.listData; // call the setter
+ }
+ }
+ if (renderer.y > listContent.height)
+ {
+ addToFreeItemRenderers(renderer);
+ itemUID = itemToUID(renderer.data);
+ if (selectionIndicators[itemUID])
+ {
+ //remove indicators mask
+ indicator = selectionIndicators[itemUID];
+ if (indicator)
+ {
+ mask = indicator.mask;
+ if (mask)
+ {
+ listContent.removeChild(mask);
+ indicator.mask = null;
+ }
+ }
+ removeIndicators(itemUID);
+ }
+ delete rowMap[renderer.name];
+ if (firstDeletedRow < 0)
+ firstDeletedRow = i;
+ }
+ }
+ else
+ {
+ if (rowInfo[i].y >= listContent.height)
+ {
+ if (firstDeletedRow < 0)
+ firstDeletedRow = i;
+ }
+ }
+ }
+ if (firstDeletedRow >= 0)
+ {
+ rowInfo.splice(firstDeletedRow);
+ listItems.splice(firstDeletedRow);
+ }
+ }
+ else //closing
+ {
+ for (i = 0; i < rowList.length; i++)
+ {
+ mask = rowList[i].item.mask;
+ if (mask)
+ {
+ listContent.removeChild(mask);
+ rowList[i].item.mask = null;
+ }
+ addToFreeItemRenderers(rowList[i].item);
+ //kill graphic and graphic mask if necessary
+ itemUID = itemToUID(rowList[i].item.data);
+ if (selectionIndicators[itemUID])
+ {
+ //remove indicators mask
+ indicator = selectionIndicators[itemUID];
+ if (indicator)
+ {
+ mask = indicator.mask;
+ if (mask)
+ {
+ listContent.removeChild(mask);
+ indicator.mask = null;
+ }
+ }
+ removeIndicators(itemUID);
+ }
+ delete rowMap[rowList[i].item.name];
+ }
+ for (i = rowIndex; i < rC; i++)
+ {
+ if (listItems[i].length)
+ {
+ renderer = listItems[i][0];
+ rowMap[renderer.name].rowIndex = i;
+ if (renderer is IDropInListItemRenderer)
+ {
+ dilir = IDropInListItemRenderer(renderer);
+ if (dilir.listData)
+ {
+ dilir.listData.rowIndex = i;
+ dilir.listData = dilir.listData; // call the setter
+ }
+ }
+ }
+ }
+ }
+
+ //should we dispatch a tree event?
+ if (eventAfterTween)
+ {
+ dispatchTreeEvent((isItemOpen(eventAfterTween)
+ ? TreeEvent.ITEM_OPEN
+ : TreeEvent.ITEM_CLOSE),
+ eventAfterTween,
+ visibleData[itemToUID(eventAfterTween)],
+ lastUserInteraction);
+ lastUserInteraction = null;
+ eventAfterTween = false;
+ }
+ //invalidate
+ itemsSizeChanged = true;
+ invalidateDisplayList();
+ // Get rid of the tween, so this onTweenEnd doesn't get called more than once.
+ tween = null;
+ } */
+
+ /**
+ * @private
+ *
+ * Helper function that builds up the collectionChange ADD or
+ * REMOVE events that correlate to the nodes that were expanded
+ * or collapsed.
+ */
+ /* private function buildUpCollectionEvents(open:Boolean):Array
+ {
+ var ce:CollectionEvent;
+ var i:int;
+ var item:Object;
+ var parentArray:Array;
+ var rowsAdded:Array = [];
+ var rowsRemoved:Array = [];
+ var retVal:Array = [];
+
+ var itemIndex:int = getItemIndex(expandedItem);
+
+ if (open)
+ {
+ var children:ICollectionView = getChildren(expandedItem, iterator.view);
+ if (!children)
+ return [];
+ var cursor:IViewCursor = children.createCursor();
+ var push:Boolean = true;
+ while (!cursor.afterLast)
+ {
+ rowsAdded.push(cursor.current);
+ cursor.moveNext();
+ }
+ }
+ else
+ {
+ var stack:Array = [];
+ var j:int = 0;
+ stack = getOpenChildrenStack(expandedItem, stack);
+ while (j < stack.length)
+ {
+ for (i = 0; i < selectedItems.length; i++)
+ {
+ if (selectedItems[i] == stack[j])
+ {
+ bSelectedItemRemoved = true;
+ }
+ }
+ rowsRemoved.push(stack[j]);
+ j++;
+ }
+ }
+ if (rowsAdded.length > 0)
+ {
+ ce = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ ce.kind = CollectionEventKind.ADD;
+ ce.location = itemIndex + 1;
+ ce.items = rowsAdded;
+ retVal.push(ce);
+ }
+ if (rowsRemoved.length > 0)
+ {
+ ce = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ ce.kind = CollectionEventKind.REMOVE;
+ ce.location = itemIndex + 1;
+ ce.items = rowsRemoved;
+ retVal.push(ce);
+ }
+ return retVal;
+ } */
+
+ /**
+ * @private
+ * Go through the open items and figure out which is deepest.
+ */
+ /* private function getIndent():Number
+ {
+ var depth:Number = 0;
+ for (var p:String in _openItems)
+ {
+ // add one since its children are actually indented
+ depth = Math.max(getParentStack(_openItems[p]).length + 1, depth);
+ }
+ return depth * getStyle("indentation");
+ } */
+
+ /**
+ * Checks to see if item is visible in the list
+ * @private
+ */
+ /* override public function isItemVisible(item:Object):Boolean
+ {
+ //first check visible data
+ if (visibleData[itemToUID(item)])
+ return true;
+
+ //then check parent items
+ var parentItem:Object = getParentItem(item);
+ if (parentItem)
+ {
+ var uid:String = itemToUID(parentItem);
+ if (visibleData[uid] && _openItems[uid])
+ {
+ return true;
+ }
+ }
+ return false;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function getItemIndex(item:Object):int
+ {
+ var cursor:IViewCursor = collection.createCursor();
+ var i:int = 0;
+ do
+ {
+ if (cursor.current === item)
+ break;
+ i++;
+ }
+ while (cursor.moveNext());
+ // set back to 0 in case a change event comes along
+ // and causes the cursor to hit an unexpected IPE
+ cursor.seek(CursorBookmark.FIRST, 0);
+ return i;
+ } */
+
+ /**
+ * @private
+ */
+ /* private function getIndexItem(index:int):Object
+ {
+ var cursor:IViewCursor = collection.createCursor();
+ var i:int = index;
+ while (cursor.moveNext())
+ {
+ if (i == 0)
+ return cursor.current;
+ i--;
+ }
+ return null;
+ } */
+
+ /**
+ * Opens or closes all the tree items below the specified item.
+ *
+ * If you set <code>dataProvider</code> and then immediately call
+ * <code>expandChildrenOf()</code> you may not see the correct behavior.
+ * You should either wait for the component to validate
+ * or call the <code>validateNow()</code> method.
+ *
+ * @param item The starting item.
+ *
+ * @param open Toggles an open or close operation.
+ * Specify <code>true</code> to open the items, and <code>false</code> to close them.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ public function expandChildrenOf(item:Object, open:Boolean):void
+ {
+ //if the iterator is null, that indicates we have not been
+ //validated yet, so we will not continue.
+ /* if (iterator == null)
+ return;
+
+ // if it is not a branch item there's nothing to do
+ if (isBranch(item))
+ {
+ dispatchTreeEvent(TreeEvent.ITEM_OPENING,
+ item, //item
+ null, //renderer
+ null, //trigger
+ open, //opening
+ false, //animate
+ true); //dispatch
+
+ var childItems:ICollectionView;
+ if (item != null &&
+ _dataDescriptor.isBranch(item, iterator.view) &&
+ _dataDescriptor.hasChildren(item, iterator.view))
+ {
+ childItems = getChildren(item, iterator.view);
+ }
+ if (childItems)
+ {
+ var cursor:IViewCursor = childItems.createCursor();
+ while (!cursor.afterLast)
+ {
+ if (isBranch(cursor.current))
+ expandChildrenOf(cursor.current, open);
+ cursor.moveNext();
+ }
+ }
+ } */
+ }
+
+ /**
+ * Returns the known parent of a child item. This method returns a value
+ * only if the item was or is currently visible. Top level items have a
+ * parent with the value <code>null</code>.
+ *
+ * @param The item for which to get the parent.
+ *
+ * @return The parent of the item.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ public function getParentItem(item:Object):*
+ {
+ /* if (item == null)
+ return null;
+ if (item && collection)
+ {
+ if (_dataDescriptor is ITreeDataDescriptor2)
+ return ITreeDataDescriptor2(_dataDescriptor).getParent(item, wrappedCollection, _rootModel);
+ return HierarchicalCollectionView(collection).getParentItem(item);
+ } */
+ return null;
+ }
+
+ /**
+ * @private
+ * Returns the stack of parents from a child item.
+ */
+ /* private function getParentStack(item:Object):Array
+ {
+ var stack:Array = [];
+ if (item == null)
+ return stack;
+
+ var parent:* = getParentItem(item);
+ while (parent)
+ {
+ stack.push(parent);
+ parent = getParentItem(parent);
+ }
+ return stack;
+ } */
+
+ /**
+ * @private
+ * Returns a stack of all open descendants of an item.
+ */
+ /* private function getOpenChildrenStack(item:Object, stack:Array):Array
+ {
+ var curr:Object;
+ if (item == null)
+ return stack;
+
+ var children:ICollectionView = getChildren(item, iterator.view);
+ if (!children)
+ return [];
+ var cursor:IViewCursor = children.createCursor();
+ while (!cursor.afterLast)
+ {
+ curr = cursor.current;
+ stack.push(curr);
+ if (isBranch(curr) && isItemOpen(curr))
+ {
+ getOpenChildrenStack(curr, stack);
+ }
+ cursor.moveNext();
+ }
+ return stack;
+ } */
+
+ /**
+ * @private
+ * Finds the index distance between a parent and child
+ */
+ /* private function getChildIndexInParent(parent:Object, child:Object):int
+ {
+ var index:int = 0;
+ if (!parent)
+ {
+ var cursor:IViewCursor = ICollectionView(iterator.view).createCursor();
+ while (!cursor.afterLast)
+ {
+ if (child === cursor.current)
+ break;
+ index++;
+ cursor.moveNext();
+ }
+ }
+ else
+ {
+ if (parent != null &&
+ _dataDescriptor.isBranch(parent, iterator.view) &&
+ _dataDescriptor.hasChildren(parent, iterator.view))
+ {
+ var children:ICollectionView = getChildren(parent, iterator.view);
+ if (children.contains(child))
+ {
+ cursor = children.createCursor();
+ while (!cursor.afterLast)
+ {
+ if (child === cursor.current)
+ break;
+ cursor.moveNext();
+ index++;
+ }
+
+ }
+ else
+ {
+ //throw new Error("Parent item does not contain specified child: " + itemToUID(child));
+ }
+ }
+ }
+ return index;
+ } */
+
+ /**
+ * @private
+ * Collapses those items in the selected items array that have
+ * parent nodes already selected.
+ */
+ /* private function collapseSelectedItems():Array
+ {
+ var collection:ArrayCollection = new ArrayCollection(selectedItems);
+
+ for (var i:int = 0; i < selectedItems.length; i++)
+ {
+ var item:Object = selectedItems[i];
+ var stack:Array = getParentStack(item);
+ for (var j:int = 0; j < stack.length; j++)
+ {
+ if (collection.contains(stack[j]))
+ {
+ //item's parent is included in the selected item set
+ var index:int = collection.getItemIndex(item);
+ var removed:Object = collection.removeItemAt(index);
+ break;
+ }
+ }
+ }
+ return collection.source;
+ } */
+
+ /**
+ * @private
+ */
+ /* private function updateDropData(event:DragEvent):void
+ {
+ var rowCount:int = rowInfo.length;
+ var rowNum:int = 0;
+ var yy:int = rowInfo[rowNum].height;
+ var pt:Point = globalToLocal(new Point(event.stageX, event.stageY));
+ while (rowInfo[rowNum] && pt.y >= yy)
+ {
+ if (rowNum != rowInfo.length-1)
+ {
+ rowNum++;
+ yy += rowInfo[rowNum].height;
+ }
+ else
+ {
+ // now we're past all rows. adding a pixel or two should be enough.
+ // at this point yOffset doesn't really matter b/c we're past all elements
+ // but might as well try to keep it somewhat correct
+ yy += rowInfo[rowNum].height;
+ rowNum++;
+ }
+ }
+
+ var lastRowY:Number = rowNum < rowInfo.length ? rowInfo[rowNum].y : (rowInfo[rowNum-1].y + rowInfo[rowNum-1].height);
+ var yOffset:Number = pt.y - lastRowY;
+ var rowHeight:Number = rowNum < rowInfo.length ? rowInfo[rowNum].height : rowInfo[rowNum-1].height;
+
+ rowNum += verticalScrollPosition;
+
+ var parent:Object;
+ var index:int;
+ var emptyFolder:Boolean = false;
+ var numItems:int = collection ? collection.length : 0;
+
+ var topItem:Object = (rowNum > _verticalScrollPosition && rowNum <= numItems) ?
+ listItems[rowNum - _verticalScrollPosition - 1][0].data : null;
+ var bottomItem:Object = (rowNum - verticalScrollPosition < rowInfo.length && rowNum < numItems) ?
+ listItems[rowNum - _verticalScrollPosition][0].data : null;
+
+ var topParent:Object = collection ? getParentItem(topItem) : null;
+ var bottomParent:Object = collection ? getParentItem(bottomItem) : null;
+
+ // check their relationship
+ if (yOffset > rowHeight * .5 &&
+ isItemOpen(bottomItem) &&
+ _dataDescriptor.isBranch(bottomItem, iterator.view) &&
+ (!_dataDescriptor.hasChildren(bottomItem, iterator.view) ||
+ _dataDescriptor.getChildren(bottomItem, iterator.view).length == 0))
+ {
+ // we'll get here if we're dropping into an empty folder.
+ // we have to be in the lower 50% of the row, otherwise
+ // we're "between" rows.
+ parent = bottomItem;
+ index = 0;
+ emptyFolder = true;
+ }
+ else if (!topItem && !rowNum == rowCount)
+ {
+ parent = collection ? getParentItem(bottomItem) : null;
+ index = bottomItem ? getChildIndexInParent(parent, bottomItem) : 0;
+ rowNum = 0;
+ }
+ else if (bottomItem && bottomParent == topItem)
+ {
+ // we're dropping in the first item of a folder, that's an easy one
+ parent = topItem;
+ index = 0;
+ }
+ else if (topItem && bottomItem && topParent == bottomParent)
+ {
+ parent = collection ? getParentItem(topItem) : null;
+ index = iterator ? getChildIndexInParent(parent, bottomItem) : 0;
+ }
+ else
+ {
+ //we're dropping at the end of a folder. Pay attention to the position.
+ if (topItem && (yOffset < (rowHeight * .5)))
+ {
+ // ok, we're on the top half of the bottomItem.
+ parent = topParent;
+ index = getChildIndexInParent(parent, topItem) + 1; // insert after
+ }
+ else if (!bottomItem)
+ {
+ parent = null;
+ if ((rowNum - verticalScrollPosition) == 0)
+ index = 0;
+ else if (collection)
+ index = collection.length;
+ else index = 0;
+ }
+ else
+ {
+ parent = bottomParent;
+ index = getChildIndexInParent(parent, bottomItem);
+ }
+ }
+ _dropData = { parent: parent, index: index, localX: event.localX, localY: event.localY,
+ emptyFolder: emptyFolder, rowHeight: rowHeight, rowIndex: rowNum };
+ } */
+
+ /**
+ * Initializes a TreeListData object that is used by the tree item renderer.
+ *
+ * @param item The item to be rendered.
+ * @param treeListData The TreeListDataItem to use in rendering the item.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* protected function initListData(item:Object, treeListData:TreeListData):void
+ {
+ if (item == null)
+ return;
+
+ var open:Boolean = isItemOpen(item);
+ var branch:Boolean = isBranch(item);
+ var uid:String = itemToUID(item);
+
+ // this is hidden by non-branches but kept so we know how wide it is so things align
+ treeListData.disclosureIcon = getStyle(open ? "disclosureOpenIcon" :
+ "disclosureClosedIcon");
+ treeListData.open = open;
+ treeListData.hasChildren = branch;
+ treeListData.depth = getItemDepth(item, treeListData.rowIndex);
+ treeListData.indent = (treeListData.depth - 1) * getStyle("indentation");
+ treeListData.item = item;
+ treeListData.icon = itemToIcon(item);
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden event handlers
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ /* override protected function layoutEditor(x:int, y:int, w:int, h:int):void
+ {
+ var indent:int = rowMap[editedItemRenderer.name].indent;
+ itemEditorInstance.move(x + indent, y);
+ itemEditorInstance.setActualSize(w - indent, h);
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function scrollHandler(event:Event):void
+ {
+ if (isOpening)
+ return;
+
+ // TextField.scroll bubbles so you might see it here
+ if (event is ScrollEvent)
+ super.scrollHandler(event);
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function keyDownHandler(event:KeyboardEvent):void
+ {
+ var evt:ListEvent;
+ var pt:Point;
+
+ if (isOpening)
+ {
+ event.stopImmediatePropagation();
+ return;
+ }
+
+ if (itemEditorInstance)
+ return;
+
+ // If rtl layout, need to swap LEFT and RIGHT so correct action
+ // is done.
+ var keyCode:uint = mapKeycodeForLayoutDirection(event);
+
+ // Keyboard handling is consistent with Windows Explorer.
+ var item:Object = selectedItem;
+ if (event.ctrlKey)
+ {
+ // Ctrl keys always get sent to the List.
+ super.keyDownHandler(event);
+ }
+ else if (keyCode == Keyboard.SPACE)
+ {
+ // if user has moved the caret cursor from the selected item
+ // move the cursor back to selected item
+ if (caretIndex != selectedIndex)
+ {
+ // erase the caret
+ var renderer:IListItemRenderer = indexToItemRenderer(caretIndex);
+ if (renderer)
+ drawItem(renderer);
+ caretIndex = selectedIndex;
+ }
+
+ // Spacebar toggles the current open/closed status. No effect for leaf items.
+ if (isBranch(item))
+ {
+ var o:Boolean = !isItemOpen(item);
+ dispatchTreeEvent(TreeEvent.ITEM_OPENING,
+ item, //item
+ null, //renderer
+ event, //trigger
+ o, //opening
+ true, //animate
+ true); //dispatch
+ }
+ event.stopImmediatePropagation();
+ }
+ else if (keyCode == Keyboard.LEFT)
+ {
+ // Left Arrow closes an open item.
+ // Otherwise, selects the parent item if there is one.
+ if (isItemOpen(item))
+ {
+ dispatchTreeEvent(TreeEvent.ITEM_OPENING,
+ item, //item
+ null, //renderer
+ event, //trigger
+ false, //opening
+ true, //animate
+ true) //dispatch
+ }
+ else
+ {
+ var parentItem:Object = getParentItem(item);
+ if (parentItem)
+ {
+ proposedSelectedItem = parentItem;
+ finishArrowKeySelection();
+ }
+ }
+ event.stopImmediatePropagation();
+ }
+ else if (keyCode == Keyboard.RIGHT)
+ {
+ // Right Arrow has no effect on leaf items. Closed branch items are opened.
+ //Opened branch items select the first child.
+ if (isBranch(item))
+ {
+ if (isItemOpen(item))
+ {
+ if (item)
+ {
+ var children:ICollectionView = getChildren(item, iterator.view);
+ if (children)
+ {
+ var cursor:IViewCursor = children.createCursor();
+ if (cursor.current)
+ proposedSelectedItem = cursor.current;
+ }
+ else
+ proposedSelectedItem = null;
+ }
+ else
+ selectedItem = proposedSelectedItem = null;
+
+ finishArrowKeySelection();
+ }
+ else
+ {
+ dispatchTreeEvent(TreeEvent.ITEM_OPENING,
+ item, //item
+ null, //renderer
+ event, //trigger
+ true, //opening
+ true, //animate
+ true); //dispatch
+ }
+ }
+ event.stopImmediatePropagation();
+ }
+ else if (keyCode == Keyboard.NUMPAD_MULTIPLY)
+ {
+ expandChildrenOf(item, !isItemOpen(item));
+ }
+ else if (keyCode == Keyboard.NUMPAD_ADD)
+ {
+ if (isBranch(item))
+ {
+ if (!isItemOpen(item))
+ {
+ dispatchTreeEvent(TreeEvent.ITEM_OPENING,
+ item, //item
+ null, //renderer
+ event, //trigger
+ true, //opening
+ true, //animate
+ true); //dispatch
+ }
+ }
+ }
+ else if (keyCode == Keyboard.NUMPAD_SUBTRACT)
+ {
+ if (isItemOpen(item))
+ {
+ dispatchTreeEvent(TreeEvent.ITEM_OPENING,
+ item, //item
+ null, //renderer
+ event, //trigger
+ false, //opening
+ true, //animate
+ true); //dispatch
+ }
+ }
+ else
+ {
+ // Nothing that we know or care about. Send it off to the List.
+ super.keyDownHandler(event);
+ }
+ } */
+
+ /**
+ * @private
+ * finish up left/right arrow key handling
+ */
+ /* private function finishArrowKeySelection():void
+ {
+ bFinishArrowKeySelection = false;
+
+ if (proposedSelectedItem)
+ selectedItem = proposedSelectedItem;
+
+ // now test to see if it worked, if it didn't we probably
+ // got an IPE
+ if (selectedItem === proposedSelectedItem || !proposedSelectedItem)
+ {
+ var evt:ListEvent;
+ var pt:Point;
+ evt = new ListEvent(ListEvent.CHANGE);
+ evt.itemRenderer = indexToItemRenderer(selectedIndex);
+ pt = itemRendererToIndices(evt.itemRenderer);
+ if (pt)
+ {
+ evt.rowIndex = pt.y;
+ evt.columnIndex = pt.x;
+ }
+ dispatchEvent(evt);
+ var dI:int = getItemIndex(selectedItem);
+ if (dI != caretIndex)
+ {
+ caretIndex = selectedIndex;
+ }
+ if (dI < _verticalScrollPosition)
+ {
+ verticalScrollPosition = dI;
+ }
+ }
+ else
+ {
+ bFinishArrowKeySelection = true;
+ }
+ } */
+
+
+ /**
+ * @private
+ * Blocks mouse events on items that are tweening away and are invalid for input
+ */
+ /* override protected function mouseOverHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseOverHandler(event);
+ } */
+
+ /**
+ * @private
+ * Blocks mouse events on items that are tweening away and are invalid for input
+ */
+ /* override protected function mouseOutHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseOutHandler(event);
+ } */
+
+ /**
+ * @private
+ * Blocks mouse events on items that are tweening away and are invalid for input
+ */
+ /* override protected function mouseClickHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseClickHandler(event);
+ } */
+
+ /**
+ * @private
+ * Blocks mouse events on items that are tweening away and are invalid for input
+ */
+ /* override protected function mouseDoubleClickHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseDoubleClickHandler(event);
+ } */
+
+ /**
+ * @private
+ * Blocks mouse events on items that are tweening away and are invalid for input
+ */
+ /* override protected function mouseDownHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseDownHandler(event);
+ } */
+
+ /**
+ * @private
+ * Blocks mouse events on items that are tweening away and are invalid for input
+ */
+ /* override protected function mouseUpHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseUpHandler(event);
+ } */
+
+ /**
+ * @private
+ * Blocks mouse wheel handling while tween is running
+ */
+ /* override protected function mouseWheelHandler(event:MouseEvent):void
+ {
+ if (!tween)
+ super.mouseWheelHandler(event);
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function dragEnterHandler(event:DragEvent):void
+ {
+ if (event.isDefaultPrevented())
+ return;
+
+ lastDragEvent = event;
+ haveItemIndices = false;
+
+ try
+ {
+ if (iteratorValid && event.dragSource.hasFormat("treeItems"))
+ {
+ //if (collectionThrowsIPE)
+ //checkItemIndices(event);
+
+ DragManager.acceptDragDrop(this);
+ DragManager.showFeedback(event.ctrlKey ?
+ DragManager.COPY :
+ DragManager.MOVE);
+ showDropFeedback(event);
+ return;
+ }
+ }
+ catch(e:ItemPendingError)
+ {
+ if (!lastTreeSeekPending)
+ {
+ lastTreeSeekPending = new TreeSeekPending(event, dragEnterHandler)
+ e.addResponder(new ItemResponder(seekPendingDuringDragResultHandler, seekPendingDuringDragFailureHandler,
+ lastTreeSeekPending));
+ }
+ }
+ catch(e1:Error)
+ {
+ }
+ hideDropFeedback(event);
+ DragManager.showFeedback(DragManager.NONE);
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function dragOverHandler(event:DragEvent):void
+ {
+ if (event.isDefaultPrevented())
+ return;
+
+ lastDragEvent = event;
+
+ try
+ {
+ if (iteratorValid && event.dragSource.hasFormat("treeItems"))
+ {
+ if (collectionThrowsIPE)
+ checkItemIndices(event);
+
+ DragManager.showFeedback(event.ctrlKey ?
+ DragManager.COPY :
+ DragManager.MOVE);
+ showDropFeedback(event);
+ return;
+ }
+ }
+ catch(e:ItemPendingError)
+ {
+ if (!lastTreeSeekPending)
+ {
+ lastTreeSeekPending = new TreeSeekPending(event, dragOverHandler)
+ e.addResponder(new ItemResponder(seekPendingDuringDragResultHandler, seekPendingDuringDragFailureHandler,
+ lastTreeSeekPending));
+ }
+ }
+ catch(e1:Error)
+ {
+ }
+ hideDropFeedback(event);
+ DragManager.showFeedback(DragManager.NONE);
+ } */
+
+ /**
+ * @private
+ * The default failure handler when a seek fails due to a page fault.
+ */
+ /* private function seekPendingDuringDragFailureHandler(data:Object,
+ info:TreeSeekPending):void
+ {
+ } */
+
+ /**
+ * @private
+ * The default result handler when a seek fails due to a page fault.
+ * This method re-attempts setting the drag feedback
+ */
+ /* private function seekPendingDuringDragResultHandler(data:Object,
+ info:TreeSeekPending):void
+ {
+ lastTreeSeekPending = null;
+
+ if (lastDragEvent)
+ info.retryFunction(info.event);
+ } */
+
+ /**
+ * @private
+ */
+ /* private function checkItemIndices(event:DragEvent):void
+ {
+ if (haveItemIndices)
+ return;
+
+ // if we're moving to ourselves, we need to make sure we have
+ // everything paged below before we allow a drop
+ if ((event.action == DragManager.MOVE || event.action == DragManager.NONE) && dragMoveEnabled)
+ {
+ if (event.dragInitiator == this)
+ {
+ var items:Array = event.dragSource.dataForFormat("treeItems") as Array;
+ var n:int = items.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var parent:Object = getParentItem(items[i]);
+ getChildIndexInParent(parent, items[i]);
+ }
+ haveItemIndices = true;
+ }
+ }
+ } */
+
+ /**
+ * Handles <code>DragEvent.DRAG_DROP events</code>. This method hides
+ * the drop feedback by calling the <code>hideDropFeedback()</code> method.
+ *
+ * <p>If the action is a <code>COPY</code>,
+ * then this method makes a deep copy of the object
+ * by calling the <code>ObjectUtil.copy()</code> method,
+ * and replaces the copy's <code>uid</code> property (if present)
+ * with a new value by calling the <code>UIDUtil.createUID()</code> method.</p>
+ *
+ * @param event The DragEvent object.
+ *
+ * @see mx.utils.ObjectUtil
+ * @see mx.utils.UIDUtil
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* override protected function dragDropHandler(event:DragEvent):void
+ {
+ if (event.isDefaultPrevented())
+ return;
+
+ hideDropFeedback(event);
+
+ if (event.dragSource.hasFormat("treeItems"))
+ {
+ var items:Array = event.dragSource.dataForFormat("treeItems") as Array;
+ var i:int;
+ var n:int;
+
+ // if we're moving to ourselves, we need to treat it specially and check for "parent"
+ // problems where we could recurse forever.
+ if (event.action == DragManager.MOVE && dragMoveEnabled)
+ {
+ if (event.dragInitiator == this)
+ {
+ // If we're dropping onto ourselves or a child of a descendant then dont actually drop
+
+ calculateDropIndex(event);
+
+ // If we did start this drag op then we need to remove first
+ var index:int;
+ var parent:*;
+ var parentItem:*;
+ var dropIndex:int = _dropData.index;
+
+ //get ancestors of the drop target item
+ var dropParentStack:Array = getParentStack(_dropData.parent);
+ dropParentStack.unshift(_dropData.parent);
+
+ n = items.length;
+ for (i = 0; i < n; i++)
+ {
+ parent = getParentItem(items[i]);
+ index = getChildIndexInParent(parent, items[i]);
+ //check ancestors of the dropTarget if the item matches, we're invalid
+
+ for each (parentItem in dropParentStack)
+ {
+ //we dont want to drop into one of our own sets of children
+ if (items[i] === parentItem)
+ return;
+ }
+
+ //we remove before we add due to the behavior
+ //of structures with parent pointers like e4x
+ removeChildItem(parent, items[i], index);
+
+ //is the removed item before the drop location?
+ // then we need to shift the dropIndex accordingly
+ if (parent == _dropData.parent && index < _dropData.index)
+ dropIndex--;
+
+ addChildItem(_dropData.parent, items[i], dropIndex);
+ }
+
+ return;
+ }
+ }
+
+ // If not dropping onto ourselves, then add the
+ // items here if it's a copy operation.
+ // If it's a move operation (and not on ourselves), then they
+ // are added in dragCompleteHandler and are removed from
+ // the source's dragCompleteHandler. We do both in dragCompleteHandler
+ // because in order to be re-parented, they must be removed from their
+ // original source FIRST. This means our code isn't coupled fantastically
+ // as dragCompleteHandler must get the destination tree and
+ // cast it to a Tree.
+
+ if (event.action == DragManager.COPY)
+ {
+ if (!dataProvider) {
+ // Create an empty collection to drop items into.
+ dataProvider = [];
+ validateNow();
+ }
+
+ n = items.length;
+ for (i = 0; i < n; i++)
+ {
+ var item:Object = copyItemWithUID(items[i]);
+
+ addChildItem(_dropData.parent,
+ item,
+ _dropData.index);
+ }
+ }
+ }
+ lastDragEvent = null;
+ } */
+
+ /**
+ * Handles <code>DragEvent.DRAG_COMPLETE</code> events. This method
+ * removes the item from the data provider.
+ *
+ * @param event The DragEvent object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* override protected function dragCompleteHandler(event:DragEvent):void
+ {
+ isPressed = false;
+
+ if (event.isDefaultPrevented())
+ return;
+
+ resetDragScrolling()
+
+ try
+ {
+ if (event.dragSource.hasFormat("treeItems"))
+ {
+ // if we've moved the elements, then remove them here
+ if (event.action == DragManager.MOVE && dragMoveEnabled)
+ {
+ // if we moved onto ourselves, we already handled this in
+ // dragDropHandler
+ if (event.relatedObject != this)
+ {
+ var items:Array = event.dragSource.dataForFormat("treeItems") as Array;
+ var parent:*;
+ var index:int;
+ var i:int;
+ var n:int;
+
+ //do the remove
+ n = items.length;
+ for (i = 0; i < n; i++)
+ {
+ parent = getParentItem(items[i]);
+ index = getChildIndexInParent(parent, items[i]);
+ removeChildItem(parent, items[i], index);
+ }
+
+ // then add it to the target control (copy operations are
+ // handled in the target's dragDropHandler), but the MOVE
+ // operations need to be handled here (see comment in
+ // dragDropHandler about this)
+ if (event.relatedObject is Tree)
+ {
+ var targetTree:Tree = Tree(event.relatedObject);
+ if (!targetTree.dataProvider) {
+ // Create an empty collection to drop items into.
+ targetTree.dataProvider = [];
+ targetTree.validateNow();
+ }
+
+ n = items.length;
+ for (i = 0; i < n; i++)
+ {
+ var item:Object = items[i];
+
+ targetTree.addChildItem(targetTree._dropData.parent,
+ item,
+ targetTree._dropData.index);
+ }
+ }
+ }
+ clearSelected(false);
+ }
+ }
+ }
+ catch(e:ItemPendingError)
+ {
+ e.addResponder(new ItemResponder(seekPendingDuringDragResultHandler, seekPendingDuringDragFailureHandler,
+ new TreeSeekPending(event, dragCompleteHandler)));
+ }
+ lastDragEvent = null;
+ } */
+
+ /**
+ * @private
+ * Delegates to the Descriptor to add a child to a parent
+ */
+ /* mx_internal function addChildItem(parent:Object, child:Object, index:Number):Boolean
+ {
+ return _dataDescriptor.addChildAt(parent, child, index, iterator.view);
+ } */
+
+ /**
+ * @private
+ * Delegates to the Descriptor to remove a child from a parent
+ */
+ /* mx_internal function removeChildItem(parent:Object, child:Object, index:Number):Boolean
+ {
+ return _dataDescriptor.removeChildAt(parent, child, index, iterator.view);
+ } */
+
+ /**
+ * @private
+ */
+ /* mx_internal function dispatchTreeEvent(type:String,
+ item:Object,
+ renderer:IListItemRenderer,
+ trigger:Event = null,
+ opening:Boolean = true,
+ animate:Boolean = true,
+ dispatch:Boolean = true):void
+ {
+ var event:TreeEvent;
+
+ // Create expanding event.
+ if (type == TreeEvent.ITEM_OPENING)
+ {
+ event = new TreeEvent(TreeEvent.ITEM_OPENING,
+ false, true);
+ event.opening = opening;
+ event.animate = animate;
+ event.dispatchEvent = dispatch;
+ }
+
+ // Create all other events.
+ if (!event)
+ event = new TreeEvent(type);
+
+ // Common values.
+ event.item = item;
+ event.itemRenderer = renderer;
+ event.triggerEvent = trigger;
+
+ // Send it off.
+ dispatchEvent(event);
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Event handlers
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Handler for CollectionEvents dispatched from the root dataProvider as the data changes.
+ */
+ /* override protected function collectionChangeHandler(event:Event):void
+ {
+ //if the iterator is null that indicates we havent been validated yet so we'll bail.
+ if (iterator == null)
+ return;
+
+ var node:Object;
+ var parent:Object;
+
+ if (event is CollectionEvent)
+ {
+ var ce:CollectionEvent = CollectionEvent(event);
+
+ if (ce.kind == CollectionEventKind.EXPAND)
+ {
+ //we ignore expand in list/tree
+ event.stopPropagation();
+ }
+ if (ce.kind == CollectionEventKind.UPDATE)
+ {
+ //this prevents listbase from invalidating the displaylist too early.
+ event.stopPropagation();
+ //we only want to update the displaylist if an updated item was visible
+ //but dont have a sufficient test for that yet
+ itemsSizeChanged = true;
+ invalidateDisplayList();
+ }
+ else
+ {
+ super.collectionChangeHandler(event);
+ }
+ }
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function adjustAfterRemove(items:Array, location:int, emitEvent:Boolean):Boolean
+ {
+ var indicesLength:int = selectedItems.length;
+ var requiresValueCommit:Boolean = emitEvent;
+ var length:int = items.length;
+
+ if (_selectedIndex > location)
+ {
+ _selectedIndex -= length;
+ requiresValueCommit = true;
+ }
+
+ if (bSelectedItemRemoved && indicesLength < 1)
+ {
+ _selectedIndex = getItemIndex(expandedItem);
+ requiresValueCommit = true;
+ bSelectionChanged = true;
+ bSelectedIndexChanged = true;
+ invalidateDisplayList();
+ }
+
+ return requiresValueCommit;
+ } */
+
+ /**
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* mx_internal function expandItemHandler(event:TreeEvent):void
+ {
+ if (event.isDefaultPrevented())
+ return;
+
+ if (event.type == TreeEvent.ITEM_OPENING)
+ {
+ expandItem(event.item, event.opening, event.animate, event.dispatchEvent, event.triggerEvent);
+ }
+ } */
+
+ /**
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.3
+ */
+ /* override mx_internal function selectionDataPendingResultHandler(
+ data:Object,
+ info:ListBaseSelectionDataPending):void
+ {
+ super.selectionDataPendingResultHandler(data, info);
+ if (bFinishArrowKeySelection && selectedItem === proposedSelectedItem)
+ finishArrowKeySelection();
+ } */
+}
+
+}
+
+/* import mx.events.DragEvent;
+
+class TreeSeekPending
+{
+ public function TreeSeekPending(event:DragEvent, retryFunction:Function)
+ {
+ this.event = event;
+ this.retryFunction = retryFunction;
+ }
+
+ public var event:DragEvent;
+
+ public var retryFunction:Function;
+
+}
+ */
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
alinakazi@apache.org.