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 07c2bea  jewel-combobox: add key handling with arrow keys and enter to 
close popup. This was
07c2bea is described below

commit 07c2beadaed206d56d8221e5cf8184d219afcd7d
Author: Carlos Rovira <carlosrov...@apache.org>
AuthorDate: Wed Apr 22 19:05:28 2020 +0200

    jewel-combobox: add key handling with arrow keys and enter to close popup. 
This was
---
 .../jewel/beads/controllers/ComboBoxController.as  | 107 ++++++++++++++++-----
 .../royale/jewel/beads/views/ComboBoxView.as       |   6 +-
 .../apache/royale/jewel/beads/views/ListView.as    |   2 +-
 3 files changed, 89 insertions(+), 26 deletions(-)

diff --git 
a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
 
b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
index 0a9b95b..919dfd8 100644
--- 
a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
+++ 
b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ComboBoxController.as
@@ -24,10 +24,14 @@ package org.apache.royale.jewel.beads.controllers
     }
        import org.apache.royale.core.IBeadController;
        import org.apache.royale.core.IComboBoxModel;
+       import org.apache.royale.core.IItemRendererOwnerView;
        import org.apache.royale.core.IStrand;
        import org.apache.royale.events.Event;
        import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.events.KeyboardEvent;
        import org.apache.royale.events.MouseEvent;
+       import org.apache.royale.html.beads.IListView;
+       import org.apache.royale.html.supportClasses.StyledDataItemRenderer;
        import org.apache.royale.jewel.List;
        import org.apache.royale.jewel.beads.controls.combobox.IComboBoxView;
        import org.apache.royale.jewel.beads.models.IJewelSelectionModel;
@@ -63,7 +67,6 @@ package org.apache.royale.jewel.beads.controllers
                private var model:IComboBoxModel;
 
                private var _strand:IStrand;
-
                /**
                 *  @copy org.apache.royale.core.IBead#strand
                 *
@@ -100,11 +103,11 @@ package org.apache.royale.jewel.beads.controllers
                {
                        
IEventDispatcher(viewBead.button).addEventListener(MouseEvent.CLICK, 
clickHandler);
             
IEventDispatcher(viewBead.textinput).addEventListener(MouseEvent.CLICK, 
clickHandler);
+                       
IEventDispatcher(viewBead.textinput).addEventListener(KeyboardEvent.KEY_DOWN, 
textInputKeyEventHandler);
             COMPILE::JS{
-                               //keyboard navigation from textfield should 
also close the popup
-                viewBead.textinput.element.addEventListener('blur', 
handleFocusOut);
+                       //keyboard navigation from textfield should also close 
the popup
+                       viewBead.textinput.element.addEventListener('blur', 
handleFocusOut);
                        }
-
                }
 
                /**
@@ -118,19 +121,18 @@ package org.apache.royale.jewel.beads.controllers
                        viewBead.popUpVisible = true;
 
                        COMPILE::JS {
-                               //put focus in the textinput
-                if (event.target == viewBead.button) {
-                    viewBead.textinput.element.focus();
-                }
+                       //put focus in the textinput
+                       if (event.target == viewBead.button)
+                               viewBead.textinput.element.focus();
                        }
 
-
                        // viewBead.popup is ComboBoxPopUp that fills 100% of 
browser window-> We want List inside its view
                        popup = viewBead.popup as ComboBoxPopUp;
                        popup.addEventListener(MouseEvent.MOUSE_DOWN, 
removePopUpWhenClickOutside);
 
                        list = (popup.view as ComboBoxPopUpView).list;
                        list.addEventListener(MouseEvent.MOUSE_DOWN, 
handleControlMouseDown);
+                       list.addEventListener(KeyboardEvent.KEY_DOWN, 
listKeyEventHandler);
                        list.addEventListener(Event.CHANGE, changeHandler);
             if (model is IJewelSelectionModel) {
                                //don't let the pop-up's list take over as 
primary dispatcher
@@ -139,6 +141,60 @@ package org.apache.royale.jewel.beads.controllers
             }
                }
 
+               /**
+                * key listener at TextInput level
+                * @private
+                */
+               protected function 
textInputKeyEventHandler(event:KeyboardEvent):void
+               {
+                       COMPILE::JS
+                       {
+                       if (document.activeElement !== 
viewBead.textinput.element)
+                               return; 
+                       }
+                       
+                       // from this point we don't want to perform this 
actions if textinput is not active
+
+                       if(event.key === KeyboardEvent.KEYCODE__DOWN)
+                       {
+                               keyPressed = true
+                               var view:IListView = list.view as IListView;
+                               var dataGroup:IItemRendererOwnerView = 
view.dataGroup;
+                               var goToIndex:int = list.selectedIndex == -1 ? 
0 : list.selectedIndex; 
+                               list.scrollToIndex(goToIndex);
+                               var ir:StyledDataItemRenderer = 
dataGroup.getItemRendererForIndex(goToIndex) as StyledDataItemRenderer;
+                               COMPILE::JS
+                               {
+                               // this 'hack' is needed due to browsers 
scrolling list on popups when get focus
+                               if(list.element.classList.contains("scroll"));
+                               {
+                                       list.element.classList.remove("scroll");
+                                       setTimeout(restoreScroll, 300);
+                               }
+                               list.element.focus({preventScroll:true});
+                               list.selectedIndex = goToIndex;
+                               }
+                       }
+               }
+
+               /**
+                * key listener at global List level
+                * @private
+                */
+               protected function listKeyEventHandler(event:KeyboardEvent):void
+               {
+                       if(event.key === KeyboardEvent.KEYCODE__ENTER)
+                       {
+                               dismissPopUp();
+                       }
+               }
+
+               COMPILE::JS
+               private function restoreScroll():void
+               {
+                       list.element.classList.add("scroll");
+               }
+
                private var popup:ComboBoxPopUp;
 
                protected function handleControlMouseDown(event:MouseEvent):void
@@ -146,7 +202,6 @@ package org.apache.royale.jewel.beads.controllers
                        event.stopImmediatePropagation();
                }
 
-
         /**
          * @private
          */
@@ -162,7 +217,9 @@ package org.apache.royale.jewel.beads.controllers
         }
 
         protected function hidePopup():void{
-            viewBead.popUpVisible = false;
+                       if(!keyPressed)
+               viewBead.popUpVisible = false;
+                       keyPressed = false;
         }
                /**
          *  @royaleignorecoercion org.apache.royale.core.UIBase
@@ -170,10 +227,7 @@ package org.apache.royale.jewel.beads.controllers
                 */
                protected function removePopUpWhenClickOutside(event:MouseEvent 
= null):void
                {
-                       popup.removeEventListener(MouseEvent.MOUSE_DOWN, 
removePopUpWhenClickOutside);
-                       list.removeEventListener(MouseEvent.MOUSE_DOWN, 
handleControlMouseDown);
-                       list.removeEventListener(Event.CHANGE, changeHandler);
-                       viewBead.popUpVisible = false;
+                       dismissPopUp();
                }
 
                /**
@@ -183,19 +237,28 @@ package org.apache.royale.jewel.beads.controllers
                private function changeHandler(event:Event):void
                {
                        event.stopImmediatePropagation();
-
-                       popup.removeEventListener(MouseEvent.MOUSE_DOWN, 
removePopUpWhenClickOutside);
-                       list.removeEventListener(MouseEvent.MOUSE_DOWN, 
handleControlMouseDown);
-                       list.removeEventListener(Event.CHANGE, changeHandler);
-
                        model.selectedItem = 
IComboBoxModel(list.getBeadByType(IComboBoxModel)).selectedItem;
-                       viewBead.popUpVisible = false;
-
                        IEventDispatcher(_strand).dispatchEvent(new 
Event(Event.CHANGE));
+                       dismissPopUp();
                }
 
         protected function modelChangeHandler(event:Event):void{
             IEventDispatcher(_strand).dispatchEvent(new Event(event.type));
         }
+
+               private var keyPressed:Boolean;
+
+               private function dismissPopUp():void
+               {
+                       if(!keyPressed)
+                       {
+                               
popup.removeEventListener(MouseEvent.MOUSE_DOWN, removePopUpWhenClickOutside);
+                               list.removeEventListener(MouseEvent.MOUSE_DOWN, 
handleControlMouseDown);
+                               list.removeEventListener(Event.CHANGE, 
changeHandler);
+                               
list.removeEventListener(KeyboardEvent.KEY_DOWN, listKeyEventHandler);
+                               viewBead.popUpVisible = false;
+                       }
+                       keyPressed = false;
+               }
        }
 }
diff --git 
a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
 
b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
index 93861cc..546eeab 100644
--- 
a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
+++ 
b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ComboBoxView.as
@@ -129,9 +129,8 @@ package org.apache.royale.jewel.beads.views
             }*/
 
                        _button = new Button();
-                       COMPILE::JS {
-                _button.element.setAttribute('tabindex', -1);
-                       }
+               _button.tabIndex = -1;
+                       
                        _button.text = '\u25BC';
 
                        initSize();
@@ -200,6 +199,7 @@ package org.apache.royale.jewel.beads.views
                                        
                                        //popup width needs to be set before 
position inside bounding client to work ok
                                        _list.width = host.width;
+                                       
_list.scrollToIndex(_list.selectedIndex);
                     
                     COMPILE::JS
                     {
diff --git 
a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
 
b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
index 0703f84..21e34b3 100644
--- 
a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
+++ 
b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/views/ListView.as
@@ -32,6 +32,7 @@ package org.apache.royale.jewel.beads.views
        import org.apache.royale.core.IRollOverModel;
        import org.apache.royale.core.ISelectableItemRenderer;
        import org.apache.royale.core.ISelectionModel;
+       import org.apache.royale.core.StyledUIBase;
        import org.apache.royale.events.Event;
        import org.apache.royale.events.IEventDispatcher;
        import org.apache.royale.events.KeyboardEvent;
@@ -39,7 +40,6 @@ package org.apache.royale.jewel.beads.views
        import org.apache.royale.jewel.beads.models.ListPresentationModel;
        import 
org.apache.royale.jewel.supportClasses.list.IListPresentationModel;
        import org.apache.royale.utils.getSelectionRenderBead;
-       import org.apache.royale.core.StyledUIBase;
 
        /**
         *  The ListView class creates the visual elements of the 
org.apache.royale.jewel.List

Reply via email to