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 <aha...@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
aha...@apache.org.

Reply via email to