org.vectomatic.dnd.DropPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lib-gwt-file Show documentation
Show all versions of lib-gwt-file Show documentation
A GWT encapsulation of the W3C File API
/**********************************************
* Copyright (C) 2011 Lukas laag
* This file is part of lib-gwt-file.
*
* lib-gwt-file is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lib-gwt-file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with lib-gwt-file. If not, see http://www.gnu.org/licenses/
**********************************************/
package org.vectomatic.dnd;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Node;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.DragEnterEvent;
import com.google.gwt.event.dom.client.DragEnterHandler;
import com.google.gwt.event.dom.client.DragLeaveEvent;
import com.google.gwt.event.dom.client.DragLeaveHandler;
import com.google.gwt.event.dom.client.DragOverEvent;
import com.google.gwt.event.dom.client.DragOverHandler;
import com.google.gwt.event.dom.client.DropEvent;
import com.google.gwt.event.dom.client.DropHandler;
import com.google.gwt.event.dom.client.HasDragEnterHandlers;
import com.google.gwt.event.dom.client.HasDragLeaveHandlers;
import com.google.gwt.event.dom.client.HasDragOverHandlers;
import com.google.gwt.event.dom.client.HasDropHandlers;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.ui.SimplePanel;
/**
* A widget which accepts file drag and drop.
* Note: users must add a handler for ALL four main
* events (dragenter, dragleave, dragover and drop) to prevent
* the default browser behavior from applying, otherwise dropping
* will result in the browser opening a new page with the dropped
* resource.
* @author laaglu
*/
public class DropPanel extends SimplePanel implements HasDropHandlers, HasDragEnterHandlers, HasDragLeaveHandlers, HasDragOverHandlers {
/**
* The event bus shared by all drop panels
*/
static protected EventBus eventBus;
/**
* Returns the event bus shared by all drop panels
* @return the event bus shared by all drop panels
*/
public static EventBus getEventBus() {
if (eventBus == null) {
eventBus = new SimpleEventBus();
}
return eventBus;
}
/**
* Sets the event bus shared by all drop panels
* @param eventBus the event bus shared by all drop panels
*/
public static void setEventBus(EventBus eventBus) {
DropPanel.eventBus = eventBus;
}
/**
* Constructor. The size of the widget should be set using CSS.
*/
public DropPanel() {
super();
setup(getElement());
}
private final native void setup(Element elem) /*-{
var x = this;
var handler = function(evt) {
[email protected]::dispatch(Lcom/google/gwt/dom/client/NativeEvent;)(evt);
};
elem.addEventListener("dragenter", handler, false);
elem.addEventListener("dragleave", handler, false);
elem.addEventListener("dragover", handler, false);
elem.addEventListener("drop", handler, false);
}-*/;
public void fireEvent(GwtEvent> event) {
revive(event);
getEventBus().fireEventFromSource(event, this);
}
/**
* Revive the event. GWT does it by taking advantage of the
* fact that HandlerManager has package access to GwtEvent.
* Here we use a JSNI call to bypass scope restrictions
*/
private static final native void revive(GwtEvent> event) /*-{
[email protected]::revive()();
}-*/;
/**
* Dispatches the specified event to this node
* event handlers
* @param event The event to dispatch
*/
public void dispatch(NativeEvent event) {
// dragenter and dragleave deserve special treatment
// to solve issues described in:
// http://www.quirksmode.org/js/events_mouse.html
if ("dragenter".equals(event.getType())
|| "dragleave".equals(event.getType())) {
if (isChildOf((Node)event.getCurrentEventTarget().cast(), (Node)event.getRelatedEventTarget().cast())) {
return;
}
}
// This call wraps the native event into a DomEvent
// and invokes fireEvent
DomEvent.fireNativeEvent(event, this, (Element)event.getCurrentEventTarget().cast());
}
/**
* Tests if a node is part of a DOM subtree.
* @param root
* The subtree root
* @param node
* The node to be tested
* @return
* True if the node is part of the subtree, false otherwise
*/
protected native boolean isChildOf(Node root, Node node) /*-{
while (node != null && node != root && node.nodeName != 'BODY') {
node= node.parentNode
}
if (node === root) {
return true;
}
return false;
}-*/;
@Override
public HandlerRegistration addDropHandler(DropHandler handler) {
return getEventBus().addHandlerToSource(DropEvent.getType(), this, handler);
}
@Override
public HandlerRegistration addDragLeaveHandler(DragLeaveHandler handler) {
return getEventBus().addHandlerToSource(DragLeaveEvent.getType(), this, handler);
}
@Override
public HandlerRegistration addDragEnterHandler(DragEnterHandler handler) {
return getEventBus().addHandlerToSource(DragEnterEvent.getType(), this, handler);
}
@Override
public HandlerRegistration addDragOverHandler(DragOverHandler handler) {
return getEventBus().addHandlerToSource(DragOverEvent.getType(), this, handler);
}
}