private final class DefaultDragAndDropEventHandler implements
NativePreviewHandler {
@Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
NativeEvent nativeEvent = event.getNativeEvent();
int typeInt = event.getTypeInt();
if (typeInt == Event.ONKEYDOWN) {
int keyCode = event.getNativeEvent().getKeyCode();
if (keyCode == KeyCodes.KEY_ESCAPE) {
// end drag if ESC is hit
interruptDrag();
event.cancel();
event.getNativeEvent().preventDefault();
}
// no use for handling for any key down event
return;
}
currentDrag.setCurrentGwtEvent(nativeEvent);
updateDragImagePosition();
Node targetNode = Node.as(nativeEvent.getEventTarget());
Element targetElement;
if (Element.is(targetNode)) {
targetElement = Element.as(targetNode);
} else {
targetElement = targetNode.getParentElement();
}
if (Util.isTouchEvent(nativeEvent) || dragElement != null) {
// to detect the "real" target, hide dragelement temporary and
// use elementFromPoint
String display = dragElement.getStyle().getDisplay();
dragElement.getStyle().setDisplay(Display.NONE);
try {
int x = Util.getTouchOrMouseClientX(nativeEvent);
int y = Util.getTouchOrMouseClientY(nativeEvent);
// Util.browserDebugger();
targetElement = Util.getElementFromPoint(x, y);
if (targetElement == null) {
// ApplicationConnection.getConsole().log(
// "Event on dragImage, ignored");
event.cancel();
nativeEvent.stopPropagation();
return;
} else {
// ApplicationConnection.getConsole().log(
// "Event on dragImage, target changed");
// special handling for events over dragImage
// pretty much all events are mousemove althout below
// kind of happens mouseover
switch (typeInt) {
case Event.ONMOUSEOVER:
case Event.ONMOUSEOUT:
// ApplicationConnection
// .getConsole()
// .log(
// "IGNORING proxy image event, fired because of hack or not significant");
return;
case Event.ONMOUSEMOVE:
case Event.ONTOUCHMOVE:
VDropHandler findDragTarget = findDragTarget(targetElement);
if (findDragTarget != currentDropHandler) {
// dragleave on old
if (currentDropHandler != null) {
currentDropHandler.dragLeave(currentDrag);
currentDrag.getDropDetails().clear();
serverCallback = null;
}
// dragenter on new
currentDropHandler = findDragTarget;
if (findDragTarget != null) {
// ApplicationConnection.getConsole().log(
// "DropHandler now"
// + currentDropHandler
// .getPaintable());
}
if (currentDropHandler != null) {
currentDrag.setElementOver(targetElement);
currentDropHandler.dragEnter(currentDrag);
}
} else if (findDragTarget != null) {
currentDrag.setElementOver(targetElement);
currentDropHandler.dragOver(currentDrag);
}
// prevent text selection on IE
nativeEvent.preventDefault();
return;
default:
// just update element over and let the actual
// handling code do the thing
// ApplicationConnection.getConsole().log(
// "Target just modified on "
// + event.getType());
currentDrag.setElementOver(targetElement);
break;
}
}
} catch (RuntimeException e) {
// ApplicationConnection.getConsole().log(
// "ERROR during elementFromPoint hack.");
throw e;
} finally {
dragElement.getStyle().setProperty("display", display);
}
}
switch (typeInt) {
case Event.ONMOUSEOVER:
VDropHandler target = findDragTarget(targetElement);
if (target != null && target != currentDropHandler) {
if (currentDropHandler != null) {
currentDropHandler.dragLeave(currentDrag);
currentDrag.getDropDetails().clear();
}
currentDropHandler = target;
// ApplicationConnection.getConsole().log(
// "DropHandler now"
// + currentDropHandler.getPaintable());
currentDrag.setElementOver(targetElement);
target.dragEnter(currentDrag);
} else if (target == null && currentDropHandler != null) {
// ApplicationConnection.getConsole().log("Invalid state!?");
currentDropHandler.dragLeave(currentDrag);
currentDrag.getDropDetails().clear();
currentDropHandler = null;
}
break;
case Event.ONMOUSEOUT:
Element relatedTarget = Element.as(nativeEvent
.getRelatedEventTarget());
VDropHandler newDragHanler = findDragTarget(relatedTarget);
if (dragElement != null
&& dragElement.isOrHasChild(relatedTarget)) {
// ApplicationConnection.getConsole().log(
// "Mouse out of dragImage, ignored");
return;
}
if (currentDropHandler != null
&& currentDropHandler != newDragHanler) {
currentDropHandler.dragLeave(currentDrag);
currentDrag.getDropDetails().clear();
currentDropHandler = null;
serverCallback = null;
}
break;
case Event.ONMOUSEMOVE:
case Event.ONTOUCHMOVE:
if (currentDropHandler != null) {
currentDrag.setElementOver(targetElement);
currentDropHandler.dragOver(currentDrag);
}
nativeEvent.preventDefault();
break;
case Event.ONTOUCHEND:
/* Avoid simulated event on drag end */