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

yishayw 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 9d5f1c2  Multi Selection beads added, still need to change drop order 
and handle case where nothing is selected
     new fc64ff9  Merge branch 'develop' of 
https://github.com/apache/royale-asjs into develop
9d5f1c2 is described below

commit 9d5f1c27694e55c654f05861144f764b5a8f838d
Author: DESKTOP-RH4S838\Yishay <[email protected]>
AuthorDate: Mon Dec 2 13:09:47 2019 +0200

    Multi Selection beads added, still need to change drop order and handle 
case where nothing is selected
---
 .../DragDrop/src/main/resources/basic-manifest.xml |   3 +
 .../DragDrop/src/main/royale/DragDropClasses.as    |   2 +
 .../html/beads/MultiSelectionDragImageBead.as      | 153 ++++++++
 .../html/beads/MultiSelectionDragSourceBead.as     | 270 ++++++++++++++
 .../beads/SensitiveMultiSelectionDropTargetBead.as | 407 +++++++++++++++++++++
 5 files changed, 835 insertions(+)

diff --git a/frameworks/projects/DragDrop/src/main/resources/basic-manifest.xml 
b/frameworks/projects/DragDrop/src/main/resources/basic-manifest.xml
index 1295ed4..c21964c 100644
--- a/frameworks/projects/DragDrop/src/main/resources/basic-manifest.xml
+++ b/frameworks/projects/DragDrop/src/main/resources/basic-manifest.xml
@@ -21,11 +21,14 @@
 
 <componentPackage>
 
+       <component id="MultiSelectionDragImageBead" 
class="org.apache.royale.html.beads.MultiSelectionDragImageBead" />
+       <component id="MultiSelectionDragSourceBead" 
class="org.apache.royale.html.beads.MultiSelectionDragSourceBead" />
        <component id="SingleSelectionDragImageBead" 
class="org.apache.royale.html.beads.SingleSelectionDragImageBead" />
        <component id="SingleSelectionDragSourceBead" 
class="org.apache.royale.html.beads.SingleSelectionDragSourceBead" />
        <component id="SingleSelectionDropIndicatorBead" 
class="org.apache.royale.html.beads.SingleSelectionDropIndicatorBead"/>
        <component id="SingleSelectionDropTargetBead" 
class="org.apache.royale.html.beads.SingleSelectionDropTargetBead" />
        <component id="SensitiveSingleSelectionDropTargetBead" 
class="org.apache.royale.html.beads.SensitiveSingleSelectionDropTargetBead" />
+       <component id="SensitiveMultiSelectionDropTargetBead" 
class="org.apache.royale.html.beads.SensitiveMultiSelectionDropTargetBead" />
     <component id="DragMouseController" 
class="org.apache.royale.html.beads.controllers.DragMouseController" />
     <component id="DropMouseController" 
class="org.apache.royale.html.beads.controllers.DropMouseController" />
        
diff --git a/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as 
b/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as
index cc64931..107c31c 100644
--- a/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as
+++ b/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as
@@ -30,6 +30,8 @@ internal class DragDropClasses
     import org.apache.royale.core.DropType; DropType;
     import org.apache.royale.events.DragEvent; DragEvent;
 
+       import org.apache.royale.html.beads.MultiSelectionDragImageBead; 
MultiSelectionDragImageBead;
+       import org.apache.royale.html.beads.MultiSelectionDragSourceBead; 
MultiSelectionDragSourceBead;
        import org.apache.royale.html.beads.SingleSelectionDragImageBead; 
SingleSelectionDragImageBead;
        import org.apache.royale.html.beads.SingleSelectionDragSourceBead; 
SingleSelectionDragSourceBead;
        import org.apache.royale.html.beads.SingleSelectionDropIndicatorBead; 
SingleSelectionDropIndicatorBead;
diff --git 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/MultiSelectionDragImageBead.as
 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/MultiSelectionDragImageBead.as
