You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ca...@apache.org on 2020/04/27 16:09:57 UTC
[royale-asjs] branch develop updated: jewel-seachfilterforlist: fix
for scrollToIndex when filtering items in a list and other improvements and
performance optimizations
This is an automated email from the ASF dual-hosted git repository.
carlosrovira pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/develop by this push:
new ca9bfeb jewel-seachfilterforlist: fix for scrollToIndex when filtering items in a list and other improvements and performance optimizations
ca9bfeb is described below
commit ca9bfeb7b57edd96ce4013c9f74d67fe9f8160b3
Author: Carlos Rovira <ca...@apache.org>
AuthorDate: Mon Apr 27 18:09:52 2020 +0200
jewel-seachfilterforlist: fix for scrollToIndex when filtering items in a list and other improvements and performance optimizations
---
.../beads/controllers/ListKeyDownController.as | 8 +-
.../controls/textinput/SearchFilterForList.as | 144 +++++++++++++--------
2 files changed, 96 insertions(+), 56 deletions(-)
diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListKeyDownController.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListKeyDownController.as
index 5feefe7..8403763 100644
--- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListKeyDownController.as
+++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ListKeyDownController.as
@@ -100,7 +100,7 @@ package org.apache.royale.jewel.beads.controllers
listModel = value.getBeadByType(ISelectionModel) as ISelectionModel;
listView = value.getBeadByType(IListView) as IListView;
- listenOnStrand(KeyboardEvent.KEY_DOWN, keyEventHandler);
+ listenOnStrand(KeyboardEvent.KEY_DOWN, keyDownEventHandler);
}
/**
@@ -113,13 +113,13 @@ package org.apache.royale.jewel.beads.controllers
*/
public function tearDown():void
{
- IEventDispatcher(_strand).removeEventListener(KeyboardEvent.KEY_DOWN, keyEventHandler);
+ IEventDispatcher(_strand).removeEventListener(KeyboardEvent.KEY_DOWN, keyDownEventHandler);
}
/**
* @private
*/
- protected function keyEventHandler(event:KeyboardEvent):void
+ protected function keyDownEventHandler(event:KeyboardEvent):void
{
// avoid Tab loose the normal behaviour, for navigation we don't want build int scrolling support in browsers
if(event.key === KeyboardEvent.KEYCODE__TAB)
@@ -146,7 +146,7 @@ package org.apache.royale.jewel.beads.controllers
var ir:IFocusable = listView.dataGroup.getItemRendererForIndex(listModel.selectedIndex) as IFocusable;
ir.setFocus();
- (listView as IScrollToIndexView).scrollToIndex(index);
+ (listView as IScrollToIndexView).scrollToIndex(listModel.selectedIndex);
sendEvent(listView.host, 'change');
}
diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/textinput/SearchFilterForList.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/textinput/SearchFilterForList.as
index e538d1e..d110e4e 100644
--- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/textinput/SearchFilterForList.as
+++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controls/textinput/SearchFilterForList.as
@@ -21,7 +21,7 @@ package org.apache.royale.jewel.beads.controls.textinput
import org.apache.royale.core.Bead;
import org.apache.royale.core.IBeadKeyController;
import org.apache.royale.core.IFocusable;
- import org.apache.royale.core.IItemRendererOwnerView;
+ import org.apache.royale.core.IItemRenderer;
import org.apache.royale.core.IRemovableBead;
import org.apache.royale.core.IStrand;
import org.apache.royale.events.Event;
@@ -29,8 +29,9 @@ package org.apache.royale.jewel.beads.controls.textinput
import org.apache.royale.html.beads.IListView;
import org.apache.royale.html.util.getLabelFromData;
import org.apache.royale.jewel.List;
- import org.apache.royale.jewel.beads.views.IScrollToIndexView;
+ import org.apache.royale.jewel.beads.models.ListPresentationModel;
import org.apache.royale.jewel.itemRenderers.ListItemRenderer;
+ import org.apache.royale.jewel.supportClasses.list.IListPresentationModel;
import org.apache.royale.jewel.supportClasses.textinput.TextInputBase;
import org.apache.royale.utils.sendEvent;
@@ -75,24 +76,30 @@ package org.apache.royale.jewel.beads.controls.textinput
{
if(_list)
{
- list.removeEventListener(KeyboardEvent.KEY_DOWN, keyEventHandler, true);
+ list.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownEventHandler, true);
}
_list = value;
if(_list)
{
+ // remove the ListKeyDownController since we need cutom handling of keys based on visible items
var keyBead:IRemovableBead = _list.getBeadByType(IBeadKeyController) as IRemovableBead;
if(keyBead)
{
keyBead.tearDown();
_list.removeBead(keyBead);
}
- list.addEventListener(KeyboardEvent.KEY_DOWN, keyEventHandler, true);
+ list.addEventListener(KeyboardEvent.KEY_DOWN, keyDownEventHandler, true);
}
}
- protected function keyEventHandler(event:KeyboardEvent):void
+ /**
+ *
+ *
+ * @param event
+ */
+ protected function keyDownEventHandler(event:KeyboardEvent):void
{
// avoid Tab loose the normal behaviour, for navigation we don't want build int scrolling support in browsers
if(event.key === KeyboardEvent.KEYCODE__TAB)
@@ -101,30 +108,79 @@ package org.apache.royale.jewel.beads.controls.textinput
event.preventDefault();
var index:int = visibleIndexes.indexOf(list.selectedIndex);
- currentIndex = index;
-
+
if(event.key === KeyboardEvent.KEYCODE__UP || event.key === KeyboardEvent.KEYCODE__LEFT)
{
if(index > 0)
- currentIndex = prevIndex;
+ list.selectedIndex = visibleIndexes[index - 1];
}
else if(event.key === KeyboardEvent.KEYCODE__DOWN || event.key === KeyboardEvent.KEYCODE__RIGHT)
{
- currentIndex = nextIndex;
+ if(index < visibleIndexes.length - 1)
+ list.selectedIndex = visibleIndexes[index + 1];
}
- if(index != currentIndex)
+ if(visibleIndexes[index] != list.selectedIndex)
{
- list.selectedItem = list.dataProvider.getItemAt(currentIndex);
+ list.selectedItem = list.dataProvider.getItemAt(list.selectedIndex);
- var fir:IFocusable = (list.view as IListView).dataGroup.getItemRendererForIndex(currentIndex) as IFocusable;
- fir.setFocus();
+ var ir:IFocusable = (list.view as IListView).dataGroup.getItemRendererForIndex(list.selectedIndex) as IFocusable;
+ ir.setFocus();
- (list.view as IScrollToIndexView).scrollToIndex(index);
+ COMPILE::JS
+ {
+ scrollToIndex(list.selectedIndex);
+ }
sendEvent(list, 'change');
}
}
+
+ /**
+ * Ensures that the data provider item at the given index is visible.
+ *
+ * This implementation consider only visible items
+ *
+ * @param index The index of the item in the data provider.
+ *
+ * @return <code>true</code> if <code>verticalScrollPosition</code> changed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Royale 0.9.7
+ */
+ COMPILE::JS
+ public function scrollToIndex(index:int):Boolean
+ {
+ var scrollArea:HTMLElement = list.element;
+ var oldScroll:Number = scrollArea.scrollTop;
+
+ var totalHeight:Number = 0;
+ var pm:IListPresentationModel = list.getBeadByType(IListPresentationModel) as IListPresentationModel;
+
+ if(pm.variableRowHeight)
+ {
+ //each item render can have its own height
+ var n:int = _visibleIndexes.length;
+ for (var i:int = 0; i <= index; i++)
+ {
+ var ir:IItemRenderer = (list.view as IListView).dataGroup.getItemRendererForIndex(_visibleIndexes[i]) as IItemRenderer;
+ totalHeight += ir.element.clientHeight;
+ }
+ scrollArea.scrollTop = Math.min(totalHeight + ir.element.clientHeight - scrollArea.clientHeight, totalHeight);
+ } else
+ {
+ var rowHeight:Number;
+ // all items renderers with same height
+ rowHeight = isNaN(pm.rowHeight) ? ListPresentationModel.DEFAULT_ROW_HEIGHT : rowHeight;
+ totalHeight = _visibleIndexes.length * rowHeight - scrollArea.clientHeight;
+
+ scrollArea.scrollTop = Math.min(index * rowHeight, totalHeight);
+ }
+
+ return oldScroll != scrollArea.scrollTop;
+ }
/**
* the filter function to use to filter entries in the list
@@ -138,14 +194,13 @@ package org.apache.royale.jewel.beads.controls.textinput
[Bindable]
public var useDecoration:Boolean = true;
- private var _length:int;
/**
* enables label decoration when filter
*/
[Bindable]
public function get length():int
{
- return _length;
+ return _visibleIndexes.length;
}
/**
@@ -160,11 +215,25 @@ package org.apache.royale.jewel.beads.controls.textinput
override public function set strand(value:IStrand):void
{
_strand = value;
- listenOnStrand(KeyboardEvent.KEY_UP, keyUpHandler);
+ listenOnStrand(KeyboardEvent.KEY_UP, textInputKeyUpHandler);
listenOnStrand('beadsAdded', onBeadsAdded);
}
- protected function keyUpHandler(event:KeyboardEvent):void
+ protected function onBeadsAdded(event:Event):void
+ {
+ var input:TextInputBase = TextInputBase(_strand);
+ COMPILE::JS
+ {
+ input.element.addEventListener('focus', onInputFocus);
+ }
+ }
+
+ protected function onInputFocus(event:Event):void
+ {
+ applyFilter(TextInputBase(_strand).text);
+ }
+
+ protected function textInputKeyUpHandler(event:KeyboardEvent):void
{
if(event.key === KeyboardEvent.KEYCODE__TAB)
return;
@@ -172,15 +241,13 @@ package org.apache.royale.jewel.beads.controls.textinput
const inputBase:TextInputBase = event.target as TextInputBase;
//keyup can include other things like tab navigation
- if (!inputBase) {
- //if (popUpVisible) event.target.parent.view.popUpVisible = false;
+ if (!inputBase)
return;
- }
- keyUpLogic(inputBase);
+ textInputKeyUpLogic(inputBase);
}
- protected function keyUpLogic(input:Object):void
+ protected function textInputKeyUpLogic(input:Object):void
{
// first remove a previous selection
if(list.selectedIndex != -1)
@@ -189,20 +256,6 @@ package org.apache.royale.jewel.beads.controls.textinput
applyFilter(input.text);
}
- protected function onBeadsAdded(event:Event):void
- {
- var input:TextInputBase = TextInputBase(_strand);
- COMPILE::JS
- {
- input.element.addEventListener('focus', onInputFocus);
- }
- }
-
- protected function onInputFocus(event:Event):void
- {
- applyFilter(TextInputBase(_strand).text);
- }
-
/**
* default filter function just filters substrings
* you can use other advanced methods like levenshtein distance
@@ -281,13 +334,11 @@ package org.apache.royale.jewel.beads.controls.textinput
if(!_visibleIndexes)
{
_visibleIndexes = [];
- var view:IListView = list.view as IListView;
- var dataGroup:IItemRendererOwnerView = view.dataGroup;
var len:int = list.numElements;
var ir:ListItemRenderer;
for(var i:int = 0; i < len; i++)
{
- ir = dataGroup.getItemRendererForIndex(i) as ListItemRenderer;
+ ir = (list.view as IListView).dataGroup.getItemRendererForIndex(i) as ListItemRenderer;
if(ir.visible)
_visibleIndexes.push(ir.index);
}
@@ -295,21 +346,10 @@ package org.apache.royale.jewel.beads.controls.textinput
return _visibleIndexes;
}
+ // order the indexes asc in array
protected function numberSort(a:int, b:int):int
{
return a - b;
}
-
- protected var currentIndex:int = 0;
-
- protected function get prevIndex():int
- {
- return currentIndex > 0 ? _visibleIndexes[--currentIndex] : 0;
- }
-
- protected function get nextIndex():int
- {
- return currentIndex < _visibleIndexes.length - 1 ? _visibleIndexes[++currentIndex] : _visibleIndexes.length - 1;
- }
}
}