Skip to content

Commit

Permalink
Add drag-drop support to interactive objects. (#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
linuxerwang committed Jun 23, 2023
1 parent 4c814c7 commit 419b86f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 33 deletions.
20 changes: 20 additions & 0 deletions lib/src/display/interactive_object.dart
Expand Up @@ -94,6 +94,12 @@ abstract class InteractiveObject extends DisplayObject {
EventStreamProvider<MouseEvent>(MouseEvent.MOUSE_WHEEL);
static const EventStreamProvider<MouseEvent> mouseContextMenu =
EventStreamProvider<MouseEvent>(MouseEvent.CONTEXT_MENU);
static const EventStreamProvider<MouseEvent> dragEnter =
EventStreamProvider<MouseEvent>(MouseEvent.DRAG_ENTER);
static const EventStreamProvider<MouseEvent> dragLeave =
EventStreamProvider<MouseEvent>(MouseEvent.DRAG_LEAVE);
static const EventStreamProvider<MouseEvent> drop =
EventStreamProvider<MouseEvent>(MouseEvent.DROP);

/// Dispatched when the user moves a pointing device away from an
/// InteractiveObject instance.
Expand Down Expand Up @@ -282,6 +288,20 @@ abstract class InteractiveObject extends DisplayObject {
EventStream<MouseEvent> get onMouseContextMenu =>
InteractiveObject.mouseContextMenu.forTarget(this);

/// Dispatched when a HTML element was dragged entering an InteractiveObject
/// instance.
EventStream<MouseEvent> get onDragEnter =>
InteractiveObject.dragEnter.forTarget(this);

/// Dispatched when a HTML element was dragged leaving an InteractiveObject
/// instance.
EventStream<MouseEvent> get onDragLeave =>
InteractiveObject.dragLeave.forTarget(this);

/// Dispatched when a HTML element was dropped in an InteractiveObject
/// instance.
EventStream<MouseEvent> get onDrop => InteractiveObject.drop.forTarget(this);

// touch events

static const EventStreamProvider<TouchEvent> touchOutEvent =
Expand Down
84 changes: 53 additions & 31 deletions lib/src/display/stage.dart
Expand Up @@ -138,28 +138,6 @@ class Stage extends DisplayObjectContainer {

EventStream<Event> get onMouseLeave => Stage.mouseLeaveEvent.forTarget(this);

/// Dispatched when an external HTML element was dragged entering the stage
/// canvas.
EventStream<MouseEvent> get onDragEnter =>
const EventStreamProvider<MouseEvent>(MouseEvent.DRAG_ENTER)
.forTarget(this);

/// Dispatched when an external HTML element was dragged leaving the stage
/// canvas.
EventStream<MouseEvent> get onDragLeave =>
const EventStreamProvider<MouseEvent>(MouseEvent.DRAG_LEAVE)
.forTarget(this);

/// Dispatched when an external HTML element was dragged over the stage
/// canvas.
EventStream<MouseEvent> get onDragOver =>
const EventStreamProvider<MouseEvent>(MouseEvent.DRAG_OVER)
.forTarget(this);

/// Dispatched when an external HTML element was dropped on stage canvas.
EventStream<MouseEvent> get onDrop =>
const EventStreamProvider<MouseEvent>(MouseEvent.DROP).forTarget(this);

//----------------------------------------------------------------------------

Stage(CanvasElement canvas,
Expand Down Expand Up @@ -661,6 +639,11 @@ class Stage extends DisplayObjectContainer {
dispatchEvent(Event(Event.MOUSE_LEAVE));
}

var isDnD = event.type == 'dragenter' ||
event.type == 'dragleave' ||
event.type == 'dragover' ||
event.type == 'drop';

//-----------------------------------------------------------------
// MOUSE_OUT, ROLL_OUT, ROLL_OVER, MOUSE_OVER

Expand Down Expand Up @@ -702,7 +685,25 @@ class Stage extends DisplayObjectContainer {
0.0,
0.0,
mouseButton.buttonDown,
0));
0,
null));
if (isDnD) {
oldTarget.dispatchEvent(MouseEvent(
MouseEvent.DRAG_LEAVE,
true,
localPoint.x,
localPoint.y,
stagePoint.x,
stagePoint.y,
event.altKey,
event.ctrlKey,
event.shiftKey,
0.0,
0.0,
mouseButton.buttonDown,
0,
event.dataTransfer));
}
}

for (var i = 0; i < oldTargetList.length - commonCount; i++) {
Expand All @@ -721,7 +722,8 @@ class Stage extends DisplayObjectContainer {
0.0,
0.0,
mouseButton.buttonDown,
0));
0,
null));
}

