You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2018/02/14 08:14:40 UTC

[royale-asjs] branch develop updated (423e26a -> 913394c)

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

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


    from 423e26a  try to fix asdoc build
     new afe6a2a  JS fixed row height virtual lists
     new 23f0bf1  example for fixed row height virtual lists
     new 1ef1b8b  fix SWF-side virtual lists
     new 913394c  virtual list example

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../ListExample/src/main/royale/MyInitialView.mxml |  22 +-
 .../src/main/royale/models/ProductsModel.as        |  15 +
 .../Basic/src/main/resources/basic-manifest.xml    |   3 +
 .../{IList.as => IListWithPresentationModel.as}    |  12 +-
 .../royale/org/apache/royale/html/DataContainer.as |   3 +-
 ...ontainerView.as => VirtualDataContainerView.as} |  20 +-
 ... VirtualDataItemRendererFactoryForArrayData.as} |  95 +++--
 .../html/beads/{ListView.as => VirtualListView.as} |  30 +-
 .../controllers/ScrollBarMouseControllerBase.as    |   4 +-
 .../beads/layouts/VirtualListVerticalLayout.as     | 401 +++++++++++++++++++++
 .../html/supportClasses/ScrollingViewport.as       |  10 +-
 .../apache/royale/html/supportClasses/Viewport.as  |   3 +-
 .../projects/Core/src/main/royale/CoreClasses.as   |   2 +
 ...s => IDataProviderVirtualItemRendererMapper.as} |  15 +-
 .../{IBorderModel.as => IScrollingViewport.as}     |  33 +-
 15 files changed, 566 insertions(+), 102 deletions(-)
 copy frameworks/projects/Basic/src/main/royale/org/apache/royale/core/{IList.as => IListWithPresentationModel.as} (78%)
 copy frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/{DataContainerView.as => VirtualDataContainerView.as} (93%)
 copy frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/{DataItemRendererFactoryForArrayData.as => VirtualDataItemRendererFactoryForArrayData.as} (72%)
 copy frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/{ListView.as => VirtualListView.as} (89%)
 create mode 100644 frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/layouts/VirtualListVerticalLayout.as
 copy frameworks/projects/Core/src/main/royale/org/apache/royale/core/{IDataProviderItemRendererMapper.as => IDataProviderVirtualItemRendererMapper.as} (77%)
 copy frameworks/projects/Core/src/main/royale/org/apache/royale/core/{IBorderModel.as => IScrollingViewport.as} (68%)

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

[royale-asjs] 03/04: fix SWF-side virtual lists

Posted by ah...@apache.org.
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 1ef1b8b158ab536af8cc00385df195ce27c913bd
Author: Alex Harui <ah...@apache.org>
AuthorDate: Wed Feb 14 00:09:19 2018 -0800

    fix SWF-side virtual lists
---
 .../Basic/src/main/resources/basic-manifest.xml    |   1 +
 .../royale/html/beads/VirtualDataContainerView.as  |   1 -
 .../apache/royale/html/beads/VirtualListView.as    |  22 ++-
 .../controllers/ScrollBarMouseControllerBase.as    |   4 +-
 .../beads/layouts/VirtualListVerticalLayout.as     | 192 +++++++++++++++------
 .../html/supportClasses/ScrollingViewport.as       |  10 +-
 .../apache/royale/html/supportClasses/Viewport.as  |   3 +-
 .../projects/Core/src/main/royale/CoreClasses.as   |   1 +
 .../org/apache/royale/core/IScrollingViewport.as   |  49 ++++++
 9 files changed, 224 insertions(+), 59 deletions(-)

