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

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit e637fdcbef6def1daaefaa7f937ea4220d0601a0
Author: greg-dove <[email protected]>
AuthorDate: Sun Oct 25 13:33:46 2020 +1300

    Added a new (WIP) SimpleDraggableController, supported more variants with 
the regular DragDrop beads (light code addition).
---
 .../DragDrop/src/main/royale/DragDropClasses.as    |   2 +
 .../html/beads/SingleSelectionDragSourceBead.as    |  46 ++++-
 .../html/beads/controllers/DragMouseController.as  |  50 ++++-
 ...eController.as => SimpleDraggableController.as} | 206 ++++++++++++---------
 4 files changed, 212 insertions(+), 92 deletions(-)

diff --git a/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as 
b/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as
index 54194db..4b894a3 100644
--- a/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as
+++ b/frameworks/projects/DragDrop/src/main/royale/DragDropClasses.as
@@ -52,6 +52,8 @@ internal class DragDropClasses
        
        import 
org.apache.royale.html.beads.DragDropListItemRendererInitializer; 
DragDropListItemRendererInitializer;
 
+       import 
org.apache.royale.html.beads.controllers.SimpleDraggableController; 
SimpleDraggableController;
+
 }
 
 }
diff --git 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SingleSelectionDragSourceBead.as
 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SingleSelectionDragSourceBead.as
index ec2dc2a..32cc175 100644
--- 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SingleSelectionDragSourceBead.as
+++ 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/SingleSelectionDragSourceBead.as
@@ -30,6 +30,7 @@ package org.apache.royale.html.beads
        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.html.beads.controllers.DragMouseController;
        import org.apache.royale.utils.getParentOrSelfByType;
 
@@ -142,14 +143,57 @@ package org.apache.royale.html.beads
                        _dragType = value;
                }
 