new file mode 100644
index 0000000..94a2730
--- /dev/null
+++ 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/MultiSelectionDragImageBead.as
@@ -0,0 +1,153 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.html.beads
+{
+
+       import org.apache.royale.collections.ArrayList;
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IBeadLayout;
+       import org.apache.royale.core.IChild;
+       import org.apache.royale.core.IMultiSelectionModel;
+       import org.apache.royale.core.IDocument;
+       import org.apache.royale.core.IDragInitiator;
+       import org.apache.royale.core.IItemRenderer;
+       import org.apache.royale.core.IItemRendererParent;
+       import org.apache.royale.core.IParent;
+       import org.apache.royale.core.ISelectableItemRenderer;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.core.Lookalike;
+       import org.apache.royale.core.UIBase;
+       import org.apache.royale.core.IBeadView;
+       import org.apache.royale.html.IListView;
+       import org.apache.royale.events.DragEvent;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.EventDispatcher;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.geom.Point;
+       import org.apache.royale.geom.Rectangle;
+       import org.apache.royale.html.Button;
+       import org.apache.royale.html.Container;
+       import org.apache.royale.html.Label;
+       import org.apache.royale.html.beads.controllers.DragMouseController;
+       import org.apache.royale.utils.PointUtils;
+       import org.apache.royale.utils.getParentOrSelfByType;
+       import org.apache.royale.html.beads.layouts.VerticalLayout;
+       import org.apache.royale.html.beads.layouts.HorizontalLayout;
+
+       COMPILE::JS
+       {
+               import org.apache.royale.core.WrappedHTMLElement;
+       }
+
+
+       /**
+        *  The MultiSelectionDragImageBead produces a UIBase component that 
represents
+        *  the item being dragged. It does this by creating lookalikes to all 
selected items
+        *  and adding them to a container.
+        *
+        *  The createDragImage() function can be overridden and a different 
component returned.
+        *
+        *  @see org.apache.royale.html.beads.SingleSelectionDragSourceBead.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       public class MultiSelectionDragImageBead extends EventDispatcher 
implements IBead
+       {
+               /**
+                * Constructor.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function MultiSelectionDragImageBead()
+               {
+                       super();
+               }
+
+               private var _strand:IStrand;
+
+               /**
+                * @private
+                */
+               public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+
+                       
IEventDispatcher(_strand).addEventListener(DragEvent.DRAG_START, 
handleDragStart);
+               }
+
+               /**
+                * Creates an example/temporary component to be dragged and 
returns it.
+                *
+                * @param ir IItemRenderer The itemRenderer to be used as a 
template.
+                * @return UIBase The "dragImage" to use.
+                *
+                *  @royaleignorecoercion 
org.apache.royale.core.WrappedHTMLElement
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               protected function createDragImage():UIBase
+               {
+                       var dragImage:Container = new Container();
+                       var layoutBead:IBead = 
_strand.getBeadByType(IBeadLayout);
+                       if (layoutBead is VerticalLayout)
+                       {
+                               dragImage.addBead(new VerticalLayout())
+                       } else
+                       {
+                               dragImage.addBead(new HorizontalLayout())
+                       }
+                       var itemRendererParent:IItemRendererParent = 
(_strand.getBeadByType(IBeadView) as IListView).dataGroup as 
IItemRendererParent;
+                       var selectedIndices:Array = 
(_strand.getBeadByType(IMultiSelectionModel) as 
IMultiSelectionModel).selectedIndices;
+                       for (var i:int = 0; i < selectedIndices.length; i++)
+                       {
+                               var ir:IItemRenderer = 
itemRendererParent.getItemRendererForIndex(selectedIndices[i]);
+                               var lookalike:UIBase = new Lookalike(ir);
+                               lookalike.width = IUIBase(ir).width;
+                               lookalike.height = IUIBase(ir).height;
+                               dragImage.addElement(lookalike);
+                       }
+
+                       dragImage.className = "DragImage";
+                       COMPILE::JS 
+                       {
+                               dragImage.element.style.position = 'absolute';
+                               dragImage.element.style.cursor = 'pointer';
+                       }
+                       return dragImage;
+               }
+
+               /**
+                * @private
+                *
+                */
+               private function handleDragStart(event:DragEvent):void
+               {
+                       DragMouseController.dragImage = createDragImage();
+               }
+       }
+}
diff --git 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/MultiSelectionDragSourceBead.as
 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/MultiSelectionDragSourceBead.as
new file mode 100644
index 0000000..ab40159
--- /dev/null
+++ 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/MultiSelectionDragSourceBead.as
@@ -0,0 +1,270 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.html.beads
+{
+       import org.apache.royale.collections.ArrayList;
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IChild;
+       import org.apache.royale.core.IMultiSelectionModel;
+       import org.apache.royale.core.IDocument;
+       import org.apache.royale.core.IDragInitiator;
+       import org.apache.royale.core.IItemRenderer;
+       import org.apache.royale.core.ILayoutHost;
+       import org.apache.royale.core.IItemRendererParent;
+       import org.apache.royale.core.IParent;
+       import org.apache.royale.core.ISelectionModel;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.events.DragEvent;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.EventDispatcher;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.geom.Point;
+       import org.apache.royale.geom.Rectangle;
+       import org.apache.royale.html.Group;
+       import org.apache.royale.html.Label;
+       import org.apache.royale.html.beads.controllers.DragMouseController;
+       import org.apache.royale.html.supportClasses.DataItemRenderer;
+       import org.apache.royale.utils.PointUtils;
+       import org.apache.royale.utils.UIUtils;
+       import org.apache.royale.utils.getParentOrSelfByType;
+
+       /**
+        * The start event is dispatched when a DragStart event happens. The 
DragEvent.dragSource
+        * is set before this event is dispatched. A listener for this event 
can then decide if
+        * if the drag-drop action should continue or not. If not, the event 
should be cancelled.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9
+        */
+       [Event(name="start", type="org.apache.royale.events.Event")]
+
+       /**
+        * The accept event is dispatched when the drop happens but just before 
the data being
+        * dragged as been incorporated into the drop target's data source. 
Cancelling this event
+        * prevents that from happening.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9
+        */
+       [Event(name="accept", type="org.apache.royale.events.Event")]
+
+       /**
+        * The complete event is dispatched when the entire drag-and-drop 
operation has completed
+        * from the drag source's perspective.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9
+        */
+       [Event(name="complete", type="org.apache.royale.events.Event")]
+
+
+       /**
+        *  The MultiSelectionDragSourceBead brings drag capability to 
single-selection List components.
+        *  By adding this bead, a user can drag a row of the List to a new 
location within the list. This bead
+        *  should be used in conjunction with SingleSelectionDropTargetBead.
+        *
+        *  This bead adds a new event to the strand, "dragImageNeeded", which 
is dispatched on the strand
+        *  just prior to the dragImage's appearance. An event listener can 
create its own dragImage if the
+        *  default, taken from the data item, is not suitable.
+        *
+        *  @see org.apache.royale.html.beads.SingleSelectionDropTargetBead.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       public class MultiSelectionDragSourceBead extends EventDispatcher 
implements IBead, IDragInitiator
+       {
+               /**
+                * Constructor
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function MultiSelectionDragSourceBead()
+               {
+                       super();
+               }
+
+               private var _strand:IStrand;
+               private var _dragController:DragMouseController;
+               private var continueDragOperation:Boolean = true;
+
+               private var _dragType:String = "move";
+
+               /**
+                * The type of drag and drop operation: move or copy.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function get dragType():String
+               {
+                       return _dragType;
+               }
+               public function set dragType(value:String):void
+               {
+                       _dragType = value;
+               }
+
+               /**
+                * @private
+                */
+               public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+
+                       _dragController = new DragMouseController();
+                       _strand.addBead(_dragController);
+
+                       
IEventDispatcher(_strand).addEventListener(DragEvent.DRAG_START, 
handleDragStart);
+                       
IEventDispatcher(_strand).addEventListener(DragEvent.DRAG_MOVE, handleDragMove);
+                       
IEventDispatcher(_strand).addEventListener(DragEvent.DRAG_END, handleDragEnd);
+               }
+
+               /**
+                * The index into the dataProvider of the strand's model where 
the dragSource
+                * can be found. If -1, the dragSource is not in the 
dataProvider.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9
+                */
+               public function get dragSourceIndices():Array
+               {
+                       var dataProviderModel:IMultiSelectionModel = 
_strand.getBeadByType(IMultiSelectionModel) as IMultiSelectionModel;
+                       return dataProviderModel.selectedIndices;
+               }
+
+               /**
+                * @private
+                */
+               private function handleDragStart(event:DragEvent):void
+               {
+                       //trace("MultiSelectionDragSourceBead received the 
DragStart");
+
+                       DragEvent.dragInitiator = this;
+                       DragMouseController.dragImageOffsetX = 0;
+                       DragMouseController.dragImageOffsetY = -30;
+
+                       var dataProviderModel:IMultiSelectionModel = 
_strand.getBeadByType(IMultiSelectionModel) as IMultiSelectionModel;
+                       DragEvent.dragSource = dataProviderModel.selectedItems;
+
+                       var newEvent:Event = new Event("start", false, true);
+                       dispatchEvent(newEvent);
+                       if (newEvent.defaultPrevented) {
+                               continueDragOperation = false;
+                       }
+               }
+
+               /**
+                * @private
+                */
+               protected function handleDragMove(event:DragEvent):void
+               {
+                       // ignored for now
+               }
+
+               /**
+                * @private
+                */
+               protected function handleDragEnd(event:DragEvent):void
+               {
+                       // ignored for now
+               }
+
+               /* IDragInitiator */
+
+               /**
+                * Handles pre-drop actions.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function acceptingDrop(dropTarget:Object, 
type:String):void
+               {
+                       if (!continueDragOperation) return;
+
+                       //trace("MultiSelectionDragSourceBead accepting drop of 
type "+type);
+                       var newEvent:Event = new Event("accept", false, true);
+                       dispatchEvent(newEvent);
+                       if (newEvent.defaultPrevented) return;
+                       
+                       var dataProviderModel:IMultiSelectionModel = 
_strand.getBeadByType(IMultiSelectionModel) as IMultiSelectionModel;
+                       if (dataProviderModel is ISelectionModel) {
+                               (dataProviderModel as 
IMultiSelectionModel).selectedIndices = null;
+                       }
+
+                       if (dragType == "copy") return;
+                       var dragSource:Array = DragEvent.dragSource as Array;
+                       if (dataProviderModel.dataProvider is Array) {
+                               var dataArray:Array = 
dataProviderModel.dataProvider as Array;
+
+                               for (var i:int = 0; i < dragSource.length; i++)
+                               {
+                                       
dataArray.removeAt(dataArray.indexOf(dragSource[i]));
+                               }       
+
+                               // refresh the dataProvider model
+                               var newArray:Array = dataArray.slice()
+                               dataProviderModel.dataProvider = newArray;
+                       }
+                       else if (dataProviderModel.dataProvider is ArrayList) {
+                               var dataList:ArrayList = 
dataProviderModel.dataProvider as ArrayList;
+
+                               for (i = 0; i < dragSource.length; i++)
+                               {
+                                       dataList.removeItem(dragSource[i]);
+                               }       
+                       }
+               }
+
+               /**
+                * Handles post-drop actions.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function acceptedDrop(dropTarget:Object, 
type:String):void
+               {
+                       var dataProviderModel:IMultiSelectionModel = 
_strand.getBeadByType(IMultiSelectionModel) as IMultiSelectionModel;
+                       dataProviderModel.selectedIndices = null;
+                       dispatchEvent(new Event("complete"));
+               }
+
+       }
+}
diff --git 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SensitiveMultiSelectionDropTargetBead.as
 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SensitiveMultiSelectionDropTargetBead.as
new file mode 100644
index 0000000..58a8380
--- /dev/null
+++ 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SensitiveMultiSelectionDropTargetBead.as
@@ -0,0 +1,407 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// TODO:yishayw rename this class
+package org.apache.royale.html.beads
+{
+       import org.apache.royale.collections.ArrayList;
+       import org.apache.royale.core.DropType;
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IMultiSelectionModel;
+       import org.apache.royale.core.IItemRenderer;
+       import org.apache.royale.core.IItemRendererParent;
+       import org.apache.royale.core.ISelectionModel;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.core.UIBase;
+       import org.apache.royale.events.DragEvent;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.EventDispatcher;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.geom.Point;
+       import org.apache.royale.html.beads.controllers.DropMouseController;
+       import org.apache.royale.utils.PointUtils;
+
+
+       /**
+        * The enter event is dispatched when a DragEnter has been detected in 
the drop target
+        * strand. This event can be used to determine if the strand can and 
will accept the data
+        * being dragged onto it. If the data cannot be used by the drop target 
strand this event
+        * should be cancelled.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       [Event(name="enter", type="org.apache.royale.events.Event")]
+
+       /**
+        * The exit event is sent when the drag goes outside of the drop target 
space.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       [Event(name="exit", type="org.apache.royale.events.Event")]
+
+       /**
+        * The over event is dispatched while the drag is happening over the 
drop target space. This
+        * event may be cancelled if that particular area of the drop target 
cannot accept the
+        * drag source data.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       [Event(name="over", type="org.apache.royale.events.Event")]
+
+       /**
+        * The drop event is dispatched just prior to incorporating the drag 
source data into the drop
+        * target's dataProvider. This event may be cancelled to prevent that 
from happening.
+        * Note that a "exit" event always precedes this event to allow any 
drag-drop graphics
+        * to be cleared.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       [Event(name="drop", type="org.apache.royale.events.Event")]
+
+       /**
+        * The complete event is dispatched when the drop operation has 
completed from the drop
+        * target's perspective.
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       [Event(name="complete", type="org.apache.royale.events.Event")]
+
+       /**
+        *  The SensitiveMultiSelectionDropTargetBead enables items to be 
dropped onto multi-selection List
+        *  components. When the pointing device is in the first half of an 
item renderer it assumes the item is to be dropped on that item renderer.
+        *  If it is on the second half it assumes the drop target is the next 
item renderer.
+        *
+        *  @see org.apache.royale.html.beads.SingleSelectionDropTargetBead
+        *
+        *  @langversion 3.0
+        *  @playerversion Flash 10.2
+        *  @playerversion AIR 2.6
+        *  @productversion Royale 0.9.7
+        */
+       public class SensitiveMultiSelectionDropTargetBead extends 
EventDispatcher implements IBead
+       {
+               /**
+                * Constructor
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function SensitiveMultiSelectionDropTargetBead()
+               {
+                       super();
+               }
+
+               private var _dropController:DropMouseController;
+               private var _itemRendererParent:IItemRendererParent;
+               private var _dropIndicatorBead:SingleSelectionDropIndicatorBead;
+               private var _dropIndicator:UIBase;
+               private var targetIndex:int = -1;
+               private var indicatorVisible:Boolean = false;
+               private var isEndOfList:Boolean = false;
+
+               private var _strand:IStrand;
+
+               /**
+                * @private
+                *  @royaleignorecoercion 
org.apache.royale.events.IEventDispatcher
+                */
+               public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+
+                       _dropController = new DropMouseController();
+                       _strand.addBead(_dropController);
+
+                       _dropController.addEventListener(DragEvent.DRAG_ENTER, 
handleDragEnter);
+                       _dropController.addEventListener(DragEvent.DRAG_EXIT, 
handleDragExit);
+                       _dropController.addEventListener(DragEvent.DRAG_OVER, 
handleDragOver);
+                       _dropController.addEventListener(DragEvent.DRAG_DROP, 
handleDragDrop);
+                       
IEventDispatcher(_strand).addEventListener(DragEvent.DRAG_MOVE, handleDragMove);
+               }
+
+               private var _dropDirection: String = "horizontal";
+
+               /**
+                * The direction the drop indicator should display. 
"horizontal" (default) or "vertical".
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10.2
+                *  @playerversion AIR 2.6
+                *  @productversion Royale 0.9.7
+                */
+               public function get dropDirection():String
+               {
+                       return _dropDirection;
+               }
+               public function set dropDirection(value:String):void
+               {
+                       _dropDirection = value;
+               }
+
+               protected var _indicatorParent:UIBase;
+
+               /**
+                * @private
+                */
+               protected function get indicatorParent():UIBase
+               {
+                       if (_indicatorParent == null) {
+                               var layerBead:IDrawingLayerBead = 
_strand.getBeadByType(IDrawingLayerBead) as IDrawingLayerBead;
+                               if (layerBead != null) {
+                                       _indicatorParent = layerBead.layer;
+                               }
+                       }
+                       return _indicatorParent;
+               }
+               /**
+                * @private
+                */
+               private function get itemRendererParent():IItemRendererParent
+               {
+                       if (!_itemRendererParent)
+                               _itemRendererParent = 
_strand.getBeadByType(IItemRendererParent) as IItemRendererParent;
+                       return _itemRendererParent;
+               }
+
+               /**
+                * @private
+                */
+               protected function getDropIndicator(ir:Object, width:Number, 
height:Number):UIBase
+               {
+                       if (_dropIndicatorBead == null) {
+                               _dropIndicatorBead = 
_strand.getBeadByType(SingleSelectionDropIndicatorBead) as 
SingleSelectionDropIndicatorBead;
+                               if (_dropIndicatorBead == null) return null;
+                       }
+                       _dropIndicator = 
_dropIndicatorBead.getDropIndicator(ir, width, height);
+                       return _dropIndicator;
+               }
+
+               /**
+                * @private
+                */
+               private function handleDragEnter(event:DragEvent):void
+               {
+                       var newEvent:Event = new Event("enter", false, true);
+                       dispatchEvent(newEvent);
+                       if (newEvent.defaultPrevented) return;
+
+
+                       var pt0:Point;
+                       var pt1:Point;
+                       var pt2:Point;
+
+                       _dropController.acceptDragDrop(event.relatedObject as 
IUIBase, DropType.COPY);
+               }
+               
+               private function checkForNextItemRenderer(e:DragEvent):void
+               {
+                       var changeMade:Boolean = true;
+                       var calculatedIndex:int = -1;
+                       for (var i:int = 0; i < 
itemRendererParent.numItemRenderers; i++)
+                       {
+                               var ir:IUIBase = 
itemRendererParent.getItemRendererAt(i) as IUIBase;
+                               var localY:Number = 
PointUtils.globalToLocal(new Point(e.clientX, e.clientY), ir).y;
+                               if (localY >= 0 && localY <= ir.height)
+                               {
+                                       calculatedIndex = i;
+                                       if (localY > ir.height / 2)
+                                       {
+                                               calculatedIndex++;
+                                       }
+                                       break;
+                               }
+                       }
+                       if (targetIndex != calculatedIndex && calculatedIndex 
!= -1 && indicatorParent && (targetIndex != calculatedIndex || 
!indicatorVisible)) {
+                               targetIndex = calculatedIndex;
+                               // in case we're at the end of the list, we 
want to choose the last renderer
+                               // but we also want to drop the source after 
the least renderer, not before it
+                               isEndOfList = calculatedIndex == 
itemRendererParent.numItemRenderers;
+                               // calculated index may have been increased 
beyond bounds
+                               var lastItemVisitedIndex:int = !isEndOfList ? 
calculatedIndex : calculatedIndex - 1;
+                               var lastItemVisited:IUIBase = 
itemRendererParent.getItemRendererAt(lastItemVisitedIndex) as IUIBase;
+                               
+                               var di:UIBase = 
getDropIndicator(lastItemVisited, (dropDirection == "horizontal") ? 
indicatorParent.width : 4,
+                                       (dropDirection == "horizontal") ? 4 : 
indicatorParent.height);
+                               if (indicatorParent != null) {
+                                       indicatorParent.addElement(di);
+                               }
+                               displayDropIndicator(lastItemVisited, 
isEndOfList);
+                               indicatorVisible = true;
+                       }
+               }
+               
+               /**
+                * @private
+                */
+               private function handleDragExit(event:DragEvent):void
+               {
+                       //trace("MultiSelectionDropTargetBead received DragExit 
via: "+event.relatedObject.toString());
+                       dispatchEvent(new Event("exit", false, true));
+
+                       if (indicatorVisible) {
+                               if (indicatorParent != null) {
+                                       
indicatorParent.removeElement(_dropIndicator);
+                               }
+                               indicatorVisible = false;
+                       }
+               }
+
+               /**
+                * @private
+                */
+               private function handleDragOver(event:DragEvent):void
+               {
+                       //trace("MultiSelectionDropTargetBead received DragOver 
via: "+event.relatedObject.toString());
+                       var newEvent:Event = new Event("over", false, true);
+                       dispatchEvent(newEvent);
+                       if (event.defaultPrevented) {
+                               return;
+                       }
+               }
+
+               /**
+                * @private
+                */
+               private function handleDragMove(event:DragEvent):void
+               {
+                       checkForNextItemRenderer(event);
+               }
+
+               /**
+                * @private
+                */
+               private function handleDragDrop(event:DragEvent):void
+               {
+                       //trace("SingleSelectionDropTargetBead received 
DragDrop via: "+event.relatedObject.toString());
+
+                       handleDragExit(event);
+
+                       var newEvent:Event = new Event("drop", false, true);
+                       dispatchEvent(newEvent);
+                       if (newEvent.defaultPrevented) {
+                               return;
+                       }
+
+
+                       var dragSource:Array = DragEvent.dragSource as Array;
+                       var calculatedTargetIndex:int = targetIndex;
+
+                       // dragging somewhere higher on the list, fix items 
jumping down before it's dropped
+                       for (var i:int = 0; i < calculatedTargetIndex; i++)
+                       {
+                               if 
(itemRendererParent.getItemRendererAt(i).data == dragSource[0])
+                               {
+                                       calculatedTargetIndex--;
+                                       break;
+                               }
+                       }
+                       
+                       if (DragEvent.dragInitiator) {
+                               DragEvent.dragInitiator.acceptingDrop(_strand, 
"object");
+                       }
+
+                       var dataProviderModel:IMultiSelectionModel = 
_strand.getBeadByType(IMultiSelectionModel) as IMultiSelectionModel;
+                       if (dataProviderModel.dataProvider is Array) {
+                               var dataArray:Array = 
dataProviderModel.dataProvider as Array;
+                               for (i = 0; i < dragSource.length; i++)
+                               {
+                                       
dataArray.insertAt(calculatedTargetIndex++, dragSource[i]);
+                               }
+                               var newArray:Array = dataArray.slice()
+                               dataProviderModel.dataProvider = newArray;
+                       } else if (dataProviderModel.dataProvider is ArrayList)
+                       {
+                               var dataList:ArrayList = 
dataProviderModel.dataProvider as ArrayList;
+                               for (i = 0; i < dragSource.length; i++)
+                               {
+                                       dataList.addItemAt(dragSource[i], 
calculatedTargetIndex++);
+                               }
+                       }
+
+                       // Let the dragInitiator know the drop has been 
completed.
+                       if (DragEvent.dragInitiator) {
+                               DragEvent.dragInitiator.acceptedDrop(_strand, 
"object");
+                       }
+                       
+                       if (dataProviderModel is ISelectionModel) {
+                               (dataProviderModel as 
ISelectionModel).selectedIndex = calculatedTargetIndex;
+                       }
+
+                       // is this event necessary? isn't "complete" enough?
+                       IEventDispatcher(_strand).dispatchEvent(new 
Event("dragDropAccepted"));
+
+                       dispatchEvent(new Event("complete"));
+               }
+
+               COMPILE::SWF
+               private function displayDropIndicator(item:IUIBase, 
isEndOfList:Boolean=false):void
+               {
+                       var pt0:Point;
+                       var pt1:Point;
+                       var pt2:Point;
+
+                       if (dropDirection == "horizontal") {
+                               pt0 = new Point(0, item.y+item.height);
+                               pt1 = PointUtils.localToGlobal(pt0, 
item.parent);
+                               pt2 = PointUtils.globalToLocal(pt1, 
indicatorParent);
+                               _dropIndicator.x = 0;
+                               _dropIndicator.y = pt2.y - 1;
+                       }
+                       else {
+                               pt0 = new Point(item.x, 0);
+                               pt1 = PointUtils.localToGlobal(pt0, 
item.parent);
+                               pt2 = PointUtils.globalToLocal(pt1, 
indicatorParent);
+                               _dropIndicator.x = pt2.x - 1;
+                               _dropIndicator.y = 0;
+                       }
+               }
+
+               COMPILE::JS
+               private function displayDropIndicator(item:IUIBase, 
isEndOfList:Boolean=false):void
+               {
+                       var pt:Point = PointUtils.localToGlobal(new Point(0,0), 
item);
+                       pt = PointUtils.globalToLocal(pt,indicatorParent);
+                       if (dropDirection == "horizontal") {
+                               _dropIndicator.x = 0;
+                               _dropIndicator.y = pt.y + (isEndOfList ? 
item.height : 0);
+                       } else {
+                               _dropIndicator.x = pt.x + (isEndOfList ? 
item.width : 0);
+                               _dropIndicator.y = 0;
+                       }
+               }
+       }
+}

Reply via email to