This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit afe6a2af57a76985033d893c9ceaf89a545e2f5a
Author: Alex Harui <aha...@apache.org>
AuthorDate: Tue Feb 13 17:09:19 2018 -0800

    JS fixed row height virtual lists
---
 .../Basic/src/main/resources/basic-manifest.xml    |   2 +
 .../royale/core/IListWithPresentationModel.as      |  46 +++
 .../royale/org/apache/royale/html/DataContainer.as |   3 +-
 .../royale/html/beads/VirtualDataContainerView.as  | 223 +++++++++++++++
 .../VirtualDataItemRendererFactoryForArrayData.as  | 215 ++++++++++++++
 .../apache/royale/html/beads/VirtualListView.as    | 185 ++++++++++++
 .../beads/layouts/VirtualListVerticalLayout.as     | 309 +++++++++++++++++++++
 .../projects/Core/src/main/royale/CoreClasses.as   |   1 +
 .../core/IDataProviderVirtualItemRendererMapper.as |  43 +++
 9 files changed, 1026 insertions(+), 1 deletion(-)

diff --git a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml 
b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
index 0ba6ba8..19d525e 100644
--- a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
+++ b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
@@ -70,6 +70,7 @@
     <component id="BasicLayout" 
class="org.apache.royale.html.beads.layouts.BasicLayout"/>
     <component id="RemovableBasicLayout" 
class="org.apache.royale.html.beads.layouts.RemovableBasicLayout"/>
     <component id="VerticalLayout" 
class="org.apache.royale.html.beads.layouts.VerticalLayout"/>
+    <component id="VirtualListVerticalLayout" 
class="org.apache.royale.html.beads.layouts.VirtualListVerticalLayout"/>
     <component id="VerticalLayoutWithPaddingAndGap" 
class="org.apache.royale.html.beads.layouts.VerticalLayoutWithPaddingAndGap"/>
     <component id="VerticalFlexLayout" 
class="org.apache.royale.html.beads.layouts.VerticalFlexLayout"/>
     <component id="VerticalSliderLayout" 
class="org.apache.royale.html.beads.layouts.VerticalSliderLayout" />
@@ -166,6 +167,7 @@
     <component id="DynamicRemoveAllByNullItemRendererForArrayListData" 
class="org.apache.royale.html.beads.DynamicRemoveAllByNullItemRendererForArrayListData"
 />
     <component id="TextItemRendererFactoryForArrayData" 
class="org.apache.royale.html.beads.TextItemRendererFactoryForArrayData" />
     <component id="TextItemRendererFactoryForStringVectorData" 
class="org.apache.royale.html.beads.TextItemRendererFactoryForStringVectorData" 
/>
+    <component id="VirtualDataItemRendererFactoryForArrayData" 
class="org.apache.royale.html.beads.VirtualDataItemRendererFactoryForArrayData" 
/>
 
     <component id="DateChooser" class="org.apache.royale.html.DateChooser"/>
     <component id="DateChooserList" 
class="org.apache.royale.html.supportClasses.DateChooserList" />
diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/core/IListWithPresentationModel.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/core/IListWithPresentationModel.as
new file mode 100644
index 0000000..3e24bfc
--- /dev/null
+++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/core/IListWithPresentationModel.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.core
+{
+       import org.apache.royale.core.IListPresentationModel;
+
+    /**
+     *  The IListWithPresentationModel interface is implemented by any IList
+        *  that supports a separate IListPresentationModel
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+       public interface IListWithPresentationModel extends IList
+       {
+        /**
+         *  Returns the component within the list (maybe even the list shell 
itself)
+                *  which will be the parent of each itemRenderer.
+         * 
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+               function get presentationModel():IListPresentationModel;
+               
+       }
+}
diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/DataContainer.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/DataContainer.as
index 47d54b8..bb5707e 100644
--- 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/DataContainer.as
+++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/DataContainer.as
@@ -30,6 +30,7 @@ package org.apache.royale.html
        import org.apache.royale.core.IItemRendererParent;
        import org.apache.royale.core.ILayoutView;
        import org.apache.royale.core.IList;
+    import org.apache.royale.core.IListWithPresentationModel;
        import org.apache.royale.core.IListPresentationModel;
        import org.apache.royale.core.IRollOverModel;
        import org.apache.royale.core.IDataProviderModel;
@@ -73,7 +74,7 @@ package org.apache.royale.html
         *  @playerversion AIR 2.6
         *  @productversion Royale 0.0
         */
-       public class DataContainer extends DataContainerBase
+       public class DataContainer extends DataContainerBase implements 
IListWithPresentationModel
        {
                /**
                 *  constructor.
diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualDataContainerView.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualDataContainerView.as
new file mode 100644
index 0000000..dc38e6f
--- /dev/null
+++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualDataContainerView.as
@@ -0,0 +1,223 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.html.beads
+{      
+       import org.apache.royale.core.BeadViewBase;
+       import org.apache.royale.core.ContainerBase;
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IBeadLayout;
+       import org.apache.royale.core.IBeadModel;
+       import org.apache.royale.core.IBeadView;
+       import org.apache.royale.core.IDataProviderModel;
+       import org.apache.royale.core.IItemRenderer;
+       import org.apache.royale.core.IItemRendererParent;
+       import org.apache.royale.core.IList;
+       import org.apache.royale.core.IParent;
+       import org.apache.royale.core.IParentIUIBase;
+       import org.apache.royale.core.ISelectableItemRenderer;
+       import org.apache.royale.core.ISelectionModel;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.core.LayoutBase;
+       import org.apache.royale.core.Strand;
+       import org.apache.royale.core.UIBase;
+       import org.apache.royale.core.ValuesManager;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.html.supportClasses.Border;
+       import org.apache.royale.html.supportClasses.DataGroup;
+
+       /**
+        *  The DataContainerView provides the visual elements for the 
DataContainer.
+        *  
+        *  @viewbead
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.8
+        */
+       COMPILE::JS
+       public class VirtualDataContainerView extends ContainerView implements 
IListView
+       {
+               public function VirtualDataContainerView()
+               {
+                       super();
+               }
+               
+               /**
+                *  @copy org.apache.royale.core.IBead#strand
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.8
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+                       super.strand = value;
+                       
+                       host.addEventListener("beadsAdded", beadsAddedHandler);
+               }
+               
+               protected var dataModel:IDataProviderModel;
+               
+               /**
+                * @royaleignorecoercion 
org.apache.royale.core.IItemRendererParent
+                */
+               public function get dataGroup():IItemRendererParent
+               {
+                       return super.contentView as IItemRendererParent;
+               }
+               
+               protected function beadsAddedHandler(event:Event):void
+               {
+                       dataModel = _strand.getBeadByType(IDataProviderModel) 
as IDataProviderModel;
+                       host.addEventListener("itemsCreated", 
itemsCreatedHandler);
+                       dataModel.addEventListener("dataProviderChanged", 
dataProviderChangeHandler);
+               }
+               
+               /**
+                * @private
+                */
+               override protected function handleInitComplete(event:Event):void
+               {
+                       super.handleInitComplete(event);
+               }
+               
+               /**
+                * @private
+                */
+               protected function itemsCreatedHandler(event:Event):void
+               {
+                       // trace("DataContainerView: itemsCreatedHandler");
+                       host.dispatchEvent(new Event("layoutNeeded"));
+               }
+               
+               /**
+                * @private
+                */
+               protected function dataProviderChangeHandler(event:Event):void
+               {
+                       // trace("DataContainerView: 
dataProviderChangeHandler");
+            adjustView();
+                       performLayout(event);
+               }
+        
+       }
+       
+       COMPILE::SWF
+       public class VirtualDataContainerView extends ContainerView implements 
IListView
+       {
+               public function VirtualDataContainerView()
+               {
+                       super();
+               }
+                                               
+               protected var dataModel:IDataProviderModel;
+               
+               /**
+                * @private
+                */
+               override public function get host():IUIBase
+               {
+                       return _strand as IUIBase;
+               }
+               
+               /**
+                *  @copy org.apache.royale.core.IBead#strand
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.8
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+                       super.strand = value;
+                       
+                       host.addEventListener("beadsAdded", beadsAddedHandler);
+               }
+               
+               override protected function completeSetup():void
+               {
+                       super.completeSetup();
+                       
+                       // list is not interested in UI children, it wants to 
know when new items
+                       // have been added or the dataProvider has changed.
+//                     host.removeEventListener("childrenAdded", 
childrenChangedHandler);
+//                     host.removeEventListener("childrenAdded", 
performLayout);
+               }
+               
+               protected function beadsAddedHandler(event:Event):void
+               {
+                       dataModel = _strand.getBeadByType(IDataProviderModel) 
as IDataProviderModel;
+                       dataModel.addEventListener("dataProviderChanged", 
dataProviderChangeHandler);
+               }
+               
+               override protected function handleInitComplete(event:Event):void
+               {
+                       super.handleInitComplete(event);
+               }
+               
+               /**
+                *  The area holding the itemRenderers.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.8
+                */
+               public function get dataGroup():IItemRendererParent
+               {
+                       return super.contentView as IItemRendererParent;
+               }
+                               
+               /**
+                * @private
+                */
+               override public function get resizableView():IUIBase
+               {
+                       return _strand as IUIBase;
+               }
+                               
+               /**
+                * @private
+                */
+               protected function dataProviderChangeHandler(event:Event):void
+               {
+                       host.dispatchEvent(new Event("layoutNeeded"));
+               }
+                       
+        /**
+         *  respond to a change in size or request to re-layout everything
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+               override protected function resizeHandler(event:Event):void
+               {
+                       // might need to do something here, not sure yet.
+                       super.resizeHandler(event);
+               }
+       }
+}
diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualDataItemRendererFactoryForArrayData.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualDataItemRendererFactoryForArrayData.as
new file mode 100644
index 0000000..e78e67f
--- /dev/null
+++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualDataItemRendererFactoryForArrayData.as
@@ -0,0 +1,215 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.html.beads
+{
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IChild;
+       import org.apache.royale.core.IDataProviderModel;
+       import org.apache.royale.core.IDataProviderVirtualItemRendererMapper;
+       import org.apache.royale.core.IItemRendererClassFactory;
+       import org.apache.royale.core.IItemRendererParent;
+       import org.apache.royale.core.ILayoutHost;
+       import org.apache.royale.core.IList;
+       import org.apache.royale.core.IListPresentationModel;
+       import org.apache.royale.core.IParentIUIBase;
+       import org.apache.royale.core.ISelectableItemRenderer;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.core.SimpleCSSStyles;
+       import org.apache.royale.core.UIBase;
+       import org.apache.royale.core.ValuesManager;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.EventDispatcher;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.events.ItemRendererEvent;
+       import org.apache.royale.html.List;
+       import org.apache.royale.html.supportClasses.DataItemRenderer;
+       import org.apache.royale.utils.loadBeadFromValuesManager;
+
+    
[Event(name="itemRendererCreated",type="org.apache.royale.events.ItemRendererEvent")]
+       
+    /**
+     *  The DataItemRendererFactoryForArrayData class reads an
+     *  array of data and creates an item renderer for every
+     *  item in the array.  Other implementations of
+     *  IDataProviderItemRendererMapper map different data 
+     *  structures or manage a virtual set of renderers.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+       public class VirtualDataItemRendererFactoryForArrayData extends 
EventDispatcher implements IBead, IDataProviderVirtualItemRendererMapper
+       {
+        /**
+         *  Constructor.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+               public function 
VirtualDataItemRendererFactoryForArrayData(target:Object=null)
+               {
+                       super(target);
+               }
+
+               protected var dataProviderModel:IDataProviderModel;
+               protected var dataFieldProvider:DataFieldProviderBead;
+               
+               protected var labelField:String;
+        protected var dataField:String;
+
+               private var _strand:IStrand;
+               
+        /**
+         *  @copy org.apache.royale.core.IBead#strand
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+               public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+                       
IEventDispatcher(value).addEventListener("initComplete",finishSetup);
+               }
+               
+               /**
+                * @private
+                */
+               private function finishSetup(event:Event):void
+               {                       
+                       dataProviderModel = 
_strand.getBeadByType(IDataProviderModel) as IDataProviderModel;
+                       
dataProviderModel.addEventListener("dataProviderChanged", 
dataProviderChangeHandler);
+                       labelField = dataProviderModel.labelField;
+
+            dataFieldProvider = _strand.getBeadByType(DataFieldProviderBead) 
as DataFieldProviderBead;
+                       if (dataFieldProvider)
+            {
+                dataField = dataFieldProvider.dataField;
+            }
+
+                       // if the host component inherits from 
DataContainerBase, the itemRendererClassFactory will 
+                       // already have been loaded by 
DataContainerBase.addedToParent function.
+                       if(!_itemRendererFactory)
+                       _itemRendererFactory = 
loadBeadFromValuesManager(IItemRendererClassFactory, 
"iItemRendererClassFactory", _strand) as IItemRendererClassFactory;             
            
+                       
+                       dataProviderChangeHandler(null);
+               }
+               
+               private var _itemRendererFactory:IItemRendererClassFactory;
+               
+        /**
+         *  The org.apache.royale.core.IItemRendererClassFactory used 
+         *  to generate instances of item renderers.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+               public function get 
itemRendererFactory():IItemRendererClassFactory
+               {
+                       if(!_itemRendererFactory)
+                       _itemRendererFactory = 
loadBeadFromValuesManager(IItemRendererClassFactory, 
"iItemRendererClassFactory", _strand) as IItemRendererClassFactory;
+                       
+                       return _itemRendererFactory;
+               }
+               
+        /**
+         *  @private
+         */
+               public function set 
itemRendererFactory(value:IItemRendererClassFactory):void
+               {
+                       _itemRendererFactory = value;
+               }
+               
+        /**
+         *  The org.apache.royale.core.IItemRendererParent that will
+         *  parent the item renderers.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */            
+               protected function dataProviderChangeHandler(event:Event):void
+               {
+                       var dp:Array = dataProviderModel.dataProvider as Array;
+                       if (!dp)
+                               return;
+                       
+                       var list:IList = _strand as IList;
+                       var dataGroup:IItemRendererParent = list.dataGroup;
+                       
+                       dataGroup.removeAllItemRenderers();
+        }
+        
+        public function freeItemRendererForIndex(index:int):void
+        {
+            var ir:ISelectableItemRenderer = rendererMap[index];
+            var list:IList = _strand as IList;
+            var dataGroup:IItemRendererParent = list.dataGroup;
+            dataGroup.removeItemRenderer(ir);
+            delete rendererMap[index];
+        }
+        
+        private var rendererMap:Object = {};
+        
+        public function getItemRendererForIndex(index:int, 
elementIndex:int):ISelectableItemRenderer
+        {
+            var ir:ISelectableItemRenderer = rendererMap[index];
+            if (ir) return ir;
+            
+            var dp:Array = dataProviderModel.dataProvider as Array;
+            
+                       ir = itemRendererFactory.createItemRenderer(dataGroup) 
as ISelectableItemRenderer;
+            var dataItemRenderer:DataItemRenderer = ir as DataItemRenderer;
+
+            var list:IList = _strand as IList;
+            var dataGroup:IItemRendererParent = list.dataGroup;
+                       dataGroup.addItemRendererAt(ir, elementIndex);
+                       ir.index = index;
+                       ir.labelField = labelField;
+            if (dataItemRenderer)
+            {
+                dataItemRenderer.dataField = dataField;
+            }
+            rendererMap[index] = ir;
+            
+            var presentationModel:IListPresentationModel = 
_strand.getBeadByType(IListPresentationModel) as IListPresentationModel;
+                       if (presentationModel) {
+                               var style:SimpleCSSStyles = new 
SimpleCSSStyles();
+                               style.marginBottom = 
presentationModel.separatorThickness;
+                               UIBase(ir).style = style;
+                               UIBase(ir).height = presentationModel.rowHeight;
+                               UIBase(ir).percentWidth = 100;
+                       }
+                       ir.data = dp[index];
+                               
+                       var newEvent:ItemRendererEvent = new 
ItemRendererEvent(ItemRendererEvent.CREATED);
+                       newEvent.itemRenderer = ir;
+                       dispatchEvent(newEvent);
+            return ir;
+               }
+       }
+}
diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualListView.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualListView.as
new file mode 100644
index 0000000..f125deb
--- /dev/null
+++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/VirtualListView.as
@@ -0,0 +1,185 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.html.beads
+{
+       import org.apache.royale.core.BeadViewBase;
+       import org.apache.royale.core.ContainerBase;
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IBeadLayout;
+       import org.apache.royale.core.IBeadModel;
+       import org.apache.royale.core.IBeadView;
+       import org.apache.royale.core.IList;
+       import org.apache.royale.core.ISelectableItemRenderer;
+       import org.apache.royale.core.IItemRenderer;
+       import org.apache.royale.core.IItemRendererParent;
+       import org.apache.royale.core.IParent;
+    import org.apache.royale.core.IParentIUIBase;
+       import org.apache.royale.core.IRollOverModel;
+       import org.apache.royale.core.ISelectionModel;
+       import org.apache.royale.core.IStrand;
+    import org.apache.royale.core.IUIBase;
+       import org.apache.royale.core.Strand;
+       import org.apache.royale.core.UIBase;
+       import org.apache.royale.core.ValuesManager;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.html.beads.models.ArraySelectionModel;
+       import org.apache.royale.html.supportClasses.Border;
+       import org.apache.royale.html.supportClasses.DataGroup;
+
+       /**
+        *  The List class creates the visual elements of the 
org.apache.royale.html.List
+        *  component. A List consists of the area to display the data (in the 
dataGroup), any
+        *  scrollbars, and so forth.
+        *
+        *  @viewbead
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.0
+        */
+       COMPILE::JS
+       public class VirtualListView extends VirtualDataContainerView
+       {
+               public function VirtualListView()
+               {
+                       super();
+               }
+
+               protected var listModel:ISelectionModel;
+
+               protected var lastSelectedIndex:int = -1;
+
+               /**
+                * @private
+                */
+               override protected function handleInitComplete(event:Event):void
+               {
+                       listModel = _strand.getBeadByType(ISelectionModel) as 
ISelectionModel;
+                       listModel.addEventListener("selectedIndexChanged", 
selectionChangeHandler);
+                       listModel.addEventListener("rollOverIndexChanged", 
rollOverIndexChangeHandler);
+
+                       super.handleInitComplete(event);
+               }
+
+               /**
+                * @private
+                * @royaleignorecoercion 
org.apache.royale.core.ISelectableItemRenderer
+                */
+               protected function selectionChangeHandler(event:Event):void
+               {
+                       var ir:ISelectableItemRenderer = 
dataGroup.getItemRendererForIndex(lastSelectedIndex) as ISelectableItemRenderer;
+                       if(ir)
+                               ir.selected = false;
+                       ir = 
dataGroup.getItemRendererForIndex(listModel.selectedIndex) as 
ISelectableItemRenderer;
+                       if(ir)
+                               ir.selected = true;
+
+                       lastSelectedIndex = listModel.selectedIndex;
+               }
+
+               protected var lastRollOverIndex:int = -1;
+
+               /**
+                * @private
+                * @royaleignorecoercion 
org.apache.royale.core.ISelectableItemRenderer
+                * * @royaleignorecoercion org.apache.royale.core.IRollOverModel
+                */
+               protected function rollOverIndexChangeHandler(event:Event):void
+               {
+                       var ir:ISelectableItemRenderer = 
dataGroup.getItemRendererForIndex(lastRollOverIndex) as ISelectableItemRenderer;
+                       if(ir)
+                               ir.hovered = false;
+                       ir = dataGroup.getItemRendererForIndex((listModel as 
IRollOverModel).rollOverIndex) as ISelectableItemRenderer;
+                       if(ir)
+                               ir.hovered = true;
+                       lastRollOverIndex = (listModel as 
IRollOverModel).rollOverIndex;
+               }
+       }
+
+       COMPILE::SWF
+       public class VirtualListView extends VirtualDataContainerView
+       {
+               public function VirtualListView()
+               {
+                       super();
+               }
+
+               protected var listModel:ISelectionModel;
+
+               /**
+                *  @copy org.apache.royale.core.IBead#strand
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.0
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+                       super.strand = value;
+               }
+
+               /**
+                * @private
+                */
+               override protected function handleInitComplete(event:Event):void
+               {
+                       super.handleInitComplete(event);
+
+                       listModel = _strand.getBeadByType(ISelectionModel) as 
ISelectionModel;
+                       listModel.addEventListener("selectedIndexChanged", 
selectionChangeHandler);
+                       listModel.addEventListener("rollOverIndexChanged", 
rollOverIndexChangeHandler);
+               }
+
+               protected var lastSelectedIndex:int = -1;
+
+               /**
+                * @private
+                */
+               protected function selectionChangeHandler(event:Event):void
+               {
+                       var ir:ISelectableItemRenderer = 
dataGroup.getItemRendererForIndex(lastSelectedIndex) as ISelectableItemRenderer;
+            if (ir)
+                               ir.selected = false;
+                       ir = 
dataGroup.getItemRendererForIndex(listModel.selectedIndex) as 
ISelectableItemRenderer;
+                       if (ir)
+                               ir.selected = true;
+            lastSelectedIndex = listModel.selectedIndex;
+               }
+
+               protected var lastRollOverIndex:int = -1;
+
+               /**
+                * @private
+                */
+               protected function rollOverIndexChangeHandler(event:Event):void
+               {
+                       var ir:ISelectableItemRenderer = 
dataGroup.getItemRendererForIndex(lastRollOverIndex) as ISelectableItemRenderer;
+                       if(ir)
+                               ir.hovered = false;
+                       ir = 
dataGroup.getItemRendererForIndex(IRollOverModel(listModel).rollOverIndex) as 
ISelectableItemRenderer;
+                       if(ir)
+                               ir.hovered = true;
+                       
+                       lastRollOverIndex = 
IRollOverModel(listModel).rollOverIndex;
+               }
+       }
+}
diff --git 
a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/layouts/VirtualListVerticalLayout.as
 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/layouts/VirtualListVerticalLayout.as
new file mode 100644
index 0000000..703c024
--- /dev/null
+++ 
b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/layouts/VirtualListVerticalLayout.as
@@ -0,0 +1,309 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.html.beads.layouts
+{
+       import org.apache.royale.core.IBeadLayout;
+       import org.apache.royale.core.IBeadModel;
+       import org.apache.royale.core.IDataProviderModel;
+       import org.apache.royale.core.IDataProviderVirtualItemRendererMapper;
+       import org.apache.royale.core.ILayoutChild;
+       import org.apache.royale.core.ILayoutHost;
+       import org.apache.royale.core.ILayoutParent;
+       import org.apache.royale.core.ILayoutView;
+       import org.apache.royale.core.IListPresentationModel;
+       import org.apache.royale.core.IListWithPresentationModel;
+       import org.apache.royale.core.IParentIUIBase;
+       import org.apache.royale.core.ISelectableItemRenderer;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.core.LayoutBase;
+       import org.apache.royale.core.ValuesManager;
+       COMPILE::JS
+       {
+               import org.apache.royale.core.WrappedHTMLElement;
+       }
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.geom.Rectangle;
+       import org.apache.royale.utils.CSSContainerUtils;
+       import org.apache.royale.utils.CSSUtils;
+
+       /**
+        *  The VerticalLayout class is a simple layout
+        *  bead.  It takes the set of children and lays them out
+        *  vertically in one column, separating them according to
+        *  CSS layout rules for margin and horizontal-align styles.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.0
+        */
+       public class VirtualListVerticalLayout extends LayoutBase implements 
IBeadLayout
+       {
+               /**
+                *  Constructor.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.0
+         *  @royaleignorecoercion HTMLDivElement
+                */
+               public function VirtualListVerticalLayout()
+               {
+                       super();
+               }
+
+        protected var dataProviderModel:IDataProviderModel;
+
+        override public function set strand(value:IStrand):void
+        {
+            super.strand = value;
+            dataProviderModel = host.getBeadByType(IDataProviderModel) as 
IDataProviderModel;
+            COMPILE::JS
+            {
+                host.element.addEventListener("scroll", scrollHandler);
+            }
+        }
+        
+        COMPILE::JS
+        private var topSpacer:HTMLDivElement;
+        
+        COMPILE::JS
+        private var bottomSpacer:HTMLDivElement;
+        
+        COMPILE::JS
+        private var visibleIndexes:Array = [];
+        
+        COMPILE::JS
+        private function scrollHandler(e:Event):void
+        {
+            layout();
+        }
+        
+        private var inLayout:Boolean;
+        
+               /**
+                *  Layout children vertically
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.0
+                *  @royaleignorecoercion org.apache.royale.core.ILayoutHost
+                *  @royaleignorecoercion 
org.apache.royale.core.WrappedHTMLElement
+                */
+               override public function layout():Boolean
+               {
+            if (inLayout) return true;
+            inLayout = true;
+            
+                       COMPILE::SWF
+                       {
+                               var contentView:ILayoutView = layoutView;
+
+                               var n:Number = contentView.numElements;
+                               if (n == 0) return false;
+
+                               var maxWidth:Number = 0;
+                               var maxHeight:Number = 0;
+                               var hostWidthSizedToContent:Boolean = 
host.isWidthSizedToContent();
+                               var hostHeightSizedToContent:Boolean = 
host.isHeightSizedToContent();
+                               var hostWidth:Number = host.width;
+                               var hostHeight:Number = host.height;
+
+                               var ilc:ILayoutChild;
+                               var data:Object;
+                               var canAdjust:Boolean = false;
+
+                               var paddingMetrics:Rectangle = 
CSSContainerUtils.getPaddingMetrics(host);
+                               var borderMetrics:Rectangle = 
CSSContainerUtils.getBorderMetrics(host);
+                               
+                               // adjust the host's usable size by the 
metrics. If hostSizedToContent, then the
+                               // resulting adjusted value may be less than 
zero.
+                               hostWidth -= paddingMetrics.left + 
paddingMetrics.right + borderMetrics.left + borderMetrics.right;
+                               hostHeight -= paddingMetrics.top + 
paddingMetrics.bottom + borderMetrics.top + borderMetrics.bottom;
+
+                               var xpos:Number = borderMetrics.left + 
paddingMetrics.left;
+                               var ypos:Number = borderMetrics.top + 
paddingMetrics.top;
+
+                               // First pass determines the data about the 
child.
+                               for(var i:int=0; i < n; i++)
+                               {
+                                       var child:IUIBase = 
contentView.getElementAt(i) as IUIBase;
+                                       if (child == null || !child.visible) 
continue;
+                                       var positions:Object = 
childPositions(child);
+                                       var margins:Object = 
childMargins(child, hostWidth, hostHeight);
+
+                                       ilc = child as ILayoutChild;
+
+                                       ypos += margins.top;
+
+                                       var childXpos:Number = xpos + 
margins.left; // default x position
+
+                                       var childWidth:Number = child.width;
+                                       if (ilc != null && 
!isNaN(ilc.percentWidth)) {
+                                               childWidth = hostWidth * 
ilc.percentWidth/100.0;
+                                               ilc.setWidth(childWidth);
+                                       }
+                                       else if (ilc.isWidthSizedToContent() && 
!margins.auto)
+                                       {
+                                               childWidth = hostWidth;
+                                               ilc.setWidth(childWidth);
+                                       }
+                                       if (margins.auto)
+                                               childXpos = (hostWidth - 
childWidth) / 2;
+                                               
+                                       if (ilc) {
+                                               ilc.setX(childXpos);
+                                               ilc.setY(ypos);
+
+                                               if (!isNaN(ilc.percentHeight)) {
+                                                       var newHeight:Number = 
hostHeight * ilc.percentHeight / 100;
+                                                       
ilc.setHeight(newHeight);
+                                               }
+
+                                       } else {
+                                               child.x = childXpos;
+                                               child.y = ypos;
+                                       }
+
+                                       ypos += child.height + margins.bottom;
+                               }
+
+                inLayout = false;
+                               return true;
+                       }
+                       COMPILE::JS
+                       {
+                // the strategy for virtualization in JS is to leverage the 
built-in scrollbars
+                // by creating a topSpacer and bottomSpacer that take up the 
area that is offscreen
+                // so the scrollbars have the right metrics, then create 
enough renderers to
+                // show in the visible area.  This code does not recycle 
renderers, but the
+                // factory can.  This code does try to keep renderers on the 
DOM that aren't
+                // going off-screen
+                var contentView:ILayoutView = layoutView;
+                var dp:Array = dataProviderModel.dataProvider as Array;
+                var presentationModel:IListPresentationModel = (host as 
IListWithPresentationModel).presentationModel;
+                var totalHeight:Number = presentationModel.rowHeight * 
dp.length;
+                var viewportTop:Number = 
Math.max(contentView.element.scrollTop, 0);
+                var viewportHeight:Number = contentView.element.clientHeight;
+                var startIndex:int = Math.floor(viewportTop / 
presentationModel.rowHeight);
+                var factory:IDataProviderVirtualItemRendererMapper = 
host.getBeadByType(IDataProviderVirtualItemRendererMapper) as 
IDataProviderVirtualItemRendererMapper;
+                var endIndex:int = Math.ceil((viewportTop + viewportHeight) / 
presentationModel.rowHeight);
+                var freeIndex:int;
+                var firstIndex:int;
+                var lastIndex:int;
+                if (!topSpacer)
+                {
+                    topSpacer = document.createElement("div") as 
HTMLDivElement;
+                    contentView.element.appendChild(topSpacer);
+                }
+                topSpacer.style.height = (startIndex * 
presentationModel.rowHeight).toString() + "px";
+                if (visibleIndexes.length)
+                {
+                    if (startIndex < visibleIndexes[0])
+                    {
+                        // see if we can re-use any renderers
+                        freeIndex = visibleIndexes.pop();
+                        while (freeIndex >= endIndex)
+                        {
+                            factory.freeItemRendererForIndex(freeIndex);
+                            if (visibleIndexes.length == 0)
+                                break;
+                            freeIndex = visibleIndexes.pop();
+                        }
+                        if (visibleIndexes.length)
+                            endIndex = visibleIndexes[visibleIndexes.length - 
1];
+                    }
+                    else if (startIndex > visibleIndexes[0])
+                    {
+                        // see if we can re-use any renderers
+                        freeIndex = visibleIndexes.shift();
+                        while (freeIndex < startIndex)
+                        {
+                            factory.freeItemRendererForIndex(freeIndex);
+                            if (visibleIndexes.length == 0)
+                                break;
+                            freeIndex = visibleIndexes.shift();
+                        }
+                    }
+                    else
+                    {
+                        // see if rows got added or removed because height 
changed
+                        lastIndex = visibleIndexes[visibleIndexes.length - 1];
+                        if (lastIndex > endIndex)
+                        {
+                            // see if we can re-use any renderers
+                            freeIndex = visibleIndexes.pop();
+                            while (freeIndex > endIndex)
+                            {
+                                factory.freeItemRendererForIndex(freeIndex);
+                                if (visibleIndexes.length == 0)
+                                    break;
+                                freeIndex = visibleIndexes.pop();
+                            }
+                            inLayout = false;
+                            return true;  // we should be all done if we shrunk
+                        }
+                    }
+                    firstIndex = visibleIndexes[0];
+                    lastIndex = visibleIndexes[visibleIndexes.length - 1];
+                }
+                else
+                {
+                    firstIndex = dp.length;
+                    lastIndex = 0;
+                }
+                for (var i:int = startIndex; i < endIndex; i++)
+                {
+                    var ir:ISelectableItemRenderer;
+                    if (i < firstIndex)
+                    {
+                       ir  = factory.getItemRendererForIndex(i, i - startIndex 
+ 1);
+                       ir.element.style.display = "block";
+                       visibleIndexes.push(i);
+                    }
+                    else if (i > lastIndex)
+                    {
+                        ir  = factory.getItemRendererForIndex(i, i - 
startIndex + 1);
+                        ir.element.style.display = "block";
+                        visibleIndexes.push(i);
+                    }
+                }
+                visibleIndexes = visibleIndexes.sort(numberSort);
+                if (!bottomSpacer)
+                {
+                    bottomSpacer = document.createElement("div") as 
HTMLDivElement;
+                    contentView.element.appendChild(bottomSpacer);
+                }
+                bottomSpacer.style.height = ((dp.length - endIndex) * 
presentationModel.rowHeight).toString() + "px";  
+                inLayout = false;
+                               return true;
+                       }
+               }
+        
+        public function numberSort(a:int, b:int):int
+        {
+            return a - b;
+        }
+
+       }
+}
diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as 
b/frameworks/projects/Core/src/main/royale/CoreClasses.as
index edd9b69..5102ba3 100644
--- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
+++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
@@ -70,6 +70,7 @@ internal class CoreClasses
     import org.apache.royale.core.IContentView; IContentView;
        import org.apache.royale.core.IContentViewHost; IContentViewHost;
     import org.apache.royale.core.IDataProviderItemRendererMapper; 
IDataProviderItemRendererMapper;
+    import org.apache.royale.core.IDataProviderVirtualItemRendererMapper; 
IDataProviderVirtualItemRendererMapper;
        import org.apache.royale.core.IDataProviderNotifier; 
IDataProviderNotifier;
     import org.apache.royale.core.IBinaryImageModel; IBinaryImageModel;
     import org.apache.royale.core.IDocument; IDocument;
diff --git 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/core/IDataProviderVirtualItemRendererMapper.as
 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/core/IDataProviderVirtualItemRendererMapper.as
new file mode 100644
index 0000000..d31aa60
--- /dev/null
+++ 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/core/IDataProviderVirtualItemRendererMapper.as
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.core
+{
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IItemRendererClassFactory;
+
+    /**
+     *  The IDataProviderItemRendererMapper interface is the interface for 
beads
+     *  that know how to iterate through a dataProvider, generate item 
renderers,
+     *  and assign items from the dataProvider to those item renderers.  In 
Royale,
+     *  a wide range of data providers are allowed, from simple Arrays and 
Vectors
+     *  on up to sophisticated data structures that dispatch change events.
+     *  Different IDataProviderItemRendererMapper implements are often 
required to
+     *  iterate through those different data structures.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+       public interface IDataProviderVirtualItemRendererMapper extends 
IDataProviderItemRendererMapper
+       {
+        function freeItemRendererForIndex(index:int):void;
+        function getItemRendererForIndex(index:int, 
elementIndex:int):ISelectableItemRenderer;
+       }
+}

-- 
To stop receiving notification emails like this one, please contact
aha...@apache.org.

Reply via email to