2020-10-20 00:58:15 +02:00

381 lines
12 KiB
ActionScript
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Copyright (c) 2009 Yahoo! Inc. All rights reserved.
The copyrights embodied in the content of this file are licensed under the BSD (revised) open source license
*/
package com.yahoo.astra.fl.controls {
import com.yahoo.astra.fl.controls.treeClasses.*;
import com.yahoo.astra.fl.events.TreeEvent;
import fl.controls.List;
import fl.controls.listClasses.*;
import fl.core.InvalidationType;
import fl.data.DataProvider;
import fl.events.*;
import flash.display.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
//--------------------------------------
// Class description
//--------------------------------------
/**
* The Tree class creates a List-based Tree component that displays hierarchical information.
* The Tree rendering is achieved via a custom TreeDataProvider that receives and parses an XML data structure,
* the TreeNode data structure, and a supplied TreeCellRenderer (though other CellRenderers can be used in lieu
* of the default one.)
*
* @author Allen Rabinovich
* @see com.yahoo.astra.fl.controls.treeClasses.TreeDataProvider
* @see com.yahoo.astra.fl.controls.treeClasses.TreeCellRenderer
* @see com.yahoo.astra.fl.controls.treeClasses.TNode
* @see com.yahoo.astra.fl.controls.treeClasses.BranchNode
* @see com.yahoo.astra.fl.controls.treeClasses.LeafNode
*/
public class Tree extends List {
/**
* The name of the field in the data object that contains information about an icon to use for a leaf node
*/
public var leafIconField:String = "leafIcon";
/**
* The name of the field in the data object that contains information about an icon to use for an open branch node
*/
public var openBranchIconField:String = "openBranchIcon";
/**
* The name of the field in the data object that contains information about an icon to use for a closed branch node
*/
public var closedBranchIconField:String = "closedBranchIcon";
//--------------------------------------------------------------------------
//
// Class methods
//
//--------------------------------------------------------------------------
/**
* Creates and returns an instance of the Tree class. The Tree control's content
* is determined by assigning a TreeDataProvider to the dataProvider field of
* the Tree class.
*
* To display the Tree, add it as a child to your current display list or drag an instance
* of the Tree onto Stage.
*
* @return An instance of the Tree class.
*
* @see com.yahoo.astra.fl.controls.treeClasses.TreeDataProvider
*/
public function Tree() {
super();
// The default processor of item click events is nodeClick function
addEventListener(ListEvent.ITEM_CLICK, nodeClick);
addEventListener(ListEvent.ITEM_DOUBLE_CLICK, nodeClick);
setStyle('cellRenderer', TreeCellRenderer);
}
/**
* Opens all nodes at all levels in the Tree.
*
*/
public function openAllNodes () : void {
var visibleNodes:Array = dataProvider.toArray();
for each (var node:TNode in visibleNodes) {
if (!(node is LeafNode) && (node.nodeLevel == 0)) {
node.openAllChildren();
}
}
}
/**
* Closes all nodes at all levels in the Tree.
*
*/
public function closeAllNodes () : void {
var visibleNodes:Array = dataProvider.toArray();
for each (var node:TNode in visibleNodes) {
if (!(node is LeafNode) && (node.nodeLevel == 0)) {
node.closeAllChildren();
}
}
}
/**
* Finds the first instance of the node in the tree where
* the value in the field designated by <code>fieldName</code>
* is equal to <code>fieldValue</code>
*
* @param fieldName The name of the field in the node object to check.
* @param fieldValue The value to look for in the specified field.
*
* @return A node that contains the given value in the specified field; or null if
* no such node is found.
*
*/
public function findNode (fieldName:String, fieldValue:String) : TNode {
var visibleNodes:Array = dataProvider.toArray();
for each (var node:TNode in visibleNodes) {
if (node.nodeLevel == 0) {
var foundNode:TNode = node.checkForValue(fieldName, fieldValue);
if (foundNode != null) {
return foundNode;
}
}
}
return null;
}
/**
* Opens all parent nodes of a specified node, so that the specified
* node becomes visible.
*
* @param foundNode The node to be made visible.
*
* @return The index of the node in the current view of the Tree (this is the
* absolute index: i.e., the number of the nodes visible above the specified node.)
*
*/
public function showNode (foundNode:TNode) : int {
if (foundNode != null) {
var parentPointer:TNode = foundNode.parentNode;
while (!(parentPointer is RootNode)) {
parentPointer.openNode();
parentPointer = parentPointer.parentNode;
}
var foundIndex:int = dataProvider.getItemIndex(foundNode);
return foundIndex;
}
return -1;
}
/**
* Finds the first instance of the node in the tree where
* the value in the field designated by <code>fieldName</code>
* is equal to <code>fieldValue</code> and opens all parent nodes
* of the found node, so that the found node becomes visible.
*
* @param fieldName The name of the field in the node object to check.
* @param fieldValue The value to look for in the specified field.
*
* @return A node that contains the given value in the specified field; or null if
* no such node is found.
*
*/
public function exposeNode (fieldName:String, fieldValue:String) : TNode {
var foundNode:TNode = findNode(fieldName, fieldValue);
if (foundNode != null) {
showNode(foundNode);
return(foundNode);
}
return null;
}
/**
* Toggles a specified branch node to change state:
* if the node is open, it would close, and vice versa.
* <p>This method is deprecated. Use <code>BranchNode.openNode()</code>
* and <code>BranchNode.closeNode()</code> instead.</p>
*
* @param node The node that should be triggered.
*
* @see com.yahoo.astra.fl.controls.treeClasses.BranchNode
*/
public function toggleNode (node:BranchNode) : void {
if (node.nodeState == TreeDataProvider.OPEN_NODE) {
node.closeNode();
}
else {
node.openNode();
}
}
/**
* @private
* Default Node click behavior
*/
private function nodeClick(event:ListEvent):void {
var dp:TreeDataProvider = dataProvider as TreeDataProvider;
var node:Object = dp.getItemAt(event.index);
dp.toggleNode(event.index);
}
/**
* Gets or sets the name of the field in the <code>dataProvider</code> object
* to be displayed as the label for the TextInput field and drop-down list.
*
* <p>By default, the component displays the <code>label</code> property
* of each <code>dataProvider</code> item. If the <code>dataProvider</code>
* items do not contain a <code>label</code> property, you can set the
* <code>labelField</code> property to use a different property.</p>
*
* <p><strong>Note:</strong> The <code>labelField</code> property is not used
* if the <code>labelFunction</code> property is set to a callback function.</p>
*
* @default "label"
*
* @see #labelFunction
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override public function get labelField():String {
return _labelField;
}
/**
* @private
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override public function set labelField(value:String):void {
if (value == _labelField) { return; }
if (value.substr(0,1) == "@") {
_labelField = value.substr(1);
}
else {
_labelField = value;
}
invalidate(InvalidationType.DATA);
}
/**
* Gets or sets the data model of the Tree of items to be displayed.
* The Tree dataProvider is required to be of type TreeDataProvider.
* Changes to the data provider are immediately available to all Tree
* components that use it as a data source.
*
* @default null
*
* @see com.yahoo.astra.fl.controls.treeClasses.TreeDataProvider
*/
override public function get dataProvider () : DataProvider {
return _dataProvider;
}
override public function set dataProvider(value:DataProvider):void {
if ((value is DataProvider && value.length == 0) || value is TreeDataProvider) {
if (_dataProvider != null) {
_dataProvider.removeEventListener(DataChangeEvent.DATA_CHANGE,handleDataChange);
_dataProvider.removeEventListener(DataChangeEvent.PRE_DATA_CHANGE, onPreChange);
}
_dataProvider = value;
_dataProvider.addEventListener(DataChangeEvent.DATA_CHANGE,handleDataChange,false,0,true);
_dataProvider.addEventListener(DataChangeEvent.PRE_DATA_CHANGE,onPreChange,false,0,true);
clearSelection();
invalidateList();
}
else {
throw new TypeError("Error: Type Coercion failed: cannot convert " + value + " to TreeDataProvider.");
}
}
/**
* @private (protected)
*
* @langversion 3.0
* @playerversion Flash 9.0.28.0
*/
override protected function keyDownHandler(event:KeyboardEvent):void {
if (!selectable) { return; }
switch (event.keyCode) {
case Keyboard.UP:
case Keyboard.DOWN:
case Keyboard.END:
case Keyboard.HOME:
case Keyboard.PAGE_UP:
case Keyboard.PAGE_DOWN:
moveSelectionVertically(event.keyCode, event.shiftKey && _allowMultipleSelection, event.ctrlKey && _allowMultipleSelection);
break;
case Keyboard.LEFT:
case Keyboard.RIGHT:
case Keyboard.SPACE:
case Keyboard.ENTER:
if(caretIndex == -1) {
caretIndex = 0;
}
//doKeySelection(caretIndex, event.shiftKey, event.ctrlKey);
//scrollToSelected();
var renderer:TreeCellRenderer = event.currentTarget as TreeCellRenderer;
var node:TNode = selectedItem as TNode;
if(node is BranchNode)
{
var branchNode:BranchNode = node as BranchNode;
if (branchNode.isOpen())
{
branchNode.closeNode();
var closeEvent:TreeEvent = new TreeEvent(TreeEvent.ITEM_CLOSE);
closeEvent.triggerEvent = event;
closeEvent.itemRenderer = renderer;
dispatchEvent(closeEvent);
}
else
{
branchNode.openNode();
var openEvent:TreeEvent = new TreeEvent(TreeEvent.ITEM_OPEN);
openEvent.triggerEvent = event;
openEvent.itemRenderer = renderer;
dispatchEvent(openEvent);
}
}
// }
break;
default:
var nextIndex:int = getNextIndexAtLetter(String.fromCharCode(event.keyCode), selectedIndex);
if (nextIndex > -1) {
selectedIndex = nextIndex;
scrollToSelected();
}
break;
}
event.stopPropagation();
}
//--------------------------------------------------------------------------
//
// Accessibility
//
//--------------------------------------------------------------------------
/**
* Placeholder for mixin by TreeAccImpl.
*/
public static var createAccessibilityImplementation:Function;
/**
* @inheritDoc
*/
override protected function initializeAccessibility():void
{
if (Tree.createAccessibilityImplementation != null)
Tree.createAccessibilityImplementation(this);
}
}
}