package com.gwt.mvp.client.dnd;
// import com.allen_sauer.gwt.log.client.Log;
/**
* @author jguibert
* @author ibouakl
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.event.dom.client.HasMouseDownHandlers;
import com.google.gwt.event.dom.client.HasMouseUpHandlers;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
public class DDPanel extends FocusPanel implements DDManager {
private boolean dragging = false;
private Clipboard source = null;
private DragCursor cursor;
private HandlerRegistration hEventPere = null;
private Map<String, List<HandlerRegistration>> handlers = new HashMap<String, List<HandlerRegistration>>();
public DDPanel() {
super();
super.addMouseMoveHandler(new MouseMoveHandler() {
@Override
public void onMouseMove(MouseMoveEvent event) {
if (dragging) {
cursor.onMouseMove(event);
event.preventDefault();
} else {
destroyCursor();
}
}
});
super.addMouseUpHandler(new MouseUpHandler() {
@Override
public void onMouseUp(MouseUpEvent event) {
if (dragging) {
dragging = false;
cursor.onMouseOut();
event.preventDefault();
} else {
destroyCursor();
}
}
});
super.addMouseOutHandler(new MouseOutHandler() {
@Override
public void onMouseOut(MouseOutEvent event) {
if (dragging) {
dragging = false;
cursor.onMouseOut();
event.preventDefault();
} else {
destroyCursor();
}
}
});
}
public void expand() {
setSize(Window.getClientWidth() - getAbsoluteLeft() + "px", Window.getClientHeight() - getAbsoluteTop() + "px");
}
@Override
public HandlerRegistration registerDrag(final HasMouseDownHandlers handle, final Widget description, final Clipboard clipboard, final String groupName) {
HandlerRegistration registration = handle.addMouseDownHandler(new MouseDownHandler() {
@Override
public void onMouseDown(MouseDownEvent event) {
if (!dragging) {
source = clipboard;
dragging = true;
cursor = new DragCursor(description, event);
cursor.onMouseOver(event);
cursor.onMouseOut();
cursor.onMouseOver(event);
event.preventDefault();
}
}
});
if (groupName != null) {
register(registration, groupName);
}
return registration;
}
@Override
public HandlerRegistration registerDrop(final HasMouseUpHandlers handle, final Clipboard clipboard, final String groupName) {
HandlerRegistration registration = handle.addMouseUpHandler(new MouseUpHandler() {
@Override
public void onMouseUp(MouseUpEvent event) {
if (dragging) {
dragging = false;
destroyCursor();
fireEvent(clipboard);
event.preventDefault();
}
}
});
if (groupName != null) {
register(registration, groupName);
}
return registration;
}
@Override
public void clearRegistration(final String groupName) {
List<HandlerRegistration> list = handlers.get(groupName);
if (list != null) {
for (HandlerRegistration hr : list) {
hr.removeHandler();
}
handlers.remove(groupName);
}
}
private HandlerRegistration register(final HandlerRegistration handlerRegistration, final String groupName) {
List<HandlerRegistration> list = handlers.get(groupName);
if (list == null) {
list = new ArrayList<HandlerRegistration>();
handlers.put(groupName, list);
}
list.add(handlerRegistration);
return handlerRegistration;
}
/**
* Fire a DragInformation event width memorized data
*/
@SuppressWarnings("unchecked")
private void fireEvent(Clipboard dropTarget) {
if (source != null) {
ValueChangeEvent.fire(this, new DragInformation(source, dropTarget));
source = null;
}
}
/**
* Add a listener on a Drag event used when drop is finished
*
* @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler)
*/
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<DragInformation> handler) {
if (hEventPere != null) {
hEventPere.removeHandler();
}
hEventPere = addHandler(handler, ValueChangeEvent.getType());
return hEventPere;
}
private void destroyCursor() {
if (cursor != null) {
cursor.onMouseOut();
cursor.clear();
cursor = null;
}
}
/**
* Inner class to manage drag cursor
*
* @author jguibert
*/
private class DragCursor {
private PopupPanel tooltip = null;
private int lastX = 0;
private int lastY = 0;
private boolean isShowing = false;
private final int dx = 5;
private final int dy = 10;
/**
* The Constructor of the DragCursor.
*
* @param text The tooltip text. It should not be null.
*/
public DragCursor(Widget content, MouseEvent<?> event) {
super();
tooltip = new PopupPanel();
tooltip.setWidget(content);
RootPanel.get().add(tooltip, event.getClientX(), event.getClientY());
tooltip.setAnimationEnabled(false);
tooltip.setStyleName("DragCursor");
tooltip.hide();
onMouseMove(event);
}
public DragCursor(String html, MouseEvent<?> event) {
this(new HTML(html), event);
}
public void clear() {
isShowing = false;
tooltip.hide();
RootPanel.get().remove(tooltip);
}
final void onMouseMove(MouseEvent<?> event) {
if (isShowing) {
int left = event.getClientX() + Window.getScrollLeft() + dx;
int top = event.getClientY() + Window.getScrollTop() + dy;
if (left != lastX || top != lastY) {
tooltip.setPopupPosition(left, top);
lastX = left;
lastY = top;
}
}
}
void onMouseOver(MouseEvent<?> event) {
if (!isShowing) {
isShowing = true;
onMouseMove(event);
tooltip.show();
DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "move");
}
}
void onMouseOut() {
if (isShowing) {
isShowing = false;
tooltip.hide();
DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "default");
}
}
}
@Override
public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
return null;
}
@Override
public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
// Log.error("try adding addMouseOutHandler");
return null;
}
@Override
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
// Log.error("try adding addMouseUpHandler");
return null;
}
/**
* A hack for a bug in GWT with the scroll location
*/
static native int getScrollTop()/*-{
return $doc.body.scrollTop;
}-*/;
/**
* A hack for a bug in GWT with the scroll location
*/
static native int getScrollLeft()/*-{
return $doc.body.scrollLeft;
}-*/;
}