for (var i = newTargetList.length - commonCount - 1; i >= 0; i--) {
Expand All @@ -740,7 +742,8 @@ class Stage extends DisplayObjectContainer {
0.0,
0.0,
mouseButton.buttonDown,
0));
0,
null));
}

if (newTarget != null) {
Expand All @@ -758,7 +761,25 @@ class Stage extends DisplayObjectContainer {
0.0,
0.0,
mouseButton.buttonDown,
0));
0,
null));
if (isDnD) {
newTarget.dispatchEvent(MouseEvent(
MouseEvent.DRAG_ENTER,
true,
localPoint.x,
localPoint.y,
stagePoint.x,
stagePoint.y,
event.altKey,
event.ctrlKey,
event.shiftKey,
0.0,
0.0,
mouseButton.buttonDown,
0,
event.dataTransfer));
}
}

_mouseTarget = newTarget;
Expand Down Expand Up @@ -800,8 +821,6 @@ class Stage extends DisplayObjectContainer {
mouseEventType = MouseEvent.DRAG_ENTER;
} else if (event.type == 'dragleave') {
mouseEventType = MouseEvent.DRAG_LEAVE;
} else if (event.type == 'dragover') {
mouseEventType = MouseEvent.DRAG_OVER;
} else if (event.type == 'drop') {
mouseEventType = MouseEvent.DROP;
}
Expand All @@ -823,7 +842,8 @@ class Stage extends DisplayObjectContainer {
0.0,
0.0,
mouseButton.buttonDown,
mouseButton.clickCount));
mouseButton.clickCount,
isDnD ? event.dataTransfer : null));

if (isClick) {
mouseEventType = isDoubleClick && target.doubleClickEnabled
Expand All @@ -843,7 +863,8 @@ class Stage extends DisplayObjectContainer {
0.0,
0.0,
mouseButton.buttonDown,
0));
0,
null));
}
}
}
Expand Down Expand Up @@ -873,7 +894,8 @@ class Stage extends DisplayObjectContainer {
event.deltaX,
event.deltaY,
false,
0);
0,
null);

target.dispatchEvent(mouseEvent);

Expand Down
1 change: 1 addition & 0 deletions lib/src/events.dart
Expand Up @@ -8,6 +8,7 @@
library stagexl.events;

import 'dart:async';
import 'dart:html';

part 'events/broadcast_event.dart';
part 'events/event.dart';
Expand Down
6 changes: 4 additions & 2 deletions lib/src/events/mouse_event.dart
Expand Up @@ -36,7 +36,6 @@ class MouseEvent extends InputEvent {

static const String DRAG_ENTER = 'dragEnter';
static const String DRAG_LEAVE = 'dragLeave';
static const String DRAG_OVER = 'dragOver';
static const String DROP = 'drop';

//---------------------------------------------------------------------------
Expand Down Expand Up @@ -73,6 +72,8 @@ class MouseEvent extends InputEvent {
final int clickCount;

final DataTransfer? dataTransfer;

/// Creates a new [MouseEvent].
MouseEvent(
Expand All @@ -88,5 +89,6 @@ class MouseEvent extends InputEvent {
this.deltaX,
this.deltaY,
this.buttonDown,
this.clickCount);
this.clickCount,
this.dataTransfer);
}

0 comments on commit 419b86f

Please sign in to comment.