diff --git a/frameworks/projects/Basic/src/main/resources/basic-manifest.xml b/frameworks/projects/Basic/src/main/resources/basic-manifest.xml
index 19d525e..236ab92 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="VirtualListView" class="org.apache.royale.html.beads.VirtualListView"/>
     <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"/>
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
index dc38e6f..86905b8 100644
--- 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
@@ -116,7 +116,6 @@ package org.apache.royale.html.beads
 		protected function dataProviderChangeHandler(event:Event):void
 		{
 			// trace("DataContainerView: dataProviderChangeHandler");
-            adjustView();
 			performLayout(event);
 		}
         
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
index f125deb..b689c2a 100644
--- 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
@@ -25,6 +25,8 @@ package org.apache.royale.html.beads
 	import org.apache.royale.core.IBeadModel;
 	import org.apache.royale.core.IBeadView;
 	import org.apache.royale.core.IList;
+    import org.apache.royale.core.IListPresentationModel;
+    import org.apache.royale.core.IListWithPresentationModel;
 	import org.apache.royale.core.ISelectableItemRenderer;
 	import org.apache.royale.core.IItemRenderer;
 	import org.apache.royale.core.IItemRendererParent;
@@ -42,7 +44,10 @@ package org.apache.royale.html.beads
 	import org.apache.royale.html.beads.models.ArraySelectionModel;
 	import org.apache.royale.html.supportClasses.Border;
 	import org.apache.royale.html.supportClasses.DataGroup;
-
+    COMPILE::SWF {
+        import org.apache.royale.geom.Size;
+    }
+        
 	/**
 	 *  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
@@ -181,5 +186,18 @@ package org.apache.royale.html.beads
 			
 			lastRollOverIndex = IRollOverModel(listModel).rollOverIndex;
 		}
-	}
+
+        override protected function calculateContentSize():Size
+        {
+            return _lastContentSize;
+        }
+        
+        private var _lastContentSize:Size;
+        
+        public function set lastContentSize(value:Size):void
+        {
+            _lastContentSize = value;
+        }
+
+    }
 }
diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ScrollBarMouseControllerBase.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ScrollBarMouseControllerBase.as
index fdbc6a0..ae7bc4c 100644
--- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ScrollBarMouseControllerBase.as
+++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ScrollBarMouseControllerBase.as
@@ -135,7 +135,7 @@ package org.apache.royale.html.beads.controllers
          *  @playerversion AIR 2.6
          *  @productversion Royale 0.0
          */	
