You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2020/10/25 00:34:13 UTC
[royale-asjs] 05/05: Added a new (WIP) SimpleDraggableController,
supported more variants with the regular DragDrop beads (light code
addition).
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 <gr...@gmail.com>
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;
+ }
+ }
}