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 <[email protected]> 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 [email protected].