-		protected function decrementClickHandler(event:Event):void
+		protected function decrementClickHandler(event:MouseEvent):void
 		{
 			sbModel.value = snap(Math.max(sbModel.minimum, sbModel.value - sbModel.stepSize));
 			IEventDispatcher(_strand).dispatchEvent(new Event("scroll"));
@@ -149,7 +149,7 @@ package org.apache.royale.html.beads.controllers
          *  @playerversion AIR 2.6
          *  @productversion Royale 0.0
          */	
-		protected function incrementClickHandler(event:Event):void
+		protected function incrementClickHandler(event:MouseEvent):void
 		{
 			sbModel.value = snap(Math.min(sbModel.maximum - sbModel.pageSize, sbModel.value + sbModel.stepSize));	
 			IEventDispatcher(_strand).dispatchEvent(new Event("scroll"));
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
index 703c024..79b6c82 100644
--- 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
@@ -29,6 +29,7 @@ package org.apache.royale.html.beads.layouts
 	import org.apache.royale.core.IListPresentationModel;
 	import org.apache.royale.core.IListWithPresentationModel;
 	import org.apache.royale.core.IParentIUIBase;
+    import org.apache.royale.core.IScrollingViewport;
 	import org.apache.royale.core.ISelectableItemRenderer;
 	import org.apache.royale.core.IStrand;
 	import org.apache.royale.core.IUIBase;
@@ -41,9 +42,13 @@ package org.apache.royale.html.beads.layouts
 	import org.apache.royale.events.Event;
 	import org.apache.royale.events.IEventDispatcher;
 	import org.apache.royale.geom.Rectangle;
+    import org.apache.royale.html.beads.VirtualListView;
 	import org.apache.royale.utils.CSSContainerUtils;
 	import org.apache.royale.utils.CSSUtils;
-
+    COMPILE::SWF {
+        import org.apache.royale.geom.Size;
+    }
+        
 	/**
 	 *  The VerticalLayout class is a simple layout
 	 *  bead.  It takes the set of children and lays them out
@@ -89,10 +94,8 @@ package org.apache.royale.html.beads.layouts
         COMPILE::JS
         private var bottomSpacer:HTMLDivElement;
         
-        COMPILE::JS
         private var visibleIndexes:Array = [];
         
-        COMPILE::JS
         private function scrollHandler(e:Event):void
         {
             layout();
@@ -117,19 +120,22 @@ package org.apache.royale.html.beads.layouts
             
 			COMPILE::SWF
 			{
+                // the strategy for virtualization in SWF is based on the
+                // fact that we can completely control the scrolling metrics
+                // instead of trying to rely on the browsers built-in scrolling.
+                // This code puts enough renderers on the screen and then dictates
+                // the scrolling metrics.
 				var contentView:ILayoutView = layoutView;
 
-				var n:Number = contentView.numElements;
-				if (n == 0) return false;
-
 				var maxWidth:Number = 0;
 				var maxHeight:Number = 0;
+                var dp:Array = dataProviderModel.dataProvider as Array;
+                var presentationModel:IListPresentationModel = (host as IListWithPresentationModel).presentationModel;
 				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;
 
@@ -142,51 +148,94 @@ package org.apache.royale.html.beads.layouts
 				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);
-						}
+                var ypos:Number = borderMetrics.top + paddingMetrics.top;
+                
+                var viewport:IScrollingViewport = host.getBeadByType(IScrollingViewport) as IScrollingViewport;
+                viewport.addEventListener("verticalScrollPositionChanged", scrollHandler);
+                var viewportTop:Number = viewport.verticalScrollPosition;
+                var viewportHeight:Number = hostHeight;
+                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;
 
-					} else {
-						child.x = childXpos;
-						child.y = ypos;
-					}
+                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);
+                        sizeAndPositionRenderer(ir, xpos, ypos + (presentationModel.rowHeight * i), hostWidth, hostHeight);
+                        visibleIndexes.push(i);
+                    }
+                    else if (i > lastIndex)
+                    {
+                        ir  = factory.getItemRendererForIndex(i, i - startIndex);
+                        sizeAndPositionRenderer(ir, xpos, ypos + (presentationModel.rowHeight * i), hostWidth, hostHeight);
+                        visibleIndexes.push(i);
+                    }
+                }
+                visibleIndexes = visibleIndexes.sort(numberSort);
 
-					ypos += child.height + margins.bottom;
-				}
+                var view:VirtualListView = host.getBeadByType(VirtualListView) as VirtualListView;
+                view.lastContentSize = new Size(hostWidth, dp.length * presentationModel.rowHeight);
 
                 inLayout = false;
 				return true;
@@ -305,5 +354,48 @@ package org.apache.royale.html.beads.layouts
             return a - b;
         }
 
+        COMPILE::SWF
+        private function sizeAndPositionRenderer(ir:ISelectableItemRenderer, xpos:Number, ypos:Number, hostWidth:Number, hostHeight:Number):void
+        {
+            var ilc:ILayoutChild;
+            var positions:Object = childPositions(ir);
+            var margins:Object = childMargins(ir, hostWidth, hostHeight);
+            
+            ilc = ir as ILayoutChild;
+            var child:IUIBase = ir as IUIBase;
+            
+            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;
+        }
 	}
 }
diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ScrollingViewport.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ScrollingViewport.as
index 80b4819..a555a44 100644
--- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ScrollingViewport.as
+++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ScrollingViewport.as
@@ -25,7 +25,7 @@ package org.apache.royale.html.supportClasses
 	import org.apache.royale.core.IParentIUIBase;
 	import org.apache.royale.core.IStrand;
 	import org.apache.royale.core.IUIBase;
-	import org.apache.royale.core.IViewport;
+	import org.apache.royale.core.IScrollingViewport;
 	import org.apache.royale.core.IViewportModel;
     COMPILE::SWF
     {
@@ -53,7 +53,7 @@ package org.apache.royale.html.supportClasses
 	 *  @productversion Royale 0.0
 	 */
 	COMPILE::JS
-	public class ScrollingViewport extends Viewport implements IBead, IViewport
+	public class ScrollingViewport extends Viewport implements IBead, IScrollingViewport
 	{
 		/**
 		 * Constructor
@@ -117,7 +117,7 @@ package org.apache.royale.html.supportClasses
 	}
 	
 	COMPILE::SWF
-	public class ScrollingViewport extends Viewport implements IBead, IViewport
+	public class ScrollingViewport extends Viewport implements IBead, IScrollingViewport
 	{
 		/**
 		 * Constructor
@@ -155,6 +155,7 @@ package org.apache.royale.html.supportClasses
         public function set verticalScrollPosition(value:Number):void
         {
 			_verticalScrollPosition = value;
+            dispatchEvent(new Event("verticalScrollPositionChanged"));
 			handleVerticalScrollChange();
         }
 
@@ -167,6 +168,7 @@ package org.apache.royale.html.supportClasses
         public function set horizontalScrollPosition(value:Number):void
         {
 			_horizontalScrollPosition = value;
+            dispatchEvent(new Event("horizontalScrollPositionChanged"));
 			handleHorizontalScrollChange();
         }
 
@@ -315,6 +317,7 @@ package org.apache.royale.html.supportClasses
 			contentArea.scrollRect = rect;
 
 			_verticalScrollPosition = vpos;
+            dispatchEvent(new Event("verticalScrollPositionChanged"));
 		}
 
 		private function handleHorizontalScroll(event:Event):void
@@ -326,6 +329,7 @@ package org.apache.royale.html.supportClasses
 			contentArea.scrollRect = rect;
 
 			_horizontalScrollPosition = hpos;
+            dispatchEvent(new Event("horizontalScrollPositionChanged"));
 		}
 
 		private function handleVerticalScrollChange():void
diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/Viewport.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/Viewport.as
index aee65ea..ba2d844 100644
--- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/Viewport.as
+++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/Viewport.as
@@ -28,6 +28,7 @@ package org.apache.royale.html.supportClasses
 	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.geom.Rectangle;
     import org.apache.royale.geom.Size;
     import org.apache.royale.utils.CSSContainerUtils;
@@ -48,7 +49,7 @@ package org.apache.royale.html.supportClasses
 	 *  @playerversion AIR 2.6
 	 *  @productversion Royale 0.0
      */
-	public class Viewport implements IBead, IViewport
+	public class Viewport extends EventDispatcher implements IBead, IViewport
 	{
 		/**
 		 * Constructor
diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as b/frameworks/projects/Core/src/main/royale/CoreClasses.as
index 5102ba3..0408118 100644
--- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
+++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
@@ -111,6 +111,7 @@ internal class CoreClasses
     import org.apache.royale.core.IUIBase; IUIBase;
     import org.apache.royale.core.IValueToggleButtonModel; IValueToggleButtonModel;
 	import org.apache.royale.core.IViewport; IViewport;
+    import org.apache.royale.core.IScrollingViewport; IScrollingViewport;
 	import org.apache.royale.core.IViewportModel; IViewportModel;
 	COMPILE::SWF
 	{
diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/core/IScrollingViewport.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/core/IScrollingViewport.as
new file mode 100644
index 0000000..e0deb3a
--- /dev/null
+++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/core/IScrollingViewport.as
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.events.IEventDispatcher;
+
+	/**
+	 * A ScrollingViewport is a Viewport that scrolls overflow content.
+	 */
+    public interface IScrollingViewport extends IViewport, IEventDispatcher
+	{
+        /**
+         * Vertical scroll position.
+	     *
+	     *  @langversion 3.0
+	     *  @playerversion Flash 10.2
+	     *  @playerversion AIR 2.6
+	     *  @productversion Royale 0.0
+         */
+        function get verticalScrollPosition():Number;
+
+        /**
+         * Horizontal scroll position.
+         *
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+        function get horizontalScrollPosition():Number;
+
+	}
+}

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

[royale-asjs] 04/04: virtual list example

Posted by ah...@apache.org.
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 913394c018789f9aae4f29259acc9b305a50fb57
Author: Alex Harui <ah...@apache.org>
AuthorDate: Wed Feb 14 00:09:50 2018 -0800

    virtual list example
---
 examples/royale/ListExample/src/main/royale/MyInitialView.mxml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/examples/royale/ListExample/src/main/royale/MyInitialView.mxml b/examples/royale/ListExample/src/main/royale/MyInitialView.mxml
index abcbd33..2019a00 100644
--- a/examples/royale/ListExample/src/main/royale/MyInitialView.mxml
+++ b/examples/royale/ListExample/src/main/royale/MyInitialView.mxml
@@ -131,6 +131,7 @@ limitations under the License.
             is using an ArrayList as its dataProvider -->
             <js:VirtualDataItemRendererFactoryForArrayData />
             <js:VirtualListVerticalLayout />
+            <js:VirtualListView />
         </js:beads>
     </js:List>
     

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

[royale-asjs] 01/04: JS fixed row height virtual lists

Posted by ah...@apache.org.
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 <ah...@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
aharui@apache.org.

[royale-asjs] 02/04: example for fixed row height virtual lists

Posted by ah...@apache.org.
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 23f0bf19db7f7faaf518a1a123eab82d037a4435
Author: Alex Harui <ah...@apache.org>
AuthorDate: Tue Feb 13 17:09:42 2018 -0800

    example for fixed row height virtual lists
---
 .../ListExample/src/main/royale/MyInitialView.mxml  | 21 ++++++++++++++++++++-
 .../src/main/royale/models/ProductsModel.as         | 15 +++++++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/examples/royale/ListExample/src/main/royale/MyInitialView.mxml b/examples/royale/ListExample/src/main/royale/MyInitialView.mxml
index 2a97d31..abcbd33 100644
--- a/examples/royale/ListExample/src/main/royale/MyInitialView.mxml
+++ b/examples/royale/ListExample/src/main/royale/MyInitialView.mxml
@@ -115,5 +115,24 @@ limitations under the License.
 	</gen:GenericList>
 	
 	<js:TextButton text="Add Wing Bats" x="580" y="350" click="addProduct()" />
-	
+
+    <!-- A virtual list
+    -->
+    
+    <js:Label x="880" y="20" text="A virtual List" />
+    
+    <js:List x="880" y="40" width="200" height="300" >
+        <js:beads>
+            <js:ConstantBinding
+                sourceID="applicationModel"
+                sourcePropertyName="bigArray"
+                destinationPropertyName="dataProvider" />
+            <!-- you also add this itemRendererFactory if your DataContainer list
+            is using an ArrayList as its dataProvider -->
+            <js:VirtualDataItemRendererFactoryForArrayData />
+            <js:VirtualListVerticalLayout />
+        </js:beads>
+    </js:List>
+    
+
 </js:View>
diff --git a/examples/royale/ListExample/src/main/royale/models/ProductsModel.as b/examples/royale/ListExample/src/main/royale/models/ProductsModel.as
index 7ae33ca..f4601eb 100644
--- a/examples/royale/ListExample/src/main/royale/models/ProductsModel.as
+++ b/examples/royale/ListExample/src/main/royale/models/ProductsModel.as
@@ -40,5 +40,20 @@ package models
 		{
 			return _states;
 		}
+        
+        public var _bigArray:Array;
+        
+        public function get bigArray():Array
+        {
+            if (!_bigArray)
+            {
+                _bigArray = [];
+                for (var i:int = 0; i < 1000; i++)
+                {
+                    _bigArray.push("row " + i.toString());
+                }
+            }
+            return _bigArray;
+        }
 	}
 }

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