GSaha567/seq_level_training_data
052
1text,length,is_long_context,metric_val,label_metric2"/*3Feathers4Copyright 2012-2021 Bowler Hat LLC. All Rights Reserved.5 6This program is free software. You can redistribute and/or modify it in7accordance with the terms of the accompanying license agreement.8*/9package feathers.controls.supportClasses10{11 import feathers.controls.Scroller;12 import feathers.controls.Tree;13 import feathers.controls.renderers.ITreeItemRenderer;14 import feathers.core.FeathersControl;15 import feathers.core.IFeathersControl;16 import feathers.core.IValidating;17 import feathers.data.IHierarchicalCollection;18 import feathers.data.IListCollection;19 import feathers.events.FeathersEventType;20 import feathers.layout.ILayout;21 import feathers.layout.IVariableVirtualLayout;22 import feathers.layout.IVirtualLayout;23 import feathers.layout.LayoutBoundsResult;24 import feathers.layout.ViewPortBounds;25 26 import flash.errors.IllegalOperationError;27 import flash.geom.Point;28 import flash.utils.Dictionary;29 30 import starling.display.DisplayObject;31 import starling.events.Event;32 import starling.utils.Pool;33 34 /**35 * @private36 * Used internally by Tree. Not meant to be used on its own.37 *38 * @productversion Feathers 3.3.039 */40 public class TreeDataViewPort extends FeathersControl implements IViewPort41 {42 private static const INVALIDATION_FLAG_ITEM_RENDERER_FACTORY:String = ""itemRendererFactory"";43 private static const HELPER_VECTOR:Vector.<int> = new <int>[];44 private static const LOCATION_HELPER_VECTOR:Vector.<int> = new <int>[];45 46 public function TreeDataViewPort()47 {48 super();49 }50 51 private var _viewPortBounds:ViewPortBounds = new ViewPortBounds();52 53 private var _layoutResult:LayoutBoundsResult = new LayoutBoundsResult();54 55 private var _actualMinVisibleWidth:Number = 0;56 57 private var _explicitMinVisibleWidth:Number;58 59 public function get minVisibleWidth():Number60 {61 if(this._explicitMinVisibleWidth !== this._explicitMinVisibleWidth) //isNaN62 {63 return this._actualMinVisibleWidth;64 }65 return this._explicitMinVisibleWidth;66 }67 68 public function set minVisibleWidth(value:Number):void69 {70 if(this._explicitMinVisibleWidth == value)71 {72 return;73 }74 var valueIsNaN:Boolean = value !== value; //isNaN75 if(valueIsNaN &&76 this._explicitMinVisibleWidth !== this._explicitMinVisibleWidth) //isNaN77 {78 return;79 }80 var oldValue:Number = this._explicitMinVisibleWidth;81 this._explicitMinVisibleWidth = value;82 if(valueIsNaN)83 {84 this._actualMinVisibleWidth = 0;85 this.invalidate(INVALIDATION_FLAG_SIZE);86 }87 else88 {89 this._actualMinVisibleWidth = value;90 if(this._explicitVisibleWidth !== this._explicitVisibleWidth && //isNaN91 (this._actualVisibleWidth < value || this._actualVisibleWidth == oldValue))92 {93 //only invalidate if this change might affect the visibleWidth94 this.invalidate(INVALIDATION_FLAG_SIZE);95 }96 }97 }98 99 private var _maxVisibleWidth:Number = Number.POSITIVE_INFINITY;100 101 public function get maxVisibleWidth():Number102 {103 return this._maxVisibleWidth;104 }105 106 public function set maxVisibleWidth(value:Number):void107 {108 if(this._maxVisibleWidth == value)109 {110 return;111 }112 if(value !== value) //isNaN113 {114 throw new ArgumentError(""maxVisibleWidth cannot be NaN"");115 }116 var oldValue:Number = this._maxVisibleWidth;117 this._maxVisibleWidth = value;118 if(this._explicitVisibleWidth !== this._explicitVisibleWidth && //isNaN119 (this._actualVisibleWidth > value || this._actualVisibleWidth == oldValue))120 {121 //only invalidate if this change might affect the visibleWidth122 this.invalidate(INVALIDATION_FLAG_SIZE);123 }124 }125 126 private var _actualVisibleWidth:Number = NaN;127 128 private var _explicitVisibleWidth:Number = NaN;129 130 public function get visibleWidth():Number131 {132 return this._actualVisibleWidth;133 }134 135 public function set visibleWidth(value:Number):void136 {137 if(this._explicitVisibleWidth == value ||138 (value !== value && this._explicitVisibleWidth !== this._explicitVisibleWidth)) //isNaN139 {140 return;141 }142 this._explicitVisibleWidth = value;143 if(this._actualVisibleWidth != value)144 {145 this.invalidate(INVALIDATION_FLAG_SIZE);146 }147 }148 149 private var _actualMinVisibleHeight:Number = 0;150 151 private var _explicitMinVisibleHeight:Number;152 153 public function get minVisibleHeight():Number154 {155 if(this._explicitMinVisibleHeight !== this._explicitMinVisibleHeight) //isNaN156 {157 return this._actualMinVisibleHeight;158 }159 return this._explicitMinVisibleHeight;160 }161 162 public function set minVisibleHeight(value:Number):void163 {164 if(this._explicitMinVisibleHeight == value)165 {166 return;167 }168 var valueIsNaN:Boolean = value !== value; //isNaN169 if(valueIsNaN &&170 this._explicitMinVisibleHeight !== this._explicitMinVisibleHeight) //isNaN171 {172 return;173 }174 var oldValue:Number = this._explicitMinVisibleHeight;175 this._explicitMinVisibleHeight = value;176 if(valueIsNaN)177 {178 this._actualMinVisibleHeight = 0;179 this.invalidate(INVALIDATION_FLAG_SIZE);180 }181 else182 {183 this._actualMinVisibleHeight = value;184 if(this._explicitVisibleHeight !== this._explicitVisibleHeight && //isNaN185 (this._actualVisibleHeight < value || this._actualVisibleHeight == oldValue))186 {187 //only invalidate if this change might affect the visibleHeight188 this.invalidate(INVALIDATION_FLAG_SIZE);189 }190 }191 }192 193 private var _maxVisibleHeight:Number = Number.POSITIVE_INFINITY;194 195 public function get maxVisibleHeight():Number196 {197 return this._maxVisibleHeight;198 }199 200 public function set maxVisibleHeight(value:Number):void201 {202 if(this._maxVisibleHeight == value)203 {204 return;205 }206 if(value !== value) //isNaN207 {208 throw new ArgumentError(""maxVisibleHeight cannot be NaN"");209 }210 var oldValue:Number = this._maxVisibleHeight;211 this._maxVisibleHeight = value;212 if(this._explicitVisibleHeight !== this._explicitVisibleHeight && //isNaN213 (this._actualVisibleHeight > value || this._actualVisibleHeight == oldValue))214 {215 //only invalidate if this change might affect the visibleHeight216 this.invalidate(INVALIDATION_FLAG_SIZE);217 }218 }219 220 private var _actualVisibleHeight:Number;221 222 private var _explicitVisibleHeight:Number = NaN;223 224 public function get visibleHeight():Number225 {226 return this._actualVisibleHeight;227 }228 229 public function set visibleHeight(value:Number):void230 {231 if(this._explicitVisibleHeight == value ||232 (value !== value && this._explicitVisibleHeight !== this._explicitVisibleHeight)) //isNaN233 {234 return;235 }236 this._explicitVisibleHeight = value;237 if(this._actualVisibleHeight != value)238 {239 this.invalidate(INVALIDATION_FLAG_SIZE);240 }241 }242 243 protected var _contentX:Number = 0;244 245 public function get contentX():Number246 {247 return this._contentX;248 }249 250 protected var _contentY:Number = 0;251 252 public function get contentY():Number253 {254 return this._contentY;255 }256 257 public function get horizontalScrollStep():Number258 {259 var itemRenderer:DisplayObject = null;260 var virtualLayout:IVirtualLayout = this._layout as IVirtualLayout;261 if(virtualLayout === null || !virtualLayout.useVirtualLayout)262 {263 if(this._layoutItems.length > 0)264 {265 itemRenderer = this._layoutItems[0] as DisplayObject;266 }267 }268 if(itemRenderer === null)269 {270 itemRenderer = this._typicalItemRenderer as DisplayObject;271 }272 if(itemRenderer === null)273 {274 return 0;275 }276 var itemRendererWidth:Number = itemRenderer.width;277 var itemRendererHeight:Number = itemRenderer.height;278 if(itemRendererWidth < itemRendererHeight)279 {280 return itemRendererWidth;281 }282 return itemRendererHeight;283 }284 285 public function get verticalScrollStep():Number286 {287 var itemRenderer:DisplayObject = null;288 var virtualLayout:IVirtualLayout = this._layout as IVirtualLayout;289 if(virtualLayout === null || !virtualLayout.useVirtualLayout)290 {291 if(this._layoutItems.length > 0)292 {293 itemRenderer = this._layoutItems[0] as DisplayObject;294 }295 }296 if(itemRenderer === null)297 {298 itemRenderer = this._typicalItemRenderer as DisplayObject;299 }300 if(itemRenderer === null)301 {302 return 0;303 }304 var itemRendererWidth:Number = itemRenderer.width;305 var itemRendererHeight:Number = itemRenderer.height;306 if(itemRendererWidth < itemRendererHeight)307 {308 return itemRendererWidth;309 }310 return itemRendererHeight;311 }312 313 private var _owner:Tree = null;314 315 public function get owner():Tree316 {317 return this._owner;318 }319 320 public function set owner(value:Tree):void321 {322 this._owner = value;323 }324 325 private var _updateForDataReset:Boolean = false;326 327 private var _dataProvider:IHierarchicalCollection = null;328 329 public function get dataProvider():IHierarchicalCollection330 {331 return this._dataProvider;332 }333 334 public function set dataProvider(value:IHierarchicalCollection):void335 {336 if(this._dataProvider == value)337 {338 return;339 }340 if(this._dataProvider)341 {342 this._dataProvider.removeEventListener(Event.CHANGE, dataProvider_changeHandler);343 /*this._dataProvider.removeEventListener(CollectionEventType.RESET, dataProvider_resetHandler);344 this._dataProvider.removeEventListener(CollectionEventType.ADD_ITEM, dataProvider_addItemHandler);345 this._dataProvider.removeEventListener(CollectionEventType.REMOVE_ITEM, dataProvider_removeItemHandler);346 this._dataProvider.removeEventListener(CollectionEventType.REPLACE_ITEM, dataProvider_replaceItemHandler);347 this._dataProvider.removeEventListener(CollectionEventType.UPDATE_ITEM, dataProvider_updateItemHandler);348 this._dataProvider.removeEventListener(CollectionEventType.UPDATE_ALL, dataProvider_updateAllHandler);*/349 }350 this._dataProvider = value;351 if(this._dataProvider)352 {353 this._dataProvider.addEventListener(Event.CHANGE, dataProvider_changeHandler);354 /*this._dataProvider.addEventListener(CollectionEventType.RESET, dataProvider_resetHandler);355 this._dataProvider.addEventListener(CollectionEventType.ADD_ITEM, dataProvider_addItemHandler);356 this._dataProvider.addEventListener(CollectionEventType.REMOVE_ITEM, dataProvider_removeItemHandler);357 this._dataProvider.addEventListener(CollectionEventType.REPLACE_ITEM, dataProvider_replaceItemHandler);358 this._dataProvider.addEventListener(CollectionEventType.UPDATE_ITEM, dataProvider_updateItemHandler);359 this._dataProvider.addEventListener(CollectionEventType.UPDATE_ALL, dataProvider_updateAllHandler);*/360 }361 if(this._layout is IVariableVirtualLayout)362 {363 IVariableVirtualLayout(this._layout).resetVariableVirtualCache();364 }365 this._updateForDataReset = true;366 this.invalidate(INVALIDATION_FLAG_DATA);367 }368 369 private var _ignoreLayoutChanges:Boolean = false;370 private var _ignoreRendererResizing:Boolean = false;371 372 private var _layout:ILayout = null;373 374 public function get layout():ILayout375 {376 return this._layout;377 }378 379 public function set layout(value:ILayout):void380 {381 if(this._layout == value)382 {383 return;384 }385 if(this._layout)386 {387 this._layout.removeEventListener(Event.CHANGE, layout_changeHandler);388 }389 this._layout = value;390 if(this._layout)391 {392 if(this._layout is IVariableVirtualLayout)393 {394 var variableVirtualLayout:IVariableVirtualLayout = IVariableVirtualLayout(this._layout);395 variableVirtualLayout.resetVariableVirtualCache();396 }397 this._layout.addEventListener(Event.CHANGE, layout_changeHandler);398 }399 this.invalidate(INVALIDATION_FLAG_LAYOUT);400 }401 402 private var _horizontalScrollPosition:Number = 0;403 404 public function get horizontalScrollPosition():Number405 {406 return this._horizontalScrollPosition;407 }408 409 public function set horizontalScrollPosition(value:Number):void410 {411 if(this._horizontalScrollPosition == value)412 {413 return;414 }415 this._horizontalScrollPosition = value;416 this.invalidate(INVALIDATION_FLAG_SCROLL);417 }418 419 private var _verticalScrollPosition:Number = 0;420 421 public function get verticalScrollPosition():Number422 {423 return this._verticalScrollPosition;424 }425 426 public function set verticalScrollPosition(value:Number):void427 {428 if(this._verticalScrollPosition == value)429 {430 return;431 }432 this._verticalScrollPosition = value;433 this.invalidate(INVALIDATION_FLAG_SCROLL);434 }435 436 public function get requiresMeasurementOnScroll():Boolean437 {438 return this._layout.requiresLayoutOnScroll &&439 (this._explicitVisibleWidth !== this._explicitVisibleWidth || //isNaN440 this._explicitVisibleHeight !== this._explicitVisibleHeight); //isNaN441 }442 443 private var _ignoreSelectionChanges:Boolean = false;444 445 private var _isSelectable:Boolean = true;446 447 public function get isSelectable():Boolean448 {449 return this._isSelectable;450 }451 452 public function set isSelectable(value:Boolean):void453 {454 if(this._isSelectable == value)455 {456 return;457 }458 this._isSelectable = value;459 if(!this._isSelectable)460 {461 this.selectedItem = null;462 }463 this.invalidate(INVALIDATION_FLAG_SELECTED);464 }465 466 private var _selectedItem:Object = null;467 468 public function get selectedItem():Object469 {470 return this._selectedItem;471 }472 473 public function set selectedItem(value:Object):void474 {475 if(this._selectedItem == value)476 {477 return;478 }479 this._selectedItem = value;480 this.invalidate(INVALIDATION_FLAG_SELECTED);481 this.dispatchEventWith(Event.CHANGE);482 }483 484 private var _typicalItem:Object = null;485 486 public function get typicalItem():Object487 {488 return this._typicalItem;489 }490 491 public function set typicalItem(value:Object):void492 {493 if(this._typicalItem == value)494 {495 return;496 }497 this._typicalItem = value;498 this.invalidate(INVALIDATION_FLAG_DATA);499 }500 501 private var _itemRendererType:Class;502 503 public function get itemRendererType():Class504 {505 return this._itemRendererType;506 }507 508 public function set itemRendererType(value:Class):void509 {510 if(this._itemRendererType == value)511 {512 return;513 }514 515 this._itemRendererType = value;516 this.invalidate(INVALIDATION_FLAG_ITEM_RENDERER_FACTORY);517 }518 519 private var _itemRendererFactory:Function;520 521 public function get itemRendererFactory():Function522 {523 return this._itemRendererFactory;524 }525 526 public function set itemRendererFactory(value:Function):void527 {528 if(this._itemRendererFactory === value)529 {530 return;531 }532 533 this._itemRendererFactory = value;534 this.invalidate(INVALIDATION_FLAG_ITEM_RENDERER_FACTORY);535 }536 537 private var _itemRendererFactories:Object;538 539 public function get itemRendererFactories():Object540 {541 return this._itemRendererFactories;542 }543 544 public function set itemRendererFactories(value:Object):void545 {546 if(this._itemRendererFactories === value)547 {548 return;549 }550 551 this._itemRendererFactories = value;552 this.invalidate(INVALIDATION_FLAG_ITEM_RENDERER_FACTORY);553 }554 555 private var _factoryIDFunction:Function;556 557 public function get factoryIDFunction():Function558 {559 return this._factoryIDFunction;560 }561 562 public function set factoryIDFunction(value:Function):void563 {564 if(this._factoryIDFunction === value)565 {566 return;567 }568 569 this._factoryIDFunction = value;570 this.invalidate(INVALIDATION_FLAG_ITEM_RENDERER_FACTORY);571 }572 573 private var _customItemRendererStyleName:String;574 575 public function get customItemRendererStyleName():String576 {577 return this._customItemRendererStyleName;578 }579 580 public function set customItemRendererStyleName(value:String):void581 {582 if(this._customItemRendererStyleName == value)583 {584 return;585 }586 this._customItemRendererStyleName = value;587 this.invalidate(INVALIDATION_FLAG_ITEM_RENDERER_FACTORY);588 }589 590 private var _openBranches:IListCollection;591 592 public function get openBranches():IListCollection593 {594 return this._openBranches;595 }596 597 public function set openBranches(value:IListCollection):void598 {599 if(this._openBranches == value)600 {601 return;602 }603 if(this._openBranches !== null)604 {605 this._openBranches.removeEventListener(Event.CHANGE, openBranches_changeHandler);606 }607 this._openBranches = value;608 if(this._openBranches !== null)609 {610 this._openBranches.addEventListener(Event.CHANGE, openBranches_changeHandler);611 }612 this.invalidate(INVALIDATION_FLAG_DATA);613 }614 615 private var _typicalItemIsInDataProvider:Boolean = false;616 private var _typicalItemRenderer:ITreeItemRenderer;617 618 private var _layoutItems:Vector.<DisplayObject> = new <DisplayObject>[];619 620 private var _unrenderedItems:Array = [];621 private var _defaultItemRendererStorage:ItemRendererFactoryStorage = new ItemRendererFactoryStorage();622 private var _itemStorageMap:Object = {};623 private var _itemRendererMap:Dictionary = new Dictionary(true);624 private var _minimumItemCount:int;625 626 public function calculateNavigationDestination(location:Vector.<int>, keyCode:uint, result:Vector.<int>):void627 {628 var displayIndex:int = this.locationToDisplayIndex(location, false);629 if(displayIndex == -1)630 {631 throw new ArgumentError(""Cannot calculate navigation destination for location: "" + location);632 }633 var newDisplayIndex:int = this._layout.calculateNavigationDestination(this._layoutItems, displayIndex, keyCode, this._layoutResult);634 this.displayIndexToLocation(newDisplayIndex, result);635 }636 637 public function getScrollPositionForLocation(location:Vector.<int>, result:Point = null):Point638 {639 if(!result)640 {641 result = new Point();642 }643 644 var displayIndex:int = this.locationToDisplayIndex(location, true);645 if(displayIndex == -1)646 {647 throw new ArgumentError(""Cannot calculate scroll position for location: "" + location);648 }649 return this._layout.getScrollPositionForIndex(displayIndex, this._layoutItems,650 0, 0, this._actualVisibleWidth, this._actualVisibleHeight, result);651 }652 653 public function getNearestScrollPositionForIndex(location:Vector.<int>, result:Point = null):Point654 {655 if(!result)656 {657 result = new Point();658 }659 660 var displayIndex:int = this.locationToDisplayIndex(location, true);661 if(displayIndex == -1)662 {663 throw new ArgumentError(""Cannot calculate nearest scroll position for location: "" + location);664 }665 return this._layout.getNearestScrollPositionForIndex(displayIndex, this._horizontalScrollPosition,666 this._verticalScrollPosition, this._layoutItems, 0, 0, this._actualVisibleWidth, this._actualVisibleHeight, result);667 }668 669 public function itemToItemRenderer(item:Object):ITreeItemRenderer670 {671 if(item is XML || item is XMLList)672 {673 return ITreeItemRenderer(this._itemRendererMap[item.toXMLString()]);674 }675 return ITreeItemRenderer(this._itemRendererMap[item]);676 }677 678 override public function dispose():void679 {680 this.refreshInactiveItemRenderers(null, true);681 if(this._itemStorageMap)682 {683 for(var factoryID:String in this._itemStorageMap)684 {685 this.refreshInactiveItemRenderers(factoryID, true);686 }687 }688 this.owner = null;689 this.dataProvider = null;690 this.layout = null;691 super.dispose();692 }693 694 override protected function draw():void695 {696 var dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA);697 var scrollInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SCROLL);698 var sizeInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SIZE);699 var selectionInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SELECTED);700 var itemRendererInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_ITEM_RENDERER_FACTORY);701 var stylesInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_STYLES);702 var stateInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_STATE);703 var layoutInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_LAYOUT);704 705 //scrolling only affects the layout is requiresLayoutOnScroll is true706 if(!layoutInvalid && scrollInvalid && this._layout && this._layout.requiresLayoutOnScroll)707 {708 layoutInvalid = true;709 }710 711 var basicsInvalid:Boolean = sizeInvalid || dataInvalid || layoutInvalid || itemRendererInvalid;712 713 var oldIgnoreRendererResizing:Boolean = this._ignoreRendererResizing;714 this._ignoreRendererResizing = true;715 var oldIgnoreLayoutChanges:Boolean = this._ignoreLayoutChanges;716 this._ignoreLayoutChanges = true;717 718 if(scrollInvalid || sizeInvalid)719 {720 this.refreshViewPortBounds();721 }722 if(basicsInvalid)723 {724 this.refreshInactiveItemRenderers(null, itemRendererInvalid);725 if(this._itemStorageMap)726 {727 for(var factoryID:String in this._itemStorageMap)728 {729 this.refreshInactiveItemRenderers(factoryID, itemRendererInvalid);730 }731 }732 }733 if(dataInvalid || layoutInvalid || itemRendererInvalid)734 {735 this.refreshLayoutTypicalItem();736 }737 if(basicsInvalid)738 {739 this.refreshItemRenderers();740 }741 if(selectionInvalid || basicsInvalid)742 {743 //unlike resizing renderers and layout changes, we only want to744 //stop listening for selection changes when we're forcibly745 //updating selection. other property changes on item renderers746 //can validly change selection, and we need to detect that.747 var oldIgnoreSelectionChanges:Boolean = this._ignoreSelectionChanges;748 this._ignoreSelectionChanges = true;749 this.refreshSelection();750 this._ignoreSelectionChanges = oldIgnoreSelectionChanges;751 }752 if(stateInvalid || basicsInvalid)753 {754 this.refreshEnabled();755 }756 this._ignoreLayoutChanges = oldIgnoreLayoutChanges;757 758 if(stateInvalid || selectionInvalid || stylesInvalid || basicsInvalid)759 {760 this._layout.layout(this._layoutItems, this._viewPortBounds, this._layoutResult);761 }762 763 this._ignoreRendererResizing = oldIgnoreRendererResizing;764 765 this._contentX = this._layoutResult.contentX;766 this._contentY = this._layoutResult.contentY;767 this.saveMeasurements(this._layoutResult.contentWidth, this._layoutResult.contentHeight,768 this._layoutResult.contentWidth, this._layoutResult.contentHeight);769 this._actualVisibleWidth = this._layoutResult.viewPortWidth;770 this._actualVisibleHeight = this._layoutResult.viewPortHeight;771 this._actualMinVisibleWidth = this._layoutResult.viewPortWidth;772 this._actualMinVisibleHeight = this._layoutResult.viewPortHeight;773 774 //final validation to avoid juggler next frame issues775 this.validateRenderers();776 }777 778 private function displayIndexToLocation(displayIndex:int, result:Vector.<int>):void779 {780 }781 782 private var _displayIndex:int;783 784 private function locationToDisplayIndex(location:Vector.<int>, returnNearestIfBranchNotOpen:Boolean):int785 {786 this._displayIndex = -1;787 var result:Object = this.locationToDisplayIndexAtBranch(new <int>[], location, returnNearestIfBranchNotOpen);788 if(result !== null)789 {790 return this._displayIndex;791 }792 return -1;793 }794 795 private function locationToDisplayIndexAtBranch(locationOfBranch:Vector.<int>, locationToFind:Vector.<int>, returnNearestIfBranchNotOpen:Boolean):Object796 {797 var childCount:int = this._dataProvider.getLengthAtLocation(locationOfBranch);798 for(var i:int = 0; i < childCount; i++)799 {800 this._displayIndex++;801 locationOfBranch[locationOfBranch.length] = i;802 var child:Object = this._dataProvider.getItemAtLocation(locationOfBranch);803 if(locationOfBranch.length == locationToFind.length)804 {805 var every:Boolean = locationOfBranch.every(function(item:int, index:int, source:Vector.<int>):Boolean806 {807 return item === locationToFind[index];808 });809 if(every)810 {811 return child;812 }813 }814 if(this._dataProvider.isBranch(child))815 {816 if(this.owner.isBranchOpen(child))817 {818 var result:Object = this.locationToDisplayIndexAtBranch(locationOfBranch, locationToFind, returnNearestIfBranchNotOpen);819 if(result)820 {821 return result;822 }823 }824 else if(returnNearestIfBranchNotOpen)825 {826 //if the location is inside a closed branch827 //return that branch828 every = locationOfBranch.every(function(item:int, index:int, source:Vector.<int>):Boolean829 {830 return item === locationToFind[index];831 });832 if(every)833 {834 return child;835 }836 }837 }838 locationOfBranch.length--;839 }840 //location was not found!841 return null;842 }843 844 private function refreshViewPortBounds():void845 {846 var needsMinWidth:Boolean = this._explicitMinVisibleWidth !== this._explicitMinVisibleWidth; //isNaN847 var needsMinHeight:Boolean = this._explicitMinVisibleHeight !== this._explicitMinVisibleHeight; //isNaN848 this._viewPortBounds.x = 0;849 this._viewPortBounds.y = 0;850 this._viewPortBounds.scrollX = this._horizontalScrollPosition;851 this._viewPortBounds.scrollY = this._verticalScrollPosition;852 this._viewPortBounds.explicitWidth = this._explicitVisibleWidth;853 this._viewPortBounds.explicitHeight = this._explicitVisibleHeight;854 if(needsMinWidth)855 {856 this._viewPortBounds.minWidth = 0;857 }858 else859 {860 this._viewPortBounds.minWidth = this._explicitMinVisibleWidth;861 }862 if(needsMinHeight)863 {864 this._viewPortBounds.minHeight = 0;865 }866 else867 {868 this._viewPortBounds.minHeight = this._explicitMinVisibleHeight;869 }870 this._viewPortBounds.maxWidth = this._maxVisibleWidth;871 this._viewPortBounds.maxHeight = this._maxVisibleHeight;872 }873 874 private function refreshLayoutTypicalItem():void875 {876 var virtualLayout:IVirtualLayout = this._layout as IVirtualLayout;877 if(virtualLayout === null || !virtualLayout.useVirtualLayout)878 {879 //the old layout was virtual, but this one isn't880 if(!this._typicalItemIsInDataProvider && this._typicalItemRenderer !== null)881 {882 //it's safe to destroy this renderer883 this.destroyItemRenderer(this._typicalItemRenderer);884 this._typicalItemRenderer = null;885 }886 return;887 }888 var typicalItemLocation:Vector.<int> = null;889 var newTypicalItemIsInDataProvider:Boolean = false;890 var typicalItem:Object = this._typicalItem;891 if(typicalItem !== null)892 {893 if(this._dataProvider !== null)894 {895 typicalItemLocation = this._dataProvider.getItemLocation(typicalItem);896 newTypicalItemIsInDataProvider = typicalItemLocation !== null && typicalItemLocation.length > 0;897 }898 }899 else900 {901 if(this._dataProvider !== null && this._dataProvider.getLengthAtLocation() > 0)902 {903 newTypicalItemIsInDataProvider = true;904 typicalItem = this._dataProvider.getItemAt(0);905 typicalItemLocation = new <int>[0];906 }907 }908 909 //#1645 The typicalItem can be null if the data provider contains910 //a null value at index 0. this is the only time we allow null.911 if(typicalItem !== null || newTypicalItemIsInDataProvider)912 {913 var typicalItemRenderer:ITreeItemRenderer = this.itemToItemRenderer(typicalItem);914 if(typicalItemRenderer !== null)915 {916 //at this point, the item already has an item renderer.917 //(this doesn't necessarily mean that the current typical918 //item was the typical item last time this function was919 //called)920 921 //the location may have changed if items were added,922 //removed or reordered in the data provider923 typicalItemRenderer.location = typicalItemLocation;924 }925 if(typicalItemRenderer === null && this._typicalItemRenderer !== null)926 {927 //the typical item has changed, and doesn't have an item928 //renderer yet. the previous typical item had an item929 //renderer, so we will try to reuse it.930 931 //we can reuse the existing typical item renderer if the old932 //typical item wasn't in the data provider. otherwise, it933 //may still be needed for the same item.934 var canReuse:Boolean = !this._typicalItemIsInDataProvider;935 var oldTypicalItemRemoved:Boolean = this._typicalItemIsInDataProvider &&936 this._dataProvider !== null && this._dataProvider.getItemLocation(this._typicalItemRenderer.data) === null;937 if(!canReuse && oldTypicalItemRemoved)938 {939 //special case: if the old typical item was in the data940 //provider, but it has been removed, it's safe to reuse.941 canReuse = true;942 }943 if(canReuse)944 {945 //we can't reuse if the factoryID has changed, though!946 var factoryID:String = null;947 if(this._factoryIDFunction !== null)948 {949 factoryID = this.getFactoryID(typicalItem, typicalItemLocation);950 }951 if(this._typicalItemRenderer.factoryID !== factoryID)952 {953 canReuse = false;954 }955 }956 if(canReuse)957 {958 //we can reuse the item renderer used for the old959 //typical item!960 961 //if the old typical item was in the data provider,962 //remove it from the renderer map.963 if(this._typicalItemIsInDataProvider)964 {965 var oldData:Object = this._typicalItemRenderer.data;966 if(oldData is XML || oldData is XMLList)967 {968 delete this._itemRendererMap[oldData.toXMLString()];969 }970 else971 {972 delete this._itemRendererMap[oldData];973 }974 }975 typicalItemRenderer = this._typicalItemRenderer;976 typicalItemRenderer.data = typicalItem;977 typicalItemRenderer.location = typicalItemLocation;978 //if the new typical item is in the data provider, add it979 //to the renderer map.980 if(newTypicalItemIsInDataProvider)981 {982 if(typicalItem is XML || typicalItem is XMLList)983 {984 this._itemRendererMap[typicalItem.toXMLString()] = typicalItemRenderer;985 }986 else987 {988 this._itemRendererMap[typicalItem] = typicalItemRenderer;989 }990 }991 }992 }993 if(typicalItemRenderer === null)994 {995 //if we still don't have a typical item renderer, we need to996 //create a new one.997 typicalItemRenderer = this.createItemRenderer(typicalItem, typicalItemLocation, 0, false, !newTypicalItemIsInDataProvider);998 if(!this._typicalItemIsInDataProvider && this._typicalItemRenderer !== null)999 {1000 //get rid of the old typical item renderer if it isn't1001 //needed anymore. since it was not in the data1002 //provider, we don't need to mess with the renderer map1003 //dictionary or dispatch any events.1004 this.destroyItemRenderer(this._typicalItemRenderer);1005 this._typicalItemRenderer = null;1006 }1007 }1008 }1009 1010 virtualLayout.typicalItem = DisplayObject(typicalItemRenderer);1011 this._typicalItemRenderer = typicalItemRenderer;1012 this._typicalItemIsInDataProvider = newTypicalItemIsInDataProvider;1013 if(this._typicalItemRenderer !== null && !this._typicalItemIsInDataProvider)1014 {1015 //we need to know if this item renderer resizes to adjust the1016 //layout because the layout may use this item renderer to resize1017 //the other item renderers1018 this._typicalItemRenderer.addEventListener(FeathersEventType.RESIZE, itemRenderer_resizeHandler);1019 }1020 }1021 1022 private function refreshItemRenderers():void1023 {1024 if(this._typicalItemRenderer !== null && this._typicalItemIsInDataProvider)1025 {1026 var storage:ItemRendererFactoryStorage = this.factoryIDToStorage(this._typicalItemRenderer.factoryID);1027 var inactiveItemRenderers:Vector.<ITreeItemRenderer> = storage.inactiveItemRenderers;1028 var activeItemRenderers:Vector.<ITreeItemRenderer> = storage.activeItemRenderers;1029 //this renderer is already is use by the typical item, so we1030 //don't want to allow it to be used by other items.1031 var inactiveIndex:int = inactiveItemRenderers.indexOf(this._typicalItemRenderer);1032 if(inactiveIndex >= 0)1033 {1034 inactiveItemRenderers[inactiveIndex] = null;1035 }1036 //if refreshLayoutTypicalItem() was called, it will have already1037 //added the typical item renderer to the active renderers. if1038 //not, we need to do it here.1039 var activeRendererCount:int = activeItemRenderers.length;1040 if(activeRendererCount == 0)1041 {1042 activeItemRenderers[activeRendererCount] = this._typicalItemRenderer;1043 }1044 }1045 1046 this.findUnrenderedData();1047 this.recoverInactiveItemRenderers(this._defaultItemRendererStorage);1048 if(this._itemStorageMap)1049 {1050 for(var factoryID:String in this._itemStorageMap)1051 {1052 storage = ItemRendererFactoryStorage(this._itemStorageMap[factoryID]);1053 this.recoverInactiveItemRenderers(storage);1054 }1055 }1056 this.renderUnrenderedData();1057 this.freeInactiveItemRenderers(this._defaultItemRendererStorage, this._minimumItemCount);1058 if(this._itemStorageMap)1059 {1060 for(factoryID in this._itemStorageMap)1061 {1062 storage = ItemRendererFactoryStorage(this._itemStorageMap[factoryID]);1063 this.freeInactiveItemRenderers(storage, 1);1064 }1065 }1066 this._updateForDataReset = false;1067 }1068 1069 private function findTotalLayoutCount(location:Vector.<int>):int1070 {1071 var itemCount:int = 0;1072 if(this._dataProvider !== null)1073 {1074 itemCount = this._dataProvider.getLengthAtLocation(location);1075 }1076 var result:int = itemCount;1077 for(var i:int = 0; i < itemCount; i++)1078 {1079 location[location.length] = i;1080 var item:Object = this._dataProvider.getItemAtLocation(location);1081 if(this._dataProvider.isBranch(item) &&1082 this._openBranches.contains(item))1083 {1084 result += this.findTotalLayoutCount(location);1085 }1086 location.length--;1087 }1088 return result;1089 }1090 1091 private function findUnrenderedDataForLocation(location:Vector.<int>, currentIndex:int):int1092 {1093 var virtualLayout:IVirtualLayout = this._layout as IVirtualLayout;1094 var useVirtualLayout:Boolean = virtualLayout !== null && virtualLayout.useVirtualLayout;1095 var itemCount:int = 0;1096 if(this._dataProvider !== null)1097 {1098 itemCount = this._dataProvider.getLengthAtLocation(location);1099 }1100 for(var i:int = 0; i < itemCount; i++)1101 {1102 location[location.length] = i;1103 var item:Object = this._dataProvider.getItemAtLocation(location);1104 1105 if(useVirtualLayout && HELPER_VECTOR.indexOf(currentIndex) == -1)1106 {1107 if(this._typicalItemRenderer !== null &&1108 this._typicalItemIsInDataProvider &&1109 this._typicalItemRenderer.data === item)1110 {1111 //the index may have changed if items were added, removed,1112 //or reordered in the data provider1113 this._typicalItemRenderer.layoutIndex = currentIndex;1114 }1115 this._layoutItems[currentIndex] = null;1116 }1117 else1118 {1119 this.findRendererForItem(item, location.slice(), currentIndex);1120 }1121 currentIndex++;1122 1123 if(this._dataProvider.isBranch(item) &&1124 this._openBranches.contains(item))1125 {1126 currentIndex = this.findUnrenderedDataForLocation(location, currentIndex);1127 }1128 location.length--;1129 }1130 return currentIndex;1131 }1132 1133 private function findUnrenderedData():void1134 {1135 LOCATION_HELPER_VECTOR.length = 0;1136 var totalLayoutCount:int = this.findTotalLayoutCount(LOCATION_HELPER_VECTOR);1137 LOCATION_HELPER_VECTOR.length = 0;1138 this._layoutItems.length = totalLayoutCount;1139 var virtualLayout:IVirtualLayout = this._layout as IVirtualLayout;1140 var useVirtualLayout:Boolean = virtualLayout !== null && virtualLayout.useVirtualLayout;1141 if(useVirtualLayout)1142 {1143 var point:Point = Pool.getPoint();1144 virtualLayout.measureViewPort(totalLayoutCount, this._viewPortBounds, point);1145 var viewPortWidth:Number = point.x;1146 var viewPortHeight:Number = point.y;1147 Pool.putPoint(point);1148 virtualLayout.getVisibleIndicesAtScrollPosition(this._horizontalScrollPosition, this._verticalScrollPosition, viewPortWidth, viewPortHeight, totalLayoutCount, HELPER_VECTOR);1149 1150 if(this._typicalItemRenderer !== null)1151 {1152 var minimumTypicalItemEdge:Number = this._typicalItemRenderer.height;1153 if(this._typicalItemRenderer.width < minimumTypicalItemEdge)1154 {1155 minimumTypicalItemEdge = this._typicalItemRenderer.width;1156 }1157 1158 var maximumViewPortEdge:Number = viewPortWidth;1159 if(viewPortHeight > viewPortWidth)1160 {1161 maximumViewPortEdge = viewPortHeight;1162 }1163 1164 this._minimumItemCount = Math.ceil(maximumViewPortEdge / minimumTypicalItemEdge) + 1;1165 }1166 else1167 {1168 this._minimumItemCount = 1;1169 }1170 }1171 LOCATION_HELPER_VECTOR.length = 0;1172 this.findUnrenderedDataForLocation(LOCATION_HELPER_VECTOR, 0);1173 LOCATION_HELPER_VECTOR.length = 0;1174 //update the typical item renderer's visibility1175 if(this._typicalItemRenderer !== null)1176 {1177 if(useVirtualLayout && this._typicalItemIsInDataProvider)1178 {1179 var index:int = HELPER_VECTOR.indexOf(this._typicalItemRenderer.layoutIndex);1180 if(index >= 0)1181 {1182 this._typicalItemRenderer.visible = true;1183 }1184 else1185 {1186 this._typicalItemRenderer.visible = false;1187 1188 //uncomment these lines to see a hidden typical item for1189 //debugging purposes...1190 /*this._typicalItemRenderer.visible = true;1191 this._typicalItemRenderer.x = this._horizontalScrollPosition;1192 this._typicalItemRenderer.y = this._verticalScrollPosition;*/1193 }1194 }1195 else1196 {1197 this._typicalItemRenderer.visible = this._typicalItemIsInDataProvider;1198 }1199 }1200 HELPER_VECTOR.length = 0;