forked from arpit/openpyro
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTreeCollection.as
More file actions
230 lines (193 loc) · 6.19 KB
/
TreeCollection.as
File metadata and controls
230 lines (193 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
package org.openPyro.collections
{
import org.openPyro.collections.events.CollectionEvent;
import org.openPyro.collections.events.CollectionEventKind;
import org.openPyro.utils.ArrayUtil;
/**
* The TreeCollection class is a ICollection that can be used by controls
* like Tree etc that represent Heirarchial collections. Under the hood,
* the TreeCollection maintains an XMLCollection of the data XML that it
* was initialized with and a mappedArrayCollection that is actually reflected
* to the UI.
*/
public class TreeCollection extends CollectionBase implements ICollection
{
private var _xml:XML;
private var _iterator:ArrayIterator;
private var _mappedArrayCollection:ArrayCollection;
private var originalDataSource:XMLCollection;
private var allXMLNodeDescriptors:Array = []
public function TreeCollection(xml:XML=null)
{
if(xml){
source = xml;
}
}
protected function parseNode(node:XML, depth:int, parentNodeDescriptor:XMLNodeDescriptor):void{
var desc:XMLNodeDescriptor = new XMLNodeDescriptor()
desc.node = node
desc.depth = depth
desc.parent = parentNodeDescriptor;
_mappedArrayCollection.addItem(node);
allXMLNodeDescriptors.push(desc);
depth++;
_uids.push({uid:createUID(), sourceItem:desc});
for(var i:int=0; i<node.elements("*").length(); i++){
parseNode(node.elements("*")[i], depth, desc);
}
}
public function get source():*{
return _xml;
}
public function set source(x:*):void{
_xml = x;
_uids = new Array();
_mappedArrayCollection = new ArrayCollection();
allXMLNodeDescriptors = new Array();
originalDataSource = new XMLCollection(x);
parseNode(_xml, 0, null);
if(!_showRoot){
originalDataSource.removeItemAt(0);
_mappedArrayCollection.removeItemAt(0);
ArrayUtil.removeItemAt(_uids, 0);
}
_iterator = new ArrayIterator(_mappedArrayCollection)
dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGED));
}
/**
* Returns the length of the collection as its seen.
*/
public function get length():int
{
return _mappedArrayCollection.length;
}
/**
* @inheritDoc
*/
public function get iterator():IIterator
{
return _iterator;
}
/**
* @inheritDoc
*/
public function getItemIndex(item:Object):int{
return _mappedArrayCollection.getItemIndex(item);
}
public function getNodeDescriptorFor(node:XML):XMLNodeDescriptor{
for(var i:int=0; i<allXMLNodeDescriptors.length; i++){
var src:XMLNodeDescriptor = allXMLNodeDescriptors[i];
if(src.node == node){
return src
}
}
return null;
}
public function getItemAt(idx:int):*{
return _mappedArrayCollection.getItemAt(idx);
}
public function closeNode(nodeDescriptor:XMLNodeDescriptor):void{
var items:Array = [];
nodeDescriptor.open = false;
items = getChildNodesArray(nodeDescriptor.node, items);
removeItems(items);
}
protected function getChildNodesArray(node:XML, arr:Array):Array{
for(var i:int=0; i<node.elements("*").length(); i++){
arr.push(node.elements("*")[i]);
if(node.hasComplexContent()){
getChildNodesArray(node.elements("*")[i], arr);
}
}
return arr;
}
/*
TODO: This is very close to a copy paste
from ArrayCollection
*/
public function removeItems(items:Array):void{
var changed:Boolean = false;
var delta:Array = [];
var location:int = NaN;
for each(var item:* in items){
var itemIndex:Number = getItemIndex(item);
if(itemIndex != -1){
var nodeDes:XMLNodeDescriptor = getNodeDescriptorFor(item);
delta.push(nodeDes);
if(itemIndex < location || isNaN(location)){
location = itemIndex;
}
_mappedArrayCollection.removeItem(item);
for each(var ob:Object in _uids){
if(ob.sourceItem == nodeDes){
ArrayUtil.remove(_uids, ob);
break;
}
}
changed = true;
}
}
if(! changed) return;
var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGED);
event.kind = CollectionEventKind.REMOVE;
event.delta = delta;
event.location = location;
dispatchEvent(event);
}
public function openNode(xmlNodeDescriptor:XMLNodeDescriptor):void{
xmlNodeDescriptor.open = true;
var addedEvent:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGED);
addedEvent.kind = CollectionEventKind.ADD;
addedEvent.location = getItemIndex(xmlNodeDescriptor.node)+1;
var newNodes:Array = [];
var newUIDObs:Array = [];
getSubtree(xmlNodeDescriptor.node, newUIDObs, newNodes);
_mappedArrayCollection.addItemsAt(newNodes, addedEvent.location);
ArrayUtil.insertArrayAtIndex(_uids, newUIDObs, addedEvent.location);
addedEvent.delta = newNodes;
dispatchEvent(addedEvent);
}
private function getSubtree(parentNode:XML, newUIDObs:Array, newNodes:Array):void{
for(var j:int=0; j<parentNode.elements("*").length(); j++){
var newNode:XML = XML(parentNode.elements("*")[j]);
var nodeDescriptor:XMLNodeDescriptor = getNodeDescriptorFor(newNode);
newUIDObs.push({uid:createUID(), sourceItem:nodeDescriptor});
newNodes.push(newNode);
if(nodeDescriptor.open && !nodeDescriptor.isLeaf()){
getSubtree(newNode, newUIDObs, newNodes);
}
}
}
public function addItemsUnderNode(items:Array, parentNode:XMLNodeDescriptor):void{
}
protected var _filterFunction:Function;
public function set filterFunction(f:Function):void{
this._filterFunction = f;
}
public function refresh():void{
}
public function removeItem(item:*):void{
removeItems([item]);
}
public function addItem(obj:*):void{
addItems[obj];
}
public function addItems(items:Array):void{
addItemsAt(items,this.length)
}
public function addItemsAt(items:Array, idx:Number):void{
}
private var _showRoot:Boolean = true;
/**
* Parameter returns whether or not to show the root of the
* XML data provider. Currently the parameter only works if
* the property is set before the dataProvider is parsed
*
* ie for a Tree control, set the showRoot property before
* setting the dataProvider
*/
public function set showRoot(val:Boolean):void{
_showRoot = val;
}
}
}