+               private var _approveDragStart:Function;
+               /**
+                * Provides the ability to approve (or prevent) a mouseDown 
event being considered
+                * as the start of a drag sequence. This can be useful for 
renderers with some controls
+                * that must remain interactive, so that dragging is only 
supported by other parts of the renderer.
+                * The function should return true for the mouseDown event to 
be approved as the possible start
+                * of a drag sequence
+                *
+                * @param value a function that takes a MouseEvent as a 
parameter and returns a Boolean value that
+                * pre-approves a mouseDown event (or not)
+                */
+               public function set approveDragStart(value:Function):void{
+                       if (_dragController) {
+                               _dragController.approveDragStart=value
+                       } else {
+                               _approveDragStart = value;
+                       }
+               }
+               public function get approveDragStart():Function{
+                       return _dragController? 
_dragController.approveDragStart :_approveDragStart;
+               }
+
+               private var _explicitTopmostDispatcher:IEventDispatcher;
+               /**
+                * Provides the ability to specify a non-default 
topMostEventDispatcher.
+                * A Basic Royale application looks on the document.body tag 
for an associated Royale EventDispatcher instance,
+                * and the default behaviour is to consider that to be valid.
+                * Other Application types may not be associated with the body 
tag, so this provides a way to explicitly specify
+                * the top level instance.
+                *
+                */
+               public function set 
explicitTopmostDispatcher(value:IEventDispatcher):void{
+                       if (_dragController) {
+                               _dragController.topMostDispatcher = value;
+                               _explicitTopmostDispatcher = null;
+                       }
+                       else _explicitTopmostDispatcher = value;
+               }
+               public function get 
explicitTopmostDispatcher():IEventDispatcher{
+                       return _dragController? 
_dragController.topMostDispatcher :_explicitTopmostDispatcher;
+               }
+
                /**
                 * @private
                 */
                public function set strand(value:IStrand):void
                {
                        _strand = value;
-
                        _dragController = new DragMouseController();
+                       _dragController.topMostDispatcher = 
_explicitTopmostDispatcher;
+                       _dragController.approveDragStart = _approveDragStart;
                        _strand.addBead(_dragController);
 
                        _dragController.addEventListener(DragEvent.DRAG_START, 
handleDragStart);
diff --git 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
index 5fd7222..e3da127 100644
--- 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
+++ 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
@@ -220,19 +220,52 @@ package org.apache.royale.html.beads.controllers
 
         private var host:IPopUpHost;
 
+        private var _approveDragStart:Function;
+        /**
+         * Provides the ability to approve (or prevent) a mouseDown event 
being considered
+         * as the start of a drag sequence. This can be useful for renderers 
with some controls
+         * that must remain interactive, so that dragging is only supported by 
other parts of the renderer.
+         * The function should return true for the mouseDown event to be 
approved as the possible start
+         * of a drag sequence
+         *
+         * @param value a function that takes a MouseEvent as a parameter, its 
boolean return value pre-approves a mouseDown event (or not)
+         */
+        public function set approveDragStart(value:Function):void{
+            _approveDragStart = value;
+        }
+        public function get approveDragStart():Function{
+            return _approveDragStart;
+        }
+
+        private var _topMostDispatcher:IEventDispatcher;
         /**
-         *  @private
          *  @royaleignorecoercion org.apache.royale.core.IUIBase
          */
+        public function get topMostDispatcher():IEventDispatcher{
+            if (_topMostDispatcher) return _topMostDispatcher;
+            if (_strand) _topMostDispatcher = (_strand as 
IUIBase).topMostEventDispatcher;
+            return _topMostDispatcher;
+        }
+        public function set topMostDispatcher(value:IEventDispatcher):void{
+            _topMostDispatcher = value;
+        }
+
+        private var _listeningDispatcher:IEventDispatcher;
+        /**
+         *  @private
+         */
         private function dragMouseDownHandler(event:MouseEvent):void
         {
+            if (_approveDragStart && !_approveDragStart(event)) return;
 //            trace("DRAG-MOUSE: dragMouseDown");
-            (_strand as 
IUIBase).topMostEventDispatcher.addEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
-            (_strand as 
IUIBase).topMostEventDispatcher.addEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
+            var dispatcher:IEventDispatcher = topMostDispatcher;
+            dispatcher.addEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
+            dispatcher.addEventListener(MouseEvent.CLICK, dragMouseUpHandler);
             COMPILE::SWF
             {
-                (_strand as 
IUIBase).topMostEventDispatcher.addEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
+                dispatcher.addEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
             }
+            _listeningDispatcher = dispatcher;
             /**
              * In browser, we need to listen to window to get mouseup events 
outside the window
              */
@@ -374,13 +407,14 @@ package org.apache.royale.html.beads.controllers
             DragEvent.dragSource = null;
             DragEvent.dragInitiator = null;
             dragImage = null;
-
-            (_strand as 
IUIBase).topMostEventDispatcher.removeEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
-            (_strand as 
IUIBase).topMostEventDispatcher.removeEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
+            var dispatcher:IEventDispatcher = _listeningDispatcher;
+            _listeningDispatcher = null;
+            dispatcher.removeEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
+            dispatcher.removeEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
 
             COMPILE::SWF
             {
-                (_strand as 
IUIBase).topMostEventDispatcher.removeEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
+                dispatcher.removeEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
             }
             
             COMPILE::JS
diff --git 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/SimpleDraggableController.as
similarity index 65%
copy from 
frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
copy to 
frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/SimpleDraggableController.as
index 5fd7222..a6316e4 100644
--- 
a/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/DragMouseController.as
+++ 
b/frameworks/projects/DragDrop/src/main/royale/org/apache/royale/html/beads/controllers/SimpleDraggableController.as
@@ -18,22 +18,22 @@
 
////////////////////////////////////////////////////////////////////////////////
 package org.apache.royale.html.beads.controllers
 {
-       COMPILE::SWF {
-       import flash.display.InteractiveObject;
-       import flash.display.DisplayObjectContainer;
+//@todo refactor topMostDispatcher stuff similar to elsewhere
+
+    COMPILE::SWF {
+        import flash.display.InteractiveObject;
+        import flash.display.DisplayObjectContainer;
        }
 
     COMPILE::JS
     {
         import org.apache.royale.events.utils.MouseEventConverter;
+        import org.apache.royale.core.WrappedHTMLElement;
     }
 
        import org.apache.royale.core.IBead;
-       import org.apache.royale.core.IDragInitiator;
-       import org.apache.royale.core.IPopUpHost;
        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.EventDispatcher;
        import org.apache.royale.events.IEventDispatcher;
@@ -41,7 +41,9 @@ package org.apache.royale.html.beads.controllers
        import org.apache.royale.geom.Point;
        import org.apache.royale.utils.PointUtils;
        import org.apache.royale.utils.UIUtils;
-       import org.apache.royale.css2.Cursors;
+    import org.apache.royale.utils.DisplayUtils;
+    import org.apache.royale.geom.Rectangle;
+
 
     /**
      *  Indicates that a drag/drop operation is starting.
@@ -86,7 +88,7 @@ package org.apache.royale.html.beads.controllers
         *  @playerversion AIR 2.6
         *  @productversion Royale 0.8
         */
-       public class DragMouseController extends EventDispatcher implements 
IBead
+       public class SimpleDraggableController extends EventDispatcher 
implements IBead
        {
         /**
          *  Whether there is a drag operation
@@ -101,41 +103,7 @@ package org.apache.royale.html.beads.controllers
          */
         public static var dragging:Boolean = false;
 
-        /**
-         *  The drag image.
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10.2
-         *  @playerversion AIR 2.6
-         *  @productversion Royale 0.8
-         * 
-         *  @royalesuppresspublicvarwarning
-         */
-        public static var dragImage:IUIBase;
 
-        /**
-         *  The offset of the drag image.
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10.2
-         *  @playerversion AIR 2.6
-         *  @productversion Royale 0.8
-         * 
-         *  @royalesuppresspublicvarwarning
-         */
-        public static var dragImageOffsetX:Number = 0;
-
-        /**
-         *  The offset of the drag image.
-         *
-         *  @langversion 3.0
-         *  @playerversion Flash 10.2
-         *  @playerversion AIR 2.6
-         *  @productversion Royale 0.8
-         * 
-         *  @royalesuppresspublicvarwarning
-         */
-        public static var dragImageOffsetY:Number = 0;
 
         /**
          *  The default movement in x and or y that
@@ -158,7 +126,7 @@ package org.apache.royale.html.beads.controllers
                 *  @playerversion AIR 2.6
                 *  @productversion Royale 0.8
                 */
-               public function DragMouseController()
+               public function SimpleDraggableController()
                {
             threshold = defaultThreshold;
                }
@@ -182,6 +150,7 @@ package org.apache.royale.html.beads.controllers
         {
             _threshold = value;
         }
+
         
                private var _strand:IStrand;
 
@@ -207,7 +176,7 @@ package org.apache.royale.html.beads.controllers
 
             IEventDispatcher(_strand).addEventListener(MouseEvent.MOUSE_DOWN, 
dragMouseDownHandler);
 
-            DragMouseController.instanceNumber += 100;
+            instanceNumber += 100;
                }
 
                public function get strand():IStrand
@@ -215,10 +184,42 @@ package org.apache.royale.html.beads.controllers
                        return _strand;
                }
 
+        private var _parentDraggable:IUIBase;
+
         private var mouseDownX:Number;
         private var mouseDownY:Number;
+        private var lastPositionX:Number;
+        private var lastPositionY:Number;
+
+        private var _approveDragStart:Function;
+        /**
+         * Provides the ability to approve (or prevent) a mouseDown event 
being considered
+         * as the start of a drag sequence.
+         *
+         * @param value a function that takes a MouseEvent as a parameter, its 
boolean return value pre-approves a mouseDown event (or not)
+         */
+        public function set approveDragStart(value:Function):void{
+            _approveDragStart = value;
+        }
+        public function get approveDragStart():Function{
+            return _approveDragStart;
+        }
+
+
+        private var _topMostDispatcher:IEventDispatcher;
+        /**
+         *  @royaleignorecoercion org.apache.royale.core.IUIBase
+         */
+        public function get topMostDispatcher():IEventDispatcher{
+            if (_topMostDispatcher) return _topMostDispatcher;
+            if (_strand) _topMostDispatcher = (_strand as 
IUIBase).topMostEventDispatcher;
+            return _topMostDispatcher;
+        }
+        public function set topMostDispatcher(value:IEventDispatcher):void{
+            _topMostDispatcher = value;
+        }
 
-        private var host:IPopUpHost;
+        private var _listeningDispatcher:IEventDispatcher;
 
         /**
          *  @private
@@ -227,12 +228,21 @@ package org.apache.royale.html.beads.controllers
         private function dragMouseDownHandler(event:MouseEvent):void
         {
 //            trace("DRAG-MOUSE: dragMouseDown");
-            (_strand as 
IUIBase).topMostEventDispatcher.addEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
-            (_strand as 
IUIBase).topMostEventDispatcher.addEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
+            if (_approveDragStart && !_approveDragStart(event)) return;
+            topMostDispatcher = (_strand as IUIBase).topMostEventDispatcher;
+            if (!topMostDispatcher) {
+                trace('there was a problem finding the topmost 
EventDispatcher');
+                return;
+            }
+
+            topMostDispatcher.addEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
+            topMostDispatcher.addEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
+
             COMPILE::SWF
             {
-                (_strand as 
IUIBase).topMostEventDispatcher.addEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
+                topMostDispatcher.addEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
             }
+
             /**
              * In browser, we need to listen to window to get mouseup events 
outside the window
              */
@@ -240,8 +250,12 @@ package org.apache.royale.html.beads.controllers
             {
                 window.addEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
             }
+
+
             mouseDownX = event.screenX;
             mouseDownY = event.screenY;
+            lastPositionX = event.clientX;
+            lastPositionY = event.clientY;
             event.preventDefault();
         }
 
@@ -251,61 +265,78 @@ package org.apache.royale.html.beads.controllers
          */
         private function dragMouseMoveHandler(event:MouseEvent):void
         {
-            var pt:Point;
             var dragEvent:DragEvent;
-//            trace("DRAG-MOUSE: dragMouseMove");
-
             event.preventDefault();
-
+            var draggable:IUIBase;
             if (!dragging)
             {
-//                trace("DRAG-MOUSE: not dragging anything else");
+
                 if (Math.abs(event.screenX - mouseDownX) > threshold ||
                     Math.abs(event.screenY - mouseDownY) > threshold)
                 {
                     dragEvent = DragEvent.createDragEvent("dragStart", event);
-                                       dragEvent.clientX = mouseDownX;
-                                       dragEvent.clientY = mouseDownY;
+                                       dragEvent.clientX = lastPositionX;
+                                       dragEvent.clientY = lastPositionY;
+
 //                                     trace("DRAG-MOUSE: sending dragStart 
via "+event.target.toString()+" == "+dragImageOffsetX);
                                        COMPILE::SWF {
-                                               dragEvent.relatedObject = 
event.target as InteractiveObject;
+                                               dragEvent.relatedObject = 
_strand as InteractiveObject;
                                        }
                                        COMPILE::JS {
-                                               dragEvent.relatedObject = 
event.target;
+                                               dragEvent.relatedObject = 
_strand;
                                        }
                                        DragEvent.dispatchDragEvent(dragEvent, 
event.target);
                                        dispatchEvent(dragEvent);
 
-                    if (DragEvent.dragSource != null)
+                    var avoid:Boolean;
+                    COMPILE::SWF {
+                        avoid = dragEvent.isDefaultPrevented();
+                    }
+                    COMPILE::JS {
+                        avoid = dragEvent.defaultPrevented;
+                    }
+
+                    if (!avoid)
                     {
                         dragging = true;
-                        host = UIUtils.findPopUpHost(_strand as IUIBase);
-                        if (host == null) return;
-                        host.popUpParent.addElement(dragImage);
-                        pt = PointUtils.globalToLocal(new Point(event.clientX, 
event.clientY), host);
-                        dragImage.x = pt.x + dragImageOffsetX;
-                        dragImage.y = pt.y + dragImageOffsetY;
-                                               (dragImage as UIBase).id = 
"drag_image";
+
+                        var deltaX:Number = event.clientX -lastPositionX;
+                        var deltaY:Number = event.clientY - lastPositionY;
+                        lastPositionX = event.clientX;
+                        lastPositionY = event.clientY;
+                        draggable = parentDraggable;
+
+                        draggable.x = draggable.x + deltaX ;
+                        draggable.y = draggable.y + deltaY ;
+
                                                COMPILE::SWF {
-                                                       (dragImage as 
InteractiveObject).mouseEnabled = false;
-                                                       (dragImage as 
DisplayObjectContainer).mouseChildren = false;
+                                                       (draggable as 
InteractiveObject).mouseEnabled = false;
+                                                       (draggable as 
DisplayObjectContainer).mouseChildren = false;
                                                }
                                                COMPILE::JS {
-                                                       
dragImage.element.style['pointer-events'] = 'none';
-                                                       
dragImage.element.style['position'] = 'absolute';
+                            draggable.element.style['cursor'] = 'move';
+                            draggable.element.style['position'] = 'absolute';
                                                }
                     }
                 }
             }
             else
             {
-               host = UIUtils.findPopUpHost(_strand as IUIBase);
-                if (host == null) return;
 //                trace("DRAG-MOUSE: sending dragMove via " + 
event.target.toString()+" == "+dragImageOffsetX);
                 dragEvent = DragEvent.createDragEvent("dragMove", event);
-                pt = PointUtils.globalToLocal(new Point(event.clientX, 
event.clientY), host);
-                dragImage.x = pt.x + dragImageOffsetX;
-                dragImage.y = pt.y + dragImageOffsetY;
+                draggable = parentDraggable;
+
+                deltaX =  event.clientX - lastPositionX;
+                deltaY = event.clientY - lastPositionY;
+                lastPositionX = event.clientX;
+                lastPositionY = event.clientY;
+
+                //@todo support some constraint approach
+
+                draggable.x = draggable.x + deltaX;
+                draggable.y = draggable.y + deltaY;
+
+
                                COMPILE::SWF {
                                        dragEvent.relatedObject = event.target 
as InteractiveObject;
                                }
@@ -325,11 +356,9 @@ package org.apache.royale.html.beads.controllers
             //trace("DRAG-MOUSE: dragMouseUp");
             var dragEvent:DragEvent;
 
-            host = UIUtils.findPopUpHost(_strand as IUIBase);
-            if (dragImage && host) {
-               host.popUpParent.removeElement(dragImage);
-            }
+       //     host = UIUtils.findPopUpHost(_strand as IUIBase);
 
+            var draggable:IUIBase;
             if (dragging && event.target)
             {
                 //trace("DRAG-MOUSE: sending dragEnd via: 
"+event.target.toString());
@@ -373,22 +402,33 @@ package org.apache.royale.html.beads.controllers
             dragging = false;
             DragEvent.dragSource = null;
             DragEvent.dragInitiator = null;
-            dragImage = null;
 
-            (_strand as 
IUIBase).topMostEventDispatcher.removeEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
-            (_strand as 
IUIBase).topMostEventDispatcher.removeEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
+            topMostDispatcher.removeEventListener(MouseEvent.MOUSE_MOVE, 
dragMouseMoveHandler);
+            topMostDispatcher.removeEventListener(MouseEvent.CLICK, 
dragMouseUpHandler);
 
             COMPILE::SWF
             {
-                (_strand as 
IUIBase).topMostEventDispatcher.removeEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
+                topMostDispatcher.removeEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
             }
             
             COMPILE::JS
             {
                 window.removeEventListener(MouseEvent.MOUSE_UP, 
dragMouseUpHandler);
+                parentDraggable.element.style['cursor'] = 'auto';
             }
 
         }
 
-       }
+        /**
+         * allows explicitly setting a parent that can be dragged by this bead 
being
+         * active on one of its children (e.g. use case: panel draggable from 
its header)
+         */
+        public function get parentDraggable():IUIBase {
+            return _parentDraggable || _strand as IUIBase;
+        }
+
+        public function set parentDraggable(value:IUIBase):void {
+            _parentDraggable = value;
+        }
+    }
 }

Reply via email to