You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@royale.apache.org by Alex Harui <ah...@adobe.com.INVALID> on 2020/01/28 05:20:55 UTC

Re: [royale-asjs] branch develop updated: Only contorllers truly intersted in multiselection will dipatch a multiselection event.

Just noticed this while looking into the has/is refactor.

Was this ClassFactory created to fix a bug?  I didn't think the renderers would have loaded their IBeadController during the create() call.  Should happen when they are placed on the display list unless placed on the strand as an override (in which case, it should be respected as intentional?)

IMO, MutipleSelectionLists might benefit from their own renderers (subclasses of StringItemRenderer or whatever) that would specify a different set of beads (not just mouse controlers, but someday keyboard controllers).  And possibly additional information for the renderers about the selection.  Renderer visuals for multiple selection might need to be more complex than for single selection (anchors, carets, etc).

Mostly wondering,
-Alex

On 11/24/19, 4:26 AM, "yishayw@apache.org" <yi...@apache.org> wrote:

    This is an automated email from the ASF dual-hosted git repository.
    
    yishayw pushed a commit to branch develop
    in repository https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&amp;data=02%7C01%7Caharui%40adobe.com%7C1062582d7b7f4000bf7d08d770d97f6d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637101951823273040&amp;sdata=8vA%2ByeX3qJz8ZyAsTGZeSZpxQzSgdHUAulThoBui4xo%3D&amp;reserved=0
    
    
    The following commit(s) were added to refs/heads/develop by this push:
         new 95cc8f9  Only contorllers truly intersted in multiselection will dipatch a multiselection event.
         new dd5ca83  Merge branch 'develop' of https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-asjs&amp;data=02%7C01%7Caharui%40adobe.com%7C1062582d7b7f4000bf7d08d770d97f6d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637101951823273040&amp;sdata=lgKjvVJQ%2FS6f5%2FDWwjhNBveNNoU7zhs2dVREQzCqN1c%3D&amp;reserved=0 into develop
    95cc8f9 is described below
    
    commit 95cc8f9dc87503c91f0d345036796d93b15cb1e4
    Author: DESKTOP-RH4S838\Yishay <yi...@hotmail.com>
    AuthorDate: Sun Nov 24 14:23:33 2019 +0200
    
        Only contorllers truly intersted in multiselection will dipatch a multiselection event.
        
        Also, make sure to use metevent for apple devices as ctrlKey is not usually associated with multiselection there.
    ---
     .../projects/Basic/src/main/resources/defaults.css |   2 +-
     .../projects/Basic/src/main/royale/BasicClasses.as |   1 +
     .../MultiSelectionItemRendererClassFactory.as      |  65 +++++++++++++
     .../AccordionItemRendererMouseController.as        |   2 -
     .../controllers/ItemRendererMouseController.as     |  10 --
     .../ListMultiSelectionMouseController.as           |   4 +-
     ...> MultiSelectionItemRendererMouseController.as} | 106 ++++++++++-----------
     .../supportClasses/ButtonBarButtonItemRenderer.as  |   2 -
     .../html/supportClasses/TextButtonItemRenderer.as  |   2 -
     .../projects/Core/src/main/royale/CoreClasses.as   |   1 +
     .../org/apache/royale/events/ItemClickedEvent.as   |  18 +---
     ...dEvent.as => MultiSelectionItemClickedEvent.as} |  67 ++++++-------
     .../controllers/ItemRendererMouseController.as     |   4 -
     13 files changed, 156 insertions(+), 128 deletions(-)
    
    diff --git a/frameworks/projects/Basic/src/main/resources/defaults.css b/frameworks/projects/Basic/src/main/resources/defaults.css
    index 8069565..64d320c 100644
    --- a/frameworks/projects/Basic/src/main/resources/defaults.css
    +++ b/frameworks/projects/Basic/src/main/resources/defaults.css
    @@ -396,7 +396,7 @@ MultiSelectionList
     	IBeadController: ClassReference("org.apache.royale.html.beads.controllers.ListMultiSelectionMouseController");
     	IBeadLayout: ClassReference("org.apache.royale.html.beads.layouts.VerticalLayout");
     	IDataProviderItemRendererMapper: ClassReference("org.apache.royale.html.beads.DataItemRendererFactoryForArrayData");
    -	IItemRendererClassFactory: ClassReference("org.apache.royale.core.ItemRendererClassFactory");
    +	IItemRendererClassFactory: ClassReference("org.apache.royale.html.beads.MultiSelectionItemRendererClassFactory");
     	IItemRenderer: ClassReference("org.apache.royale.html.supportClasses.StringItemRenderer");
     	IViewport: ClassReference("org.apache.royale.html.supportClasses.ScrollingViewport");
     	IViewportModel: ClassReference("org.apache.royale.html.beads.models.ViewportModel");
    diff --git a/frameworks/projects/Basic/src/main/royale/BasicClasses.as b/frameworks/projects/Basic/src/main/royale/BasicClasses.as
    index 4822106..742eef8 100644
    --- a/frameworks/projects/Basic/src/main/royale/BasicClasses.as
    +++ b/frameworks/projects/Basic/src/main/royale/BasicClasses.as
    @@ -191,6 +191,7 @@ internal class BasicClasses
         import org.apache.royale.html.beads.controllers.ItemRendererMouseController; ItemRendererMouseController;
         import org.apache.royale.html.beads.controllers.ListSingleSelectionMouseController; ListSingleSelectionMouseController;
         import org.apache.royale.html.beads.controllers.ListMultiSelectionMouseController; ListMultiSelectionMouseController;
    +    import org.apache.royale.html.beads.MultiSelectionItemRendererClassFactory; MultiSelectionItemRendererClassFactory;
     	import org.apache.royale.html.beads.controllers.TreeSingleSelectionMouseController; TreeSingleSelectionMouseController;
     	import org.apache.royale.html.beads.controllers.MenuSelectionMouseController; MenuSelectionMouseController;
         import org.apache.royale.html.beads.controllers.HSliderMouseController; HSliderMouseController;
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/MultiSelectionItemRendererClassFactory.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/MultiSelectionItemRendererClassFactory.as
    new file mode 100644
    index 0000000..25c6c0f
    --- /dev/null
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/MultiSelectionItemRendererClassFactory.as
    @@ -0,0 +1,65 @@
    +////////////////////////////////////////////////////////////////////////////////
    +//
    +//  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
    +//
    +//      https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&amp;data=02%7C01%7Caharui%40adobe.com%7C1062582d7b7f4000bf7d08d770d97f6d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637101951823273040&amp;sdata=%2BHN5r%2BhS%2BJXItT7fzoawMFzftwzgo2UQ68xBJFu3wVo%3D&amp;reserved=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
    +{
    +	/**
    +	 *  The MultiSelectionItemRendererClassFactory class extends ItemRendererClassFactory to add a multiselection controller to item renderers
    +	 * 
    +	 *  @langversion 3.0
    +	 *  @playerversion Flash 10.2
    +	 *  @playerversion AIR 2.6
    +	 *  @productversion Royale 0.9.7
    +	 */
    +	import org.apache.royale.core.IBeadController;
    +	import org.apache.royale.core.IItemRendererParent;
    +	import org.apache.royale.core.IBead;
    +	import org.apache.royale.core.ItemRendererClassFactory;
    +	import org.apache.royale.core.IItemRenderer;
    +	import org.apache.royale.core.IStrand;
    +	import org.apache.royale.html.beads.controllers.MultiSelectionItemRendererMouseController;
    +
    +	public class MultiSelectionItemRendererClassFactory extends ItemRendererClassFactory
    +	{
    +		/**
    +		 *  Constructor.
    +		 *  
    +		 *  @langversion 3.0
    +		 *  @playerversion Flash 10.2
    +		 *  @playerversion AIR 2.6
    +		 *  @productversion Royale 0.9.7
    +		 */
    +		public function MultiSelectionItemRendererClassFactory()
    +		{
    +			super();
    +		}
    +
    +		override public function createFromClass(parent:IItemRendererParent):IItemRenderer
    +		{
    +			var renderer:IItemRenderer = super.createFromClass(parent);
    +			var strand:IStrand = renderer as IStrand;
    +			var bead:IBead = strand.getBeadByType(IBeadController);
    +			if (bead)
    +			{
    +				strand.removeBead(bead);
    +			}
    +			strand.addBead(new MultiSelectionItemRendererMouseController());
    +			return renderer;
    +		}
    +	}
    +}
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as
    index e97eb1a..eea497f 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as
    @@ -62,8 +62,6 @@ package org.apache.royale.html.beads.controllers
     		{
     			var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
     			newEvent.data = accordionItemRenderer.data;
    -			newEvent.shiftKey = event.shiftKey;
    -			newEvent.ctrlKey = event.ctrlKey;
     			newEvent.index = accordionItemRenderer.index;
     			
     			accordionItemRenderer.dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    index 2d458e8..1da2806 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    @@ -160,8 +160,6 @@ COMPILE::JS {
                     
                     var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
                     newEvent.data = target.data;
    -                newEvent.shiftKey = event.shiftKey;
    -                newEvent.ctrlKey = event.ctrlKey;
                     newEvent.index = target.index;
                     
                     target.dispatchEvent(newEvent);
    @@ -184,8 +182,6 @@ COMPILE::JS {
     
     				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
    @@ -204,8 +200,6 @@ COMPILE::JS {
     			{				
     				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     				
                     target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);                
    @@ -225,8 +219,6 @@ COMPILE::JS {
     			{
     				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
    @@ -245,8 +237,6 @@ COMPILE::JS {
     			{
     				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseUp");
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as
    index d0a6cf2..4ccfcc3 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as
    @@ -31,7 +31,7 @@ package org.apache.royale.html.beads.controllers
     	import org.apache.royale.events.MouseEvent;
     	import org.apache.royale.html.beads.IListView;
     
    -	import org.apache.royale.events.ItemClickedEvent;
    +	import org.apache.royale.events.MultiSelectionItemClickedEvent;
     
     	/**
     	 *  The ListMultiSelectionMouseController class is a controller for
    @@ -133,7 +133,7 @@ package org.apache.royale.html.beads.controllers
     			IEventDispatcher(event.item).removeEventListener("itemRollOut", rolloutHandler);
     		}
     
    -		protected function selectedHandler(event:ItemClickedEvent):void
    +		protected function selectedHandler(event:MultiSelectionItemClickedEvent):void
     		{
     			var selectedIndices:Array = [];
     			var newIndices:Array;
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MultiSelectionItemRendererMouseController.as
    similarity index 75%
    copy from frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    copy to frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MultiSelectionItemRendererMouseController.as
    index 2d458e8..ec095ee 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MultiSelectionItemRendererMouseController.as
    @@ -21,22 +21,22 @@ package org.apache.royale.html.beads.controllers
     	import org.apache.royale.core.IBeadController;
     	import org.apache.royale.core.ISelectableItemRenderer;
     	import org.apache.royale.core.IStrand;
    -COMPILE::SWF {
    -	import org.apache.royale.events.Event;
    -	import org.apache.royale.events.MouseEvent;
    -}
    -COMPILE::JS {
    -	import org.apache.royale.core.UIBase;
    -	import org.apache.royale.core.WrappedHTMLElement;
    -	import org.apache.royale.events.BrowserEvent;
    -	import goog.events.Event;
    -	import goog.events.EventType;
    -    import goog.events;
    -}
    -	import org.apache.royale.events.ItemClickedEvent;
    +	COMPILE::SWF {
    +		import org.apache.royale.events.Event;
    +		import org.apache.royale.events.MouseEvent;
    +	}
    +	COMPILE::JS {
    +		import org.apache.royale.core.UIBase;
    +		import org.apache.royale.core.WrappedHTMLElement;
    +		import org.apache.royale.events.BrowserEvent;
    +		import goog.events.Event;
    +		import goog.events.EventType;
    +		import goog.events;
    +	}
    +	import org.apache.royale.events.MultiSelectionItemClickedEvent;
     
     	/**
    -	 *  The ItemRendererMouseController class can mouse events in itemRenderers. This
    +	 *  The MultiSelectionItemRendererMouseController class can mouse events in itemRenderers. This
     	 *  includes roll-overs, mouse down, and mouse up. These platform-specific events are then
     	 *  re-dispatched as Royale events.
     	 *  
    @@ -46,7 +46,8 @@ COMPILE::JS {
     	 *  @productversion Royale 0.9
     	 *  @royaleignoreimport goog.events.Event
     	 */
    -	public class ItemRendererMouseController implements IBeadController
    +
    +	public class MultiSelectionItemRendererMouseController implements IBeadController
     	{
     		/**
     		 *  constructor.
    @@ -56,13 +57,13 @@ COMPILE::JS {
     		 *  @playerversion AIR 2.6
     		 *  @productversion Royale 0.9
     		 */
    -		public function ItemRendererMouseController()
    +		public function MultiSelectionItemRendererMouseController()
     		{
     		}
    -		
    -        private var renderer:ISelectableItemRenderer;
    +
    +		private var renderer:ISelectableItemRenderer;
     		private var _strand:IStrand;
    -		
    +
     		/**
     		 *  @copy org.apache.royale.core.IBead#strand
     		 *  
    @@ -76,26 +77,26 @@ COMPILE::JS {
     		public function set strand(value:IStrand):void
     		{
     			_strand = value;
    -            renderer = value as ISelectableItemRenderer;
    -			
    +			renderer = value as ISelectableItemRenderer;
    +
     			COMPILE::SWF {
    -	            renderer.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
    -	            renderer.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
    +				renderer.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
    +				renderer.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
     				renderer.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
     				renderer.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
     			}
    -				
    +
     			COMPILE::JS {
     				var element:WrappedHTMLElement = (_strand as UIBase).element;
    -				
    +
     				goog.events.listen(element, goog.events.EventType.MOUSEOVER, this.handleMouseOver);
     				goog.events.listen(element, goog.events.EventType.MOUSEOUT, this.handleMouseOut);
     				goog.events.listen(element, goog.events.EventType.MOUSEDOWN, this.handleMouseDown);
     				goog.events.listen(element, goog.events.EventType.CLICK, this.handleMouseClick);
    -                goog.events.listen(element, goog.events.EventType.MOUSEUP, this.handleMouseUp);
    +				goog.events.listen(element, goog.events.EventType.MOUSEUP, this.handleMouseUp);
     			}
     		}
    -		
    +
     		/**
     		 * @private
     		 */
    @@ -108,7 +109,7 @@ COMPILE::JS {
     				target.dispatchEvent(new Event("itemRollOver",true));
     			}
     		}
    -		
    +
     		/**
     		 * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
     		 */
    @@ -120,7 +121,7 @@ COMPILE::JS {
     				target.dispatchEvent(new Event("itemRollOver",true));
     			}
     		}
    -		
    +
     		/**
     		 * @private
     		 */
    @@ -133,7 +134,7 @@ COMPILE::JS {
     				target.dispatchEvent(new Event("itemRollOut",true));
     			}
     		}
    -		
    +
     		/**
     		 * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
     		 */
    @@ -156,19 +157,19 @@ COMPILE::JS {
     			var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
     			if (target)
     			{
    -                target.down = true;
    -                
    -                var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
    -                newEvent.data = target.data;
    -                newEvent.shiftKey = event.shiftKey;
    -                newEvent.ctrlKey = event.ctrlKey;
    -                newEvent.index = target.index;
    -                
    -                target.dispatchEvent(newEvent);
    +				target.down = true;
    +
    +				var newEvent:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent("itemMouseDown", true, true);
    +				newEvent.shiftKey = event.shiftKey;
    +				newEvent.ctrlKey = event.ctrlKey;
    +				newEvent.data = target.data;
    +				newEvent.index = target.index;
    +
    +				target.dispatchEvent(newEvent);
     				target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
     			}
     		}
    -		
    +
     		/**
     		 * @private
     		 * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
    @@ -182,16 +183,14 @@ COMPILE::JS {
     				target.down = true;
     				target.hovered = false;
     
    -				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
    +				var newEvent:MultiSelectionItemClickedEvent = MultiSelectionItemClickedEvent.createMultiSelectionItemClickedEvent("itemMouseDown", event);
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
     			}
     		}
    -		
    +
     		/**
     		 * @private
     		 */
    @@ -202,17 +201,16 @@ COMPILE::JS {
     			var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
     			if (target)
     			{				
    -				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    -				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    +				var newEvent:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent("itemClicked", true, true);
     				newEvent.ctrlKey = event.ctrlKey;
    +				newEvent.shiftKey = event.shiftKey;
    +				newEvent.data = target.data;
     				newEvent.index = target.index;
    -				
    -                target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);                
    +				target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
     				target.dispatchEvent(newEvent);
     			}			
     		}
    -		
    +
     		/**
     		 * @private
     		 * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
    @@ -223,10 +221,8 @@ COMPILE::JS {
     			var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
     			if (target)
     			{
    -				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    +				var newEvent:MultiSelectionItemClickedEvent = MultiSelectionItemClickedEvent.createMultiSelectionItemClickedEvent("itemClicked", event);
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
    @@ -243,10 +239,8 @@ COMPILE::JS {
     			var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
     			if (target)
     			{
    -				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseUp");
    +				var newEvent:MultiSelectionItemClickedEvent = MultiSelectionItemClickedEvent.createMultiSelectionItemClickedEvent("itemMouseUp", event);
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as
    index f182c48..5366419 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as
    @@ -69,8 +69,6 @@ package org.apache.royale.html.supportClasses
     		protected function handleClickEvent(event:MouseEvent):void
     		{
     			var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    -			newEvent.shiftKey = event.shiftKey;
    -			newEvent.ctrlKey = event.ctrlKey;
     			newEvent.index = index;
     			newEvent.data = data;
     			dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as
    index 4bb2e53..93d84c9 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as
    @@ -99,8 +99,6 @@ package org.apache.royale.html.supportClasses
     		protected function handleClickEvent(event:MouseEvent):void
     		{
     			var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    -			newEvent.shiftKey = event.shiftKey;
    -			newEvent.ctrlKey = event.ctrlKey;
     			newEvent.index = index;
     			newEvent.data = data;
     			dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as b/frameworks/projects/Core/src/main/royale/CoreClasses.as
    index 2c17dc7..6145af7 100644
    --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
    +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
    @@ -43,6 +43,7 @@ internal class CoreClasses
     
     	import org.apache.royale.events.ItemAddedEvent; ItemAddedEvent;
     	import org.apache.royale.events.ItemClickedEvent; ItemClickedEvent;
    +	import org.apache.royale.events.MultiSelectionItemClickedEvent; MultiSelectionItemClickedEvent;
     	import org.apache.royale.events.ItemRemovedEvent; ItemRemovedEvent;
     	import org.apache.royale.events.ItemRendererEvent; ItemRendererEvent;
     
    diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    index c4c239f..7f92ff4 100644
    --- a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    +++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    @@ -51,7 +51,7 @@ package org.apache.royale.events
     		 * @langversion 3.0
     		 * @playerversion Flash 10.2
     		 * @playerversion AIR 2.6
    -		 * @productversion Royale 0.0
    +		 * @productversion Royale 0.9.7
     		 */
     		public function ItemClickedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
     		{
    @@ -66,8 +66,6 @@ package org.apache.royale.events
     
     			index = -1;
     			data = null;
    -			shiftKey = false;
    -			ctrlKey = false;
     		}
     
     		/**
    @@ -102,26 +100,12 @@ package org.apache.royale.events
     		 * @productversion Royale 0.9.7
     		 */
     
    -		public var shiftKey:Boolean;
    -		/**
    -		 * Whether or not this click was done while holding the control key
    -		 *
    -		 * @export
    -		 * @langversion 3.0
    -		 * @playerversion Flash 10.2
    -		 * @playerversion AIR 2.6
    -		 * @productversion Royale 0.9.7
    -		 */
    -		public var ctrlKey:Boolean;
    -
     
     		override public function cloneEvent():IRoyaleEvent
     		{
     			var newEvent:ItemClickedEvent = new ItemClickedEvent(type);
     			newEvent.index = index;
     			newEvent.data = data;
    -			newEvent.shiftKey = shiftKey;
    -			newEvent.ctrlKey = ctrlKey;
     			return newEvent;
     		}
     	}
    diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/MultiSelectionItemClickedEvent.as
    similarity index 62%
    copy from frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    copy to frameworks/projects/Core/src/main/royale/org/apache/royale/events/MultiSelectionItemClickedEvent.as
    index c4c239f..d1c73bb 100644
    --- a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    +++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/MultiSelectionItemClickedEvent.as
    @@ -20,10 +20,14 @@
     package org.apache.royale.events
     {
     
    -	import org.apache.royale.events.CustomEvent;
    +	import org.apache.royale.utils.OSUtils;
    +	COMPILE::JS
    +	{
    +		import org.apache.royale.events.BrowserEvent;
    +	}
     
     	/**
    -	 * The ItemClickedEvent is a custom event issued by an itemRenderer to
    +	 * The MultiSelectionItemClickedEvent is a custom event issued by a multi selection itemRenderer to
     	 * convey information about itself when it has determined that the
     	 * event(s) happening to it constitute a 'click' on itself.
     	 *
    @@ -34,7 +38,7 @@ package org.apache.royale.events
     	 * 
     	 *  @royalesuppresspublicvarwarning
     	 */
    -	public class ItemClickedEvent extends CustomEvent
    +	public class MultiSelectionItemClickedEvent extends ItemClickedEvent
     	{
     
     		//--------------------------------------
    @@ -51,9 +55,9 @@ package org.apache.royale.events
     		 * @langversion 3.0
     		 * @playerversion Flash 10.2
     		 * @playerversion AIR 2.6
    -		 * @productversion Royale 0.0
    +		 * @productversion Royale 0.9.7
     		 */
    -		public function ItemClickedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
    +		public function MultiSelectionItemClickedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
     		{
     			COMPILE::SWF
     			{
    @@ -63,34 +67,8 @@ package org.apache.royale.events
     			{
     				super(type);
     			}
    -
    -			index = -1;
    -			data = null;
    -			shiftKey = false;
    -			ctrlKey = false;
     		}
     
    -		/**
    -		 * The index of the item beginning with zero.
    -		 *
    -		 * @export
    -		 * @langversion 3.0
    -		 * @playerversion Flash 10.2
    -		 * @playerversion AIR 2.6
    -		 * @productversion Royale 0.0
    -		 */
    -		public var index:Number;
    -
    -		/**
    -		 * The data of the item.
    -		 *
    -		 * @export
    -		 * @langversion 3.0
    -		 * @playerversion Flash 10.2
    -		 * @playerversion AIR 2.6
    -		 * @productversion Royale 0.0
    -		 */
    -		public var data:Object;
     
     		/**
     		 * Whether or not this click was done while holding the shift key
    @@ -117,12 +95,37 @@ package org.apache.royale.events
     
     		override public function cloneEvent():IRoyaleEvent
     		{
    -			var newEvent:ItemClickedEvent = new ItemClickedEvent(type);
    +			var newEvent:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent(type);
     			newEvent.index = index;
     			newEvent.data = data;
     			newEvent.shiftKey = shiftKey;
     			newEvent.ctrlKey = ctrlKey;
     			return newEvent;
     		}
    +
    +		/**
    +		 *  Factory for MultiSelectionItemClickedEvents.
    +		 *  
    +		 *  @param type The name of the event.
    +		 *  @param event The MouseEvent properties to copy into the MultiSelectionItemClickedEvent.
    +		 *  @return The new MultiSelectionItemClickedEvent.
    +		 * 
    +		 *  @langversion 3.0
    +		 *  @playerversion Flash 10.2
    +		 *  @playerversion AIR 2.6
    +		 *  @productversion Royale 0.9.7
    +		 *  @royaleignorecoercion org.apache.royale.events.MultiSelectionItemClickedEvent
    +		 *  @royaleignorecoercion window.Event
    +		 *  @royaleignorecoercion Event
    +		 */
    +		COMPILE::JS
    +		public static function createMultiSelectionItemClickedEvent(type:String, event:BrowserEvent):MultiSelectionItemClickedEvent
    +		{
    +			var msice:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent(type, true, true);
    +			var ctrlKey:Boolean = OSUtils.getOS() == OSUtils.MAC_OS || OSUtils.getOS() == OSUtils.IOS_OS ? event.nativeEvent["metaKey"] : event.ctrlKey;
    +			msice.ctrlKey = ctrlKey;
    +			msice.shiftKey = event.shiftKey;
    +			return msice;
    +		}
     	}
     }
    diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as
    index 4435999..5f1acee 100644
    --- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as
    +++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as
    @@ -189,8 +189,6 @@ package org.apache.royale.jewel.beads.controllers
     			{				
     				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     				
                     target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);                
    @@ -211,8 +209,6 @@ package org.apache.royale.jewel.beads.controllers
     			{
     				var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
     				newEvent.data = target.data;
    -				newEvent.shiftKey = event.shiftKey;
    -				newEvent.ctrlKey = event.ctrlKey;
     				newEvent.index = target.index;
     
     				target.dispatchEvent(newEvent);
    
    


RE: [royale-asjs] branch develop updated: Only contorllers truly intersted in multiselection will dipatch a multiselection event.

Posted by Yishay Weiss <yi...@hotmail.com>.
If guess I figured most of the beads (and item renderers) were fine for my use-case so I might as well just use them as they are. We were not in immediate needs of anchors, for example. I realize directly instantiating a bead breaks IoC so I might have been following an example, but I don’t see such an example in the sources. Feel free to refactor this.

From: Alex Harui<ma...@adobe.com.INVALID>
Sent: Tuesday, January 28, 2020 7:21 AM
To: dev@royale.apache.org<ma...@royale.apache.org>; commits@royale.apache.org<ma...@royale.apache.org>
Subject: Re: [royale-asjs] branch develop updated: Only contorllers truly intersted in multiselection will dipatch a multiselection event.

Just noticed this while looking into the has/is refactor.

Was this ClassFactory created to fix a bug?  I didn't think the renderers would have loaded their IBeadController during the create() call.  Should happen when they are placed on the display list unless placed on the strand as an override (in which case, it should be respected as intentional?)

IMO, MutipleSelectionLists might benefit from their own renderers (subclasses of StringItemRenderer or whatever) that would specify a different set of beads (not just mouse controlers, but someday keyboard controllers).  And possibly additional information for the renderers about the selection.  Renderer visuals for multiple selection might need to be more complex than for single selection (anchors, carets, etc).

Mostly wondering,
-Alex

On 11/24/19, 4:26 AM, "yishayw@apache.org" <yi...@apache.org> wrote:

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

    yishayw pushed a commit to branch develop
    in repository https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&amp;data=02%7C01%7Caharui%40adobe.com%7C1062582d7b7f4000bf7d08d770d97f6d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637101951823273040&amp;sdata=8vA%2ByeX3qJz8ZyAsTGZeSZpxQzSgdHUAulThoBui4xo%3D&amp;reserved=0


    The following commit(s) were added to refs/heads/develop by this push:
         new 95cc8f9  Only contorllers truly intersted in multiselection will dipatch a multiselection event.
         new dd5ca83  Merge branch 'develop' of https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-asjs&amp;data=02%7C01%7Caharui%40adobe.com%7C1062582d7b7f4000bf7d08d770d97f6d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637101951823273040&amp;sdata=lgKjvVJQ%2FS6f5%2FDWwjhNBveNNoU7zhs2dVREQzCqN1c%3D&amp;reserved=0 into develop
    95cc8f9 is described below

    commit 95cc8f9dc87503c91f0d345036796d93b15cb1e4
    Author: DESKTOP-RH4S838\Yishay <yi...@hotmail.com>
    AuthorDate: Sun Nov 24 14:23:33 2019 +0200

        Only contorllers truly intersted in multiselection will dipatch a multiselection event.

        Also, make sure to use metevent for apple devices as ctrlKey is not usually associated with multiselection there.
    ---
     .../projects/Basic/src/main/resources/defaults.css |   2 +-
     .../projects/Basic/src/main/royale/BasicClasses.as |   1 +
     .../MultiSelectionItemRendererClassFactory.as      |  65 +++++++++++++
     .../AccordionItemRendererMouseController.as        |   2 -
     .../controllers/ItemRendererMouseController.as     |  10 --
     .../ListMultiSelectionMouseController.as           |   4 +-
     ...> MultiSelectionItemRendererMouseController.as} | 106 ++++++++++-----------
     .../supportClasses/ButtonBarButtonItemRenderer.as  |   2 -
     .../html/supportClasses/TextButtonItemRenderer.as  |   2 -
     .../projects/Core/src/main/royale/CoreClasses.as   |   1 +
     .../org/apache/royale/events/ItemClickedEvent.as   |  18 +---
     ...dEvent.as => MultiSelectionItemClickedEvent.as} |  67 ++++++-------
     .../controllers/ItemRendererMouseController.as     |   4 -
     13 files changed, 156 insertions(+), 128 deletions(-)

    diff --git a/frameworks/projects/Basic/src/main/resources/defaults.css b/frameworks/projects/Basic/src/main/resources/defaults.css
    index 8069565..64d320c 100644
    --- a/frameworks/projects/Basic/src/main/resources/defaults.css
    +++ b/frameworks/projects/Basic/src/main/resources/defaults.css
    @@ -396,7 +396,7 @@ MultiSelectionList
         IBeadController: ClassReference("org.apache.royale.html.beads.controllers.ListMultiSelectionMouseController");
         IBeadLayout: ClassReference("org.apache.royale.html.beads.layouts.VerticalLayout");
         IDataProviderItemRendererMapper: ClassReference("org.apache.royale.html.beads.DataItemRendererFactoryForArrayData");
    -   IItemRendererClassFactory: ClassReference("org.apache.royale.core.ItemRendererClassFactory");
    +   IItemRendererClassFactory: ClassReference("org.apache.royale.html.beads.MultiSelectionItemRendererClassFactory");
         IItemRenderer: ClassReference("org.apache.royale.html.supportClasses.StringItemRenderer");
         IViewport: ClassReference("org.apache.royale.html.supportClasses.ScrollingViewport");
         IViewportModel: ClassReference("org.apache.royale.html.beads.models.ViewportModel");
    diff --git a/frameworks/projects/Basic/src/main/royale/BasicClasses.as b/frameworks/projects/Basic/src/main/royale/BasicClasses.as
    index 4822106..742eef8 100644
    --- a/frameworks/projects/Basic/src/main/royale/BasicClasses.as
    +++ b/frameworks/projects/Basic/src/main/royale/BasicClasses.as
    @@ -191,6 +191,7 @@ internal class BasicClasses
         import org.apache.royale.html.beads.controllers.ItemRendererMouseController; ItemRendererMouseController;
         import org.apache.royale.html.beads.controllers.ListSingleSelectionMouseController; ListSingleSelectionMouseController;
         import org.apache.royale.html.beads.controllers.ListMultiSelectionMouseController; ListMultiSelectionMouseController;
    +    import org.apache.royale.html.beads.MultiSelectionItemRendererClassFactory; MultiSelectionItemRendererClassFactory;
         import org.apache.royale.html.beads.controllers.TreeSingleSelectionMouseController; TreeSingleSelectionMouseController;
         import org.apache.royale.html.beads.controllers.MenuSelectionMouseController; MenuSelectionMouseController;
         import org.apache.royale.html.beads.controllers.HSliderMouseController; HSliderMouseController;
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/MultiSelectionItemRendererClassFactory.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/MultiSelectionItemRendererClassFactory.as
    new file mode 100644
    index 0000000..25c6c0f
    --- /dev/null
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/MultiSelectionItemRendererClassFactory.as
    @@ -0,0 +1,65 @@
    +////////////////////////////////////////////////////////////////////////////////
    +//
    +//  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
    +//
    +//      https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&amp;data=02%7C01%7Caharui%40adobe.com%7C1062582d7b7f4000bf7d08d770d97f6d%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637101951823273040&amp;sdata=%2BHN5r%2BhS%2BJXItT7fzoawMFzftwzgo2UQ68xBJFu3wVo%3D&amp;reserved=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
    +{
    +   /**
    +    *  The MultiSelectionItemRendererClassFactory class extends ItemRendererClassFactory to add a multiselection controller to item renderers
    +    *
    +    *  @langversion 3.0
    +    *  @playerversion Flash 10.2
    +    *  @playerversion AIR 2.6
    +    *  @productversion Royale 0.9.7
    +    */
    +   import org.apache.royale.core.IBeadController;
    +   import org.apache.royale.core.IItemRendererParent;
    +   import org.apache.royale.core.IBead;
    +   import org.apache.royale.core.ItemRendererClassFactory;
    +   import org.apache.royale.core.IItemRenderer;
    +   import org.apache.royale.core.IStrand;
    +   import org.apache.royale.html.beads.controllers.MultiSelectionItemRendererMouseController;
    +
    +   public class MultiSelectionItemRendererClassFactory extends ItemRendererClassFactory
    +   {
    +           /**
    +            *  Constructor.
    +            *
    +            *  @langversion 3.0
    +            *  @playerversion Flash 10.2
    +            *  @playerversion AIR 2.6
    +            *  @productversion Royale 0.9.7
    +            */
    +           public function MultiSelectionItemRendererClassFactory()
    +           {
    +                   super();
    +           }
    +
    +           override public function createFromClass(parent:IItemRendererParent):IItemRenderer
    +           {
    +                   var renderer:IItemRenderer = super.createFromClass(parent);
    +                   var strand:IStrand = renderer as IStrand;
    +                   var bead:IBead = strand.getBeadByType(IBeadController);
    +                   if (bead)
    +                   {
    +                           strand.removeBead(bead);
    +                   }
    +                   strand.addBead(new MultiSelectionItemRendererMouseController());
    +                   return renderer;
    +           }
    +   }
    +}
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as
    index e97eb1a..eea497f 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/AccordionItemRendererMouseController.as
    @@ -62,8 +62,6 @@ package org.apache.royale.html.beads.controllers
                 {
                         var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
                         newEvent.data = accordionItemRenderer.data;
    -                   newEvent.shiftKey = event.shiftKey;
    -                   newEvent.ctrlKey = event.ctrlKey;
                         newEvent.index = accordionItemRenderer.index;

                         accordionItemRenderer.dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    index 2d458e8..1da2806 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    @@ -160,8 +160,6 @@ COMPILE::JS {

                     var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
                     newEvent.data = target.data;
    -                newEvent.shiftKey = event.shiftKey;
    -                newEvent.ctrlKey = event.ctrlKey;
                     newEvent.index = target.index;

                     target.dispatchEvent(newEvent);
    @@ -184,8 +182,6 @@ COMPILE::JS {

                                 var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);
    @@ -204,8 +200,6 @@ COMPILE::JS {
                         {
                                 var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                     target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    @@ -225,8 +219,6 @@ COMPILE::JS {
                         {
                                 var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);
    @@ -245,8 +237,6 @@ COMPILE::JS {
                         {
                                 var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseUp");
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as
    index d0a6cf2..4ccfcc3 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ListMultiSelectionMouseController.as
    @@ -31,7 +31,7 @@ package org.apache.royale.html.beads.controllers
         import org.apache.royale.events.MouseEvent;
         import org.apache.royale.html.beads.IListView;

    -   import org.apache.royale.events.ItemClickedEvent;
    +   import org.apache.royale.events.MultiSelectionItemClickedEvent;

         /**
          *  The ListMultiSelectionMouseController class is a controller for
    @@ -133,7 +133,7 @@ package org.apache.royale.html.beads.controllers
                         IEventDispatcher(event.item).removeEventListener("itemRollOut", rolloutHandler);
                 }

    -           protected function selectedHandler(event:ItemClickedEvent):void
    +           protected function selectedHandler(event:MultiSelectionItemClickedEvent):void
                 {
                         var selectedIndices:Array = [];
                         var newIndices:Array;
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MultiSelectionItemRendererMouseController.as
    similarity index 75%
    copy from frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    copy to frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MultiSelectionItemRendererMouseController.as
    index 2d458e8..ec095ee 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/ItemRendererMouseController.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/beads/controllers/MultiSelectionItemRendererMouseController.as
    @@ -21,22 +21,22 @@ package org.apache.royale.html.beads.controllers
         import org.apache.royale.core.IBeadController;
         import org.apache.royale.core.ISelectableItemRenderer;
         import org.apache.royale.core.IStrand;
    -COMPILE::SWF {
    -   import org.apache.royale.events.Event;
    -   import org.apache.royale.events.MouseEvent;
    -}
    -COMPILE::JS {
    -   import org.apache.royale.core.UIBase;
    -   import org.apache.royale.core.WrappedHTMLElement;
    -   import org.apache.royale.events.BrowserEvent;
    -   import goog.events.Event;
    -   import goog.events.EventType;
    -    import goog.events;
    -}
    -   import org.apache.royale.events.ItemClickedEvent;
    +   COMPILE::SWF {
    +           import org.apache.royale.events.Event;
    +           import org.apache.royale.events.MouseEvent;
    +   }
    +   COMPILE::JS {
    +           import org.apache.royale.core.UIBase;
    +           import org.apache.royale.core.WrappedHTMLElement;
    +           import org.apache.royale.events.BrowserEvent;
    +           import goog.events.Event;
    +           import goog.events.EventType;
    +           import goog.events;
    +   }
    +   import org.apache.royale.events.MultiSelectionItemClickedEvent;

         /**
    -    *  The ItemRendererMouseController class can mouse events in itemRenderers. This
    +    *  The MultiSelectionItemRendererMouseController class can mouse events in itemRenderers. This
          *  includes roll-overs, mouse down, and mouse up. These platform-specific events are then
          *  re-dispatched as Royale events.
          *
    @@ -46,7 +46,8 @@ COMPILE::JS {
          *  @productversion Royale 0.9
          *  @royaleignoreimport goog.events.Event
          */
    -   public class ItemRendererMouseController implements IBeadController
    +
    +   public class MultiSelectionItemRendererMouseController implements IBeadController
         {
                 /**
                  *  constructor.
    @@ -56,13 +57,13 @@ COMPILE::JS {
                  *  @playerversion AIR 2.6
                  *  @productversion Royale 0.9
                  */
    -           public function ItemRendererMouseController()
    +           public function MultiSelectionItemRendererMouseController()
                 {
                 }
    -
    -        private var renderer:ISelectableItemRenderer;
    +
    +           private var renderer:ISelectableItemRenderer;
                 private var _strand:IStrand;
    -
    +
                 /**
                  *  @copy org.apache.royale.core.IBead#strand
                  *
    @@ -76,26 +77,26 @@ COMPILE::JS {
                 public function set strand(value:IStrand):void
                 {
                         _strand = value;
    -            renderer = value as ISelectableItemRenderer;
    -
    +                   renderer = value as ISelectableItemRenderer;
    +
                         COMPILE::SWF {
    -               renderer.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
    -               renderer.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
    +                           renderer.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
    +                           renderer.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
                                 renderer.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
                                 renderer.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                         }
    -
    +
                         COMPILE::JS {
                                 var element:WrappedHTMLElement = (_strand as UIBase).element;
    -
    +
                                 goog.events.listen(element, goog.events.EventType.MOUSEOVER, this.handleMouseOver);
                                 goog.events.listen(element, goog.events.EventType.MOUSEOUT, this.handleMouseOut);
                                 goog.events.listen(element, goog.events.EventType.MOUSEDOWN, this.handleMouseDown);
                                 goog.events.listen(element, goog.events.EventType.CLICK, this.handleMouseClick);
    -                goog.events.listen(element, goog.events.EventType.MOUSEUP, this.handleMouseUp);
    +                           goog.events.listen(element, goog.events.EventType.MOUSEUP, this.handleMouseUp);
                         }
                 }
    -
    +
                 /**
                  * @private
                  */
    @@ -108,7 +109,7 @@ COMPILE::JS {
                                 target.dispatchEvent(new Event("itemRollOver",true));
                         }
                 }
    -
    +
                 /**
                  * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
                  */
    @@ -120,7 +121,7 @@ COMPILE::JS {
                                 target.dispatchEvent(new Event("itemRollOver",true));
                         }
                 }
    -
    +
                 /**
                  * @private
                  */
    @@ -133,7 +134,7 @@ COMPILE::JS {
                                 target.dispatchEvent(new Event("itemRollOut",true));
                         }
                 }
    -
    +
                 /**
                  * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
                  */
    @@ -156,19 +157,19 @@ COMPILE::JS {
                         var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
                         if (target)
                         {
    -                target.down = true;
    -
    -                var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
    -                newEvent.data = target.data;
    -                newEvent.shiftKey = event.shiftKey;
    -                newEvent.ctrlKey = event.ctrlKey;
    -                newEvent.index = target.index;
    -
    -                target.dispatchEvent(newEvent);
    +                           target.down = true;
    +
    +                           var newEvent:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent("itemMouseDown", true, true);
    +                           newEvent.shiftKey = event.shiftKey;
    +                           newEvent.ctrlKey = event.ctrlKey;
    +                           newEvent.data = target.data;
    +                           newEvent.index = target.index;
    +
    +                           target.dispatchEvent(newEvent);
                                 target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                         }
                 }
    -
    +
                 /**
                  * @private
                  * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
    @@ -182,16 +183,14 @@ COMPILE::JS {
                                 target.down = true;
                                 target.hovered = false;

    -                           var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseDown");
    +                           var newEvent:MultiSelectionItemClickedEvent = MultiSelectionItemClickedEvent.createMultiSelectionItemClickedEvent("itemMouseDown", event);
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);
                         }
                 }
    -
    +
                 /**
                  * @private
                  */
    @@ -202,17 +201,16 @@ COMPILE::JS {
                         var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
                         if (target)
                         {
    -                           var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    -                           newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    +                           var newEvent:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent("itemClicked", true, true);
                                 newEvent.ctrlKey = event.ctrlKey;
    +                           newEvent.shiftKey = event.shiftKey;
    +                           newEvent.data = target.data;
                                 newEvent.index = target.index;
    -
    -                target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    +                           target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                                 target.dispatchEvent(newEvent);
                         }
                 }
    -
    +
                 /**
                  * @private
                  * @royaleemitcoercion org.apache.royale.core.ISelectableItemRenderer
    @@ -223,10 +221,8 @@ COMPILE::JS {
                         var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
                         if (target)
                         {
    -                           var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    +                           var newEvent:MultiSelectionItemClickedEvent = MultiSelectionItemClickedEvent.createMultiSelectionItemClickedEvent("itemClicked", event);
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);
    @@ -243,10 +239,8 @@ COMPILE::JS {
                         var target:ISelectableItemRenderer = event.currentTarget as ISelectableItemRenderer;
                         if (target)
                         {
    -                           var newEvent:ItemClickedEvent = new ItemClickedEvent("itemMouseUp");
    +                           var newEvent:MultiSelectionItemClickedEvent = MultiSelectionItemClickedEvent.createMultiSelectionItemClickedEvent("itemMouseUp", event);
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as
    index f182c48..5366419 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/ButtonBarButtonItemRenderer.as
    @@ -69,8 +69,6 @@ package org.apache.royale.html.supportClasses
                 protected function handleClickEvent(event:MouseEvent):void
                 {
                         var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    -                   newEvent.shiftKey = event.shiftKey;
    -                   newEvent.ctrlKey = event.ctrlKey;
                         newEvent.index = index;
                         newEvent.data = data;
                         dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as
    index 4bb2e53..93d84c9 100644
    --- a/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as
    +++ b/frameworks/projects/Basic/src/main/royale/org/apache/royale/html/supportClasses/TextButtonItemRenderer.as
    @@ -99,8 +99,6 @@ package org.apache.royale.html.supportClasses
                 protected function handleClickEvent(event:MouseEvent):void
                 {
                         var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
    -                   newEvent.shiftKey = event.shiftKey;
    -                   newEvent.ctrlKey = event.ctrlKey;
                         newEvent.index = index;
                         newEvent.data = data;
                         dispatchEvent(newEvent);
    diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as b/frameworks/projects/Core/src/main/royale/CoreClasses.as
    index 2c17dc7..6145af7 100644
    --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
    +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
    @@ -43,6 +43,7 @@ internal class CoreClasses

         import org.apache.royale.events.ItemAddedEvent; ItemAddedEvent;
         import org.apache.royale.events.ItemClickedEvent; ItemClickedEvent;
    +   import org.apache.royale.events.MultiSelectionItemClickedEvent; MultiSelectionItemClickedEvent;
         import org.apache.royale.events.ItemRemovedEvent; ItemRemovedEvent;
         import org.apache.royale.events.ItemRendererEvent; ItemRendererEvent;

    diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    index c4c239f..7f92ff4 100644
    --- a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    +++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    @@ -51,7 +51,7 @@ package org.apache.royale.events
                  * @langversion 3.0
                  * @playerversion Flash 10.2
                  * @playerversion AIR 2.6
    -            * @productversion Royale 0.0
    +            * @productversion Royale 0.9.7
                  */
                 public function ItemClickedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
                 {
    @@ -66,8 +66,6 @@ package org.apache.royale.events

                         index = -1;
                         data = null;
    -                   shiftKey = false;
    -                   ctrlKey = false;
                 }

                 /**
    @@ -102,26 +100,12 @@ package org.apache.royale.events
                  * @productversion Royale 0.9.7
                  */

    -           public var shiftKey:Boolean;
    -           /**
    -            * Whether or not this click was done while holding the control key
    -            *
    -            * @export
    -            * @langversion 3.0
    -            * @playerversion Flash 10.2
    -            * @playerversion AIR 2.6
    -            * @productversion Royale 0.9.7
    -            */
    -           public var ctrlKey:Boolean;
    -

                 override public function cloneEvent():IRoyaleEvent
                 {
                         var newEvent:ItemClickedEvent = new ItemClickedEvent(type);
                         newEvent.index = index;
                         newEvent.data = data;
    -                   newEvent.shiftKey = shiftKey;
    -                   newEvent.ctrlKey = ctrlKey;
                         return newEvent;
                 }
         }
    diff --git a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/MultiSelectionItemClickedEvent.as
    similarity index 62%
    copy from frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    copy to frameworks/projects/Core/src/main/royale/org/apache/royale/events/MultiSelectionItemClickedEvent.as
    index c4c239f..d1c73bb 100644
    --- a/frameworks/projects/Core/src/main/royale/org/apache/royale/events/ItemClickedEvent.as
    +++ b/frameworks/projects/Core/src/main/royale/org/apache/royale/events/MultiSelectionItemClickedEvent.as
    @@ -20,10 +20,14 @@
     package org.apache.royale.events
     {

    -   import org.apache.royale.events.CustomEvent;
    +   import org.apache.royale.utils.OSUtils;
    +   COMPILE::JS
    +   {
    +           import org.apache.royale.events.BrowserEvent;
    +   }

         /**
    -    * The ItemClickedEvent is a custom event issued by an itemRenderer to
    +    * The MultiSelectionItemClickedEvent is a custom event issued by a multi selection itemRenderer to
          * convey information about itself when it has determined that the
          * event(s) happening to it constitute a 'click' on itself.
          *
    @@ -34,7 +38,7 @@ package org.apache.royale.events
          *
          *  @royalesuppresspublicvarwarning
          */
    -   public class ItemClickedEvent extends CustomEvent
    +   public class MultiSelectionItemClickedEvent extends ItemClickedEvent
         {

                 //--------------------------------------
    @@ -51,9 +55,9 @@ package org.apache.royale.events
                  * @langversion 3.0
                  * @playerversion Flash 10.2
                  * @playerversion AIR 2.6
    -            * @productversion Royale 0.0
    +            * @productversion Royale 0.9.7
                  */
    -           public function ItemClickedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
    +           public function MultiSelectionItemClickedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
                 {
                         COMPILE::SWF
                         {
    @@ -63,34 +67,8 @@ package org.apache.royale.events
                         {
                                 super(type);
                         }
    -
    -                   index = -1;
    -                   data = null;
    -                   shiftKey = false;
    -                   ctrlKey = false;
                 }

    -           /**
    -            * The index of the item beginning with zero.
    -            *
    -            * @export
    -            * @langversion 3.0
    -            * @playerversion Flash 10.2
    -            * @playerversion AIR 2.6
    -            * @productversion Royale 0.0
    -            */
    -           public var index:Number;
    -
    -           /**
    -            * The data of the item.
    -            *
    -            * @export
    -            * @langversion 3.0
    -            * @playerversion Flash 10.2
    -            * @playerversion AIR 2.6
    -            * @productversion Royale 0.0
    -            */
    -           public var data:Object;

                 /**
                  * Whether or not this click was done while holding the shift key
    @@ -117,12 +95,37 @@ package org.apache.royale.events

                 override public function cloneEvent():IRoyaleEvent
                 {
    -                   var newEvent:ItemClickedEvent = new ItemClickedEvent(type);
    +                   var newEvent:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent(type);
                         newEvent.index = index;
                         newEvent.data = data;
                         newEvent.shiftKey = shiftKey;
                         newEvent.ctrlKey = ctrlKey;
                         return newEvent;
                 }
    +
    +           /**
    +            *  Factory for MultiSelectionItemClickedEvents.
    +            *
    +            *  @param type The name of the event.
    +            *  @param event The MouseEvent properties to copy into the MultiSelectionItemClickedEvent.
    +            *  @return The new MultiSelectionItemClickedEvent.
    +            *
    +            *  @langversion 3.0
    +            *  @playerversion Flash 10.2
    +            *  @playerversion AIR 2.6
    +            *  @productversion Royale 0.9.7
    +            *  @royaleignorecoercion org.apache.royale.events.MultiSelectionItemClickedEvent
    +            *  @royaleignorecoercion window.Event
    +            *  @royaleignorecoercion Event
    +            */
    +           COMPILE::JS
    +           public static function createMultiSelectionItemClickedEvent(type:String, event:BrowserEvent):MultiSelectionItemClickedEvent
    +           {
    +                   var msice:MultiSelectionItemClickedEvent = new MultiSelectionItemClickedEvent(type, true, true);
    +                   var ctrlKey:Boolean = OSUtils.getOS() == OSUtils.MAC_OS || OSUtils.getOS() == OSUtils.IOS_OS ? event.nativeEvent["metaKey"] : event.ctrlKey;
    +                   msice.ctrlKey = ctrlKey;
    +                   msice.shiftKey = event.shiftKey;
    +                   return msice;
    +           }
         }
     }
    diff --git a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as
    index 4435999..5f1acee 100644
    --- a/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as
    +++ b/frameworks/projects/Jewel/src/main/royale/org/apache/royale/jewel/beads/controllers/ItemRendererMouseController.as
    @@ -189,8 +189,6 @@ package org.apache.royale.jewel.beads.controllers
                         {
                                 var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                     target.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    @@ -211,8 +209,6 @@ package org.apache.royale.jewel.beads.controllers
                         {
                                 var newEvent:ItemClickedEvent = new ItemClickedEvent("itemClicked");
                                 newEvent.data = target.data;
    -                           newEvent.shiftKey = event.shiftKey;
    -                           newEvent.ctrlKey = event.ctrlKey;
                                 newEvent.index = target.index;

                                 target.dispatchEvent(newEvent);