All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.vectomatic.dnd.DropPanel Maven / Gradle / Ivy

There is a newer version: 0.3.9
Show newest version
/**********************************************
 * 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);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy