From: Artur Signell Date: Mon, 1 Feb 2010 12:54:02 +0000 (+0000) Subject: Prefixed client side classes with V X-Git-Tag: 6.7.0.beta1~1988^2~41 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d75f17e5fba724e165b7240e191dc6e7181a3fb4;p=vaadin-framework.git Prefixed client side classes with V svn changeset:11075/svn branch:6.3_dd --- diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragDropPane.java b/src/com/vaadin/terminal/gwt/client/ui/VDragDropPane.java index 3504b8d258..7ebe953733 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragDropPane.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragDropPane.java @@ -15,22 +15,22 @@ import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.ui.dd.AbstractDropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; -import com.vaadin.terminal.gwt.client.ui.dd.DragEvent; -import com.vaadin.terminal.gwt.client.ui.dd.HasDropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.Html5DragEvent; -import com.vaadin.terminal.gwt.client.ui.dd.Transferable; +import com.vaadin.terminal.gwt.client.ui.dd.VAbstractDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.VDragEvent; +import com.vaadin.terminal.gwt.client.ui.dd.VHasDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VHtml5DragEvent; +import com.vaadin.terminal.gwt.client.ui.dd.VTransferable; public class VDragDropPane extends VAbsoluteLayout implements Container, - HasDropHandler { + VHasDropHandler { private String paintableId; /** * DragEvent is stored here in case of HTML5 drag event. */ - private DragEvent vaadinDragEvent; + private VDragEvent vaadinDragEvent; public VDragDropPane() { super(); @@ -40,9 +40,9 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, .getEventTarget(); Paintable paintable = client.getPaintable((Element) eventTarget .cast()); - Transferable transferable = new Transferable(); + VTransferable transferable = new VTransferable(); transferable.setComponent(paintable); - DragEvent drag = DragAndDropManager.get().startDrag( + VDragEvent drag = VDragAndDropManager.get().startDrag( transferable, event.getNativeEvent(), true); Element cloneNode = (Element) ((Widget) paintable).getElement() .cloneNode(true); @@ -90,20 +90,20 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, }-*/; - public boolean html5DragEnter(Html5DragEvent event) { + public boolean html5DragEnter(VHtml5DragEvent event) { ApplicationConnection.getConsole().log("HTML 5 Drag Enter"); - Transferable transferable = new Transferable(); + VTransferable transferable = new VTransferable(); // TODO refine api somehow so that we will now not use the event preview // method provided by manager - vaadinDragEvent = DragAndDropManager.get().startDrag(transferable, + vaadinDragEvent = VDragAndDropManager.get().startDrag(transferable, event, false); event.preventDefault(); event.stopPropagation(); return false; } - public boolean html5DragLeave(Html5DragEvent event) { + public boolean html5DragLeave(VHtml5DragEvent event) { ApplicationConnection.getConsole().log("HTML 5 Drag Leave posponed..."); DeferredCommand.addCommand(new Command() { public void execute() { @@ -123,7 +123,7 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, return false; } - public boolean html5DragOver(Html5DragEvent event) { + public boolean html5DragOver(VHtml5DragEvent event) { ApplicationConnection.getConsole().log("HTML 5 Drag Over"); getDropHandler().dragOver(vaadinDragEvent); // needed to be set for Safari, otherwise drop will not happen @@ -139,9 +139,9 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, return false; } - public boolean html5DragDrop(Html5DragEvent event) { + public boolean html5DragDrop(VHtml5DragEvent event) { ApplicationConnection.getConsole().log("HTML 5 Drag Drop"); - Transferable transferable = vaadinDragEvent.getTransferrable(); + VTransferable transferable = vaadinDragEvent.getTransferrable(); JsArrayString types = event.getTypes(); for (int i = 0; i < types.length(); i++) { @@ -160,7 +160,7 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, transferable.setData("fileContents", fileAsString); } - DragAndDropManager.get().endDrag(); + VDragAndDropManager.get().endDrag(); vaadinDragEvent = null; event.preventDefault(); event.stopPropagation(); @@ -178,11 +178,11 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, } } - private AbstractDropHandler dropHandler; + private VAbstractDropHandler dropHandler; - public AbstractDropHandler getDropHandler() { + public VAbstractDropHandler getDropHandler() { if (dropHandler == null) { - dropHandler = new AbstractDropHandler() { + dropHandler = new VAbstractDropHandler() { @Override public Paintable getPaintable() { @@ -190,13 +190,13 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, } @Override - public void dragLeave(DragEvent drag) { + public void dragLeave(VDragEvent drag) { ApplicationConnection.getConsole().log("DragLeave"); getStyleElement().getStyle().setBackgroundColor("yellow"); } @Override - public boolean drop(DragEvent drag) { + public boolean drop(VDragEvent drag) { ApplicationConnection.getConsole().log( "Drop" + drag.sinceStart()); @@ -226,7 +226,7 @@ public class VDragDropPane extends VAbsoluteLayout implements Container, } @Override - protected void dragAccepted(DragEvent drag) { + protected void dragAccepted(VDragEvent drag) { getStyleElement().getStyle().setBackgroundColor("green"); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 08419ec45b..bef74ff274 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -40,9 +40,9 @@ import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; -import com.vaadin.terminal.gwt.client.ui.dd.DragEvent; -import com.vaadin.terminal.gwt.client.ui.dd.Transferable; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.VDragEvent; +import com.vaadin.terminal.gwt.client.ui.dd.VTransferable; /** * VScrollTable @@ -2499,12 +2499,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { break; case Event.ONMOUSEMOVE: if (mDown && dragmode != 0) { - Transferable transferable = new Transferable(); + VTransferable transferable = new VTransferable(); transferable.setComponent(VScrollTable.this); transferable.setItemId("" + rowKey); // TODO propertyId - DragEvent ev = DragAndDropManager.get() + VDragEvent ev = VDragAndDropManager.get() .startDrag(transferable, event, true); Element cloneNode = (Element) getElement() .cloneNode(true); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java index 948e6705c1..f31e652ffc 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java @@ -27,19 +27,19 @@ import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ValueMap; -import com.vaadin.terminal.gwt.client.ui.dd.AbstractDropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.AcceptCallback; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; -import com.vaadin.terminal.gwt.client.ui.dd.DragEvent; -import com.vaadin.terminal.gwt.client.ui.dd.DropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.HasDropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.Transferable; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager.DragEventType; +import com.vaadin.terminal.gwt.client.ui.dd.VAbstractDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VAcceptCallback; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.VDragEvent; +import com.vaadin.terminal.gwt.client.ui.dd.VDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VHasDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VTransferable; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager.DragEventType; /** * */ -public class VTree extends FlowPanel implements Paintable, HasDropHandler { +public class VTree extends FlowPanel implements Paintable, VHasDropHandler { public static final String CLASSNAME = "v-tree"; @@ -72,7 +72,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { private int dragModes; - private AbstractDropHandler dropHandler; + private VAbstractDropHandler dropHandler; public VTree() { super(); @@ -161,7 +161,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { } - private void updateTreeRelatedTransferData(DragEvent drag) { + private void updateTreeRelatedTransferData(VDragEvent drag) { drag.getEventDetails().put("itemIdOver", currentMouseOverKey); if (currentMouseOverKey != null) { @@ -179,20 +179,20 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { private void updateDropHandler(UIDL childUidl) { if (dropHandler == null) { - dropHandler = new AbstractDropHandler() { + dropHandler = new VAbstractDropHandler() { @Override - public void dragEnter(DragEvent drag) { + public void dragEnter(VDragEvent drag) { updateTreeRelatedTransferData(drag); super.dragEnter(drag); } @Override - protected void dragAccepted(final DragEvent drag) { + protected void dragAccepted(final VDragEvent drag) { } @Override - public void dragOver(final DragEvent currentDrag) { + public void dragOver(final VDragEvent currentDrag) { final Object oldIdOver = currentDrag.getEventDetails().get( "itemIdOver"); final String oldDetail = (String) currentDrag @@ -217,7 +217,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { + detail); updateTreeRelatedTransferData(currentDrag); - AcceptCallback accpectedCb = new AcceptCallback() { + VAcceptCallback accpectedCb = new VAcceptCallback() { public void handleResponse( ValueMap responseData) { if (responseData == null // via client @@ -231,7 +231,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { } }; if (validateOnServer()) { - DragAndDropManager.get().visitServer( + VDragAndDropManager.get().visitServer( DragEventType.OVER, accpectedCb); } else { @@ -253,7 +253,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { } @Override - public void dragLeave(DragEvent drag) { + public void dragLeave(VDragEvent drag) { cleanUp(); } @@ -265,7 +265,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { } @Override - public boolean drop(DragEvent drag) { + public boolean drop(VDragEvent drag) { cleanUp(); return super.drop(drag); } @@ -436,10 +436,10 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { ApplicationConnection.getConsole().log( "TreeNode drag start " + event.getType()); // start actual drag on slight move when mouse is down - Transferable t = new Transferable(); + VTransferable t = new VTransferable(); t.setComponent(VTree.this); t.setItemId(key); - DragEvent drag = DragAndDropManager.get().startDrag(t, + VDragEvent drag = VDragAndDropManager.get().startDrag(t, mouseDownEvent, true); Element node = (Element) nodeCaptionDiv.cloneNode(true); node.getStyle().setOpacity(0.4); @@ -713,7 +713,7 @@ public class VTree extends FlowPanel implements Paintable, HasDropHandler { } } - public DropHandler getDropHandler() { + public VDropHandler getDropHandler() { return dropHandler; } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AbstractDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AbstractDropHandler.java deleted file mode 100644 index 0319655b75..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/AbstractDropHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.vaadin.terminal.gwt.client.Paintable; -import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.ValueMap; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager.DragEventType; - -public abstract class AbstractDropHandler implements DropHandler { - - private boolean serverValidate; - private UIDL criterioUIDL; - - public void updateRules(UIDL uidl) { - serverValidate = uidl.getBooleanAttribute("serverValidate"); - int childCount = uidl.getChildCount(); - for (int i = 0; i < childCount; i++) { - UIDL childUIDL = uidl.getChildUIDL(i); - if (childUIDL.getTag().equals("acceptCriterion")) { - criterioUIDL = childUIDL; - // TODO consider parsing the criteria tree here instead of - // translating uidl during validates() - - } - } - } - - public boolean validateOnServer() { - return serverValidate; - } - - /** - * Default implementation does nothing. - */ - public void dragOver(DragEvent currentDrag) { - - } - - /** - * Default implementation does nothing. - */ - public void dragLeave(DragEvent drag) { - // TODO Auto-generated method stub - - } - - /** - * If transferrable is accepted (either via server visit or client side - * rules) the default implementation calls {@link #dragAccepted(DragEvent)} - * method. - */ - public void dragEnter(final DragEvent drag) { - if (serverValidate) { - DragAndDropManager.get().visitServer(DragEventType.ENTER, - new AcceptCallback() { - public void handleResponse(ValueMap responseData) { - if (responseData.containsKey("accepted")) { - dragAccepted(drag); - } - } - }); - } else if (validates(drag)) { - dragAccepted(drag); - } - } - - abstract protected void dragAccepted(DragEvent drag); - - /** - * Returns true if client side rules are met. - * - * @param drag - * @return - */ - protected boolean validates(DragEvent drag) { - if (criterioUIDL != null) { - String criteriaName = criterioUIDL.getStringAttribute("name"); - AcceptCriteria acceptCriteria = AcceptCriterion.get(criteriaName); - if (acceptCriteria != null) { - // ApplicationConnection.getConsole().log( - // "Criteria : " + acceptCriteria.getClass().getName()); - return acceptCriteria.accept(drag, criterioUIDL); - } - } - return false; - } - - public boolean drop(DragEvent drag) { - if (serverValidate) { - return true; - } else { - return validates(drag); - } - } - - public abstract Paintable getPaintable(); - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCallback.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCallback.java deleted file mode 100644 index 913cda5a76..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCallback.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.vaadin.terminal.gwt.client.ValueMap; - -public interface AcceptCallback { - - /** - * This method is called by {@link DragAndDropManager} if the - * {@link DragEvent} is still active. Developer can update for example drag - * icon or target emphasis based on the information returned from server - * side. If the drag and drop operation ends or the - * {@link AbstractDropHandler} has changed before response arrives, the - * method is never called. - * - * @param responseData - */ - public void handleResponse(ValueMap responseData); - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriteria.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriteria.java deleted file mode 100644 index 8a1081fff3..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriteria.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.vaadin.terminal.gwt.client.UIDL; - -public interface AcceptCriteria { - - public boolean accept(DragEvent drag, UIDL configuration); - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterion.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterion.java deleted file mode 100644 index db4cb200d1..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterion.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import java.util.HashMap; -import java.util.Map; - -import com.google.gwt.core.client.GWT; - -public class AcceptCriterion { - protected static Map criterion = new HashMap(); - private static AcceptCriterionImpl impl; - - static { - impl = GWT.create(AcceptCriterionImpl.class); - impl.populateCriterionMap(criterion); - } - - public static AcceptCriteria get(String name) { - return criterion.get(name); - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterionImpl.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterionImpl.java deleted file mode 100644 index e0e170bc19..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterionImpl.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import java.util.Map; - -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Paintable; -import com.vaadin.terminal.gwt.client.UIDL; - -public class AcceptCriterionImpl { - - private final class OverTreeNode implements AcceptCriteria { - public boolean accept(DragEvent drag, UIDL configuration) { - Boolean containsKey = (Boolean) drag.getEventDetails().get( - "itemIdOverIsNode"); - if (containsKey != null && containsKey.booleanValue()) { - return true; - } - return false; - } - } - - private final class ComponentCriteria implements AcceptCriteria { - public boolean accept(DragEvent drag, UIDL configuration) { - try { - Paintable component = drag.getTransferrable().getComponent(); - String requiredPid = configuration - .getStringAttribute("component"); - String pid = ((Widget) component).getElement() - .getPropertyString("tkPid"); - return pid.equals(requiredPid); - } catch (Exception e) { - } - return false; - } - } - - private final class And implements AcceptCriteria { - public boolean accept(DragEvent drag, UIDL configuration) { - UIDL childUIDL = configuration.getChildUIDL(0); - UIDL childUIDL2 = configuration.getChildUIDL(1); - AcceptCriteria acceptCriteria = AcceptCriterion.get(childUIDL - .getStringAttribute("name")); - AcceptCriteria acceptCriteria2 = AcceptCriterion.get(childUIDL2 - .getStringAttribute("name")); - if (acceptCriteria == null || acceptCriteria2 == null) { - ApplicationConnection.getConsole().log( - "And criteria didn't found a chidl criteria"); - return false; - } - boolean accept = acceptCriteria.accept(drag, childUIDL); - boolean accept2 = acceptCriteria2.accept(drag, childUIDL2); - return accept && accept2; - } - } - - private final class AcceptAll implements AcceptCriteria { - public boolean accept(DragEvent drag, UIDL configuration) { - return true; - } - } - - private final class HasItemId implements AcceptCriteria { - public boolean accept(DragEvent drag, UIDL configuration) { - return drag.getTransferrable().getItemId() != null; - } - } - - /** - * TODO this method could be written by generator - * - * TODO consider moving implementations to top level classes - * - * TODO use fully qualified names of server side counterparts as keys - */ - public void populateCriterionMap(Map map) { - AcceptCriteria crit; - - crit = new HasItemId(); - map.put("needsItemId", crit); - - crit = new AcceptAll(); - map.put("acceptAll", crit); - - crit = new And(); - map.put("and", crit); - - crit = new OverTreeNode(); - map.put("overTreeNode", crit); - - crit = new ComponentCriteria(); - map.put("component", crit); - - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/DragAndDropManager.java b/src/com/vaadin/terminal/gwt/client/ui/dd/DragAndDropManager.java deleted file mode 100644 index b97cad5da5..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/DragAndDropManager.java +++ /dev/null @@ -1,393 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.dom.client.Style; -import com.google.gwt.dom.client.Style.Position; -import com.google.gwt.dom.client.Style.Unit; -import com.google.gwt.event.shared.HandlerRegistration; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.EventListener; -import com.google.gwt.user.client.Event.NativePreviewEvent; -import com.google.gwt.user.client.Event.NativePreviewHandler; -import com.google.gwt.user.client.ui.RootPanel; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.Paintable; -import com.vaadin.terminal.gwt.client.ValueMap; - -/** - * Helper class to manage the state of drag and drop event on Vaadin client - * side. Can be used to implement most of the drag and drop operation - * automatically via cross-browser event preview method or just as a helper when - * implementing own low level drag and drop operation (like with HTML5 api). - *

- * Singleton. Only one drag and drop operation can be active anyways. Use - * {@link #get()} to get instance. - * - */ -public class DragAndDropManager { - - public enum DragEventType { - ENTER, LEAVE, OVER, DROP - } - - private static final String DD_SERVICE = "DD"; - - private static DragAndDropManager instance; - private HandlerRegistration handlerRegistration; - private DragEvent currentDrag; - - /** - * If dragging is currently on a drophandler, this field has reference to it - */ - private DropHandler currentDropHandler; - - public DropHandler getCurrentDropHandler() { - return currentDropHandler; - } - - /** - * If drag and drop operation is not handled by {@link DragAndDropManager}s - * internal handler, this can be used to update current {@link DropHandler}. - * - * @param currentDropHandler - */ - public void setCurrentDropHandler(DropHandler currentDropHandler) { - this.currentDropHandler = currentDropHandler; - } - - private AcceptCallback acceptCallback; - - public static DragAndDropManager get() { - if (instance == null) { - instance = new DragAndDropManager(); - } - return instance; - } - - /* Singleton */ - private DragAndDropManager() { - } - - /** - * This method is used to start Vaadin client side drag and drop operation. - * Operation may be started by virtually any Widget. - *

- * Cancels possible existing drag. TODO figure out if this is always a bug - * if one is active. Maybe a good and cheap lifesaver thought. - *

- * If possible, method automatically detects current {@link DropHandler} and - * fires {@link DropHandler#dragEnter(DragEvent)} event on it. - *

- * May also be used to control the drag and drop operation. If this option - * is used, {@link DropHandler} is searched on mouse events and appropriate - * methods on it called automatically. - * - * @param transferable - * @param nativeEvent - * @param handleDragEvents - * if true, {@link DragAndDropManager} handles the drag and drop - * operation GWT event preview. - * @return - */ - public DragEvent startDrag(Transferable transferable, - NativeEvent startEvent, boolean handleDragEvents) { - interruptDrag(); - - currentDrag = new DragEvent(transferable, startEvent); - DropHandler dh = null; - if (startEvent != null) { - dh = findDragTarget((Element) startEvent.getEventTarget().cast()); - } - if (dh != null) { - // drag has started on a DropHandler, kind of drag over happens - currentDropHandler = dh; - updateCurrentEvent(startEvent); - dh.dragEnter(currentDrag); - } - - if (handleDragEvents) { - - handlerRegistration = Event - .addNativePreviewHandler(new NativePreviewHandler() { - - public void onPreviewNativeEvent( - NativePreviewEvent event) { - updateCurrentEvent(event.getNativeEvent()); - updateDragImagePosition(); - - NativeEvent nativeEvent = event.getNativeEvent(); - Element targetElement = (Element) nativeEvent - .getEventTarget().cast(); - if (dragElement != null - && targetElement.isOrHasChild(dragElement)) { - ApplicationConnection.getConsole().log( - "Event on dragImage, ignored"); - event.cancel(); - nativeEvent.stopPropagation(); - return; - } - - int typeInt = event.getTypeInt(); - switch (typeInt) { - case Event.ONMOUSEOVER: - ApplicationConnection.getConsole().log( - event.getNativeEvent().getType()); - DropHandler target = findDragTarget(targetElement); - if (target != null && target != currentDrag) { - currentDropHandler = target; - target.dragEnter(currentDrag); - } else if (target == null - && currentDropHandler != null) { - ApplicationConnection.getConsole().log( - "Invalid state!?"); - currentDropHandler = null; - } - break; - case Event.ONMOUSEOUT: - ApplicationConnection.getConsole().log( - event.getNativeEvent().getType()); - - Element relatedTarget = (Element) nativeEvent - .getRelatedEventTarget().cast(); - DropHandler 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); - currentDropHandler = null; - acceptCallback = null; - } - break; - case Event.ONMOUSEMOVE: - if (currentDropHandler != null) { - currentDropHandler.dragOver(currentDrag); - } - nativeEvent.preventDefault(); - - break; - - case Event.ONMOUSEUP: - endDrag(); - break; - - default: - break; - } - - } - - }); - } - return currentDrag; - } - - private void interruptDrag() { - if (currentDrag != null) { - ApplicationConnection.getConsole() - .log("Drag operation interrupted"); - if (currentDropHandler != null) { - currentDrag.currentGwtEvent = null; - currentDropHandler.dragLeave(currentDrag); - currentDropHandler = null; - } - currentDrag = null; - } - } - - private void updateDragImagePosition() { - if (currentDrag.currentGwtEvent != null && dragElement != null) { - Style style = dragElement.getStyle(); - int clientY = currentDrag.currentGwtEvent.getClientY() + 6; - int clientX = currentDrag.currentGwtEvent.getClientX() + 6; - style.setTop(clientY, Unit.PX); - style.setLeft(clientX, Unit.PX); - } - } - - /** - * First seeks the widget from this element, then iterates widgets until one - * implement HasDropHandler. Returns DropHandler from that. - * - * @param element - * @return - */ - private DropHandler findDragTarget(Element element) { - - EventListener eventListener = Event.getEventListener(element); - while (eventListener == null) { - element = element.getParentElement(); - if (element == null) { - break; - } - eventListener = Event.getEventListener(element); - } - if (eventListener == null) { - ApplicationConnection.getConsole().log( - "No suitable DropHandler found"); - return null; - } else { - Widget w = (Widget) eventListener; - while (!(w instanceof HasDropHandler)) { - w = w.getParent(); - if (w == null) { - break; - } - } - if (w == null) { - ApplicationConnection.getConsole().log( - "No suitable DropHandler found2"); - return null; - } else { - DropHandler dh = ((HasDropHandler) w).getDropHandler(); - if (dh == null) { - ApplicationConnection.getConsole().log( - "No suitable DropHandler found3"); - } - return dh; - } - } - } - - private void updateCurrentEvent(NativeEvent event) { - currentDrag.currentGwtEvent = event; - } - - public void endDrag() { - if (handlerRegistration != null) { - handlerRegistration.removeHandler(); - handlerRegistration = null; - } - if (currentDropHandler != null) { - // we have dropped on a drop target - boolean sendTransferrableToServer = currentDropHandler - .drop(currentDrag); - if (sendTransferrableToServer) { - doRequest(DragEventType.DROP); - } - currentDropHandler = null; - acceptCallback = null; - - } - - currentDrag = null; - - if (dragElement != null) { - RootPanel.getBodyElement().removeChild(dragElement); - dragElement = null; - } - } - - private int visitId = 0; - private Element dragElement; - - /** - * Visits server during drag and drop procedure. Transferable and event type - * is given to server side counterpart of DropHandler. - * - * If another server visit is started before the current is received, the - * current is just dropped. TODO consider if callback should have - * interrupted() method for cleanup. - * - * @param acceptCallback - */ - public void visitServer(DragEventType type, AcceptCallback acceptCallback) { - doRequest(type); - this.acceptCallback = acceptCallback; - } - - private void doRequest(DragEventType drop) { - Paintable paintable = currentDropHandler.getPaintable(); - ApplicationConnection client = currentDropHandler - .getApplicationConnection(); - /* - * For drag events we are using special id that are routed to - * "drag service" which then again finds the corresponding DropHandler - * on server side. - * - * TODO add rest of the data in Transferable - * - * TODO implement partial updates to Transferable (currently the whole - * Transferable is sent on each request) - */ - visitId++; - client.updateVariable(DD_SERVICE, "visitId", visitId, false); - client.updateVariable(DD_SERVICE, "eventId", currentDrag.getEventId(), - false); - client.updateVariable(DD_SERVICE, "dhowner", paintable, false); - - Transferable transferable = currentDrag.getTransferrable(); - - if (transferable.getItemId() != null) { - client.updateVariable(DD_SERVICE, "itemId", transferable - .getItemId(), false); - } - if (transferable.getPropertyId() != null) { - client.updateVariable(DD_SERVICE, "propertyId", transferable - .getPropertyId(), false); - } - - client.updateVariable(DD_SERVICE, "component", transferable - .getComponent(), false); - - client.updateVariable(DD_SERVICE, "type", drop.ordinal(), false); - - if (currentDrag.currentGwtEvent != null) { - try { - MouseEventDetails mouseEventDetails = new MouseEventDetails( - currentDrag.currentGwtEvent); - currentDrag.getEventDetails().put("mouseEvent", - mouseEventDetails.serialize()); - } catch (Exception e) { - // NOP, (at least oophm on Safari) can't serialize html dd event - // to - // mouseevent - } - } else { - currentDrag.getEventDetails().put("mouseEvent", null); - } - client.updateVariable(DD_SERVICE, "evt", currentDrag.getEventDetails(), - false); - - client.updateVariable(DD_SERVICE, "tra", transferable.getVariableMap(), - true); - - } - - public void handleServerResponse(ValueMap valueMap) { - if (acceptCallback == null) { - return; - } - int visitId = valueMap.getInt("visitId"); - if (this.visitId == visitId) { - acceptCallback.handleResponse(valueMap); - acceptCallback = null; - } - } - - void setDragElement(Element node) { - if (currentDrag != null) { - if (dragElement != null && dragElement != node) { - RootPanel.getBodyElement().removeChild(dragElement); - } else if (node == dragElement) { - return; - } - - dragElement = node; - Style style = node.getStyle(); - style.setPosition(Position.ABSOLUTE); - style.setZIndex(600000); - RootPanel.getBodyElement().appendChild(node); - } - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/DragEvent.java b/src/com/vaadin/terminal/gwt/client/ui/dd/DragEvent.java deleted file mode 100644 index a64a29925c..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/DragEvent.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.user.client.Element; - -/** - * DragEvent used by Vaadin client side engine. Supports components, items, - * properties and custom payload (HTML5 style). - * - * - */ -public class DragEvent { - - private static int eventId = 0; - - private Transferable transferable; - - NativeEvent currentGwtEvent; - - private NativeEvent startEvent; - - private int id; - - private Date start; - - private HashMap dropDetails = new HashMap(); - - DragEvent(Transferable t, NativeEvent startEvent) { - transferable = t; - this.startEvent = startEvent; - id = eventId++; - start = new Date(); - } - - public Transferable getTransferrable() { - return transferable; - } - - public NativeEvent getCurrentGwtEvent() { - return currentGwtEvent; - } - - public int getEventId() { - return id; - } - - public long sinceStart() { - return new Date().getTime() - start.getTime(); - } - - /** - * Sets the element that will be used as "drag icon". - * - * TODO decide if this method should be here or in {@link Transferable} (in - * HTML5 it is in DataTransfer) or {@link DragAndDropManager} - * - * TODO should be possible to override behaviour an set to HTML5 - * DataTransfer - * - * @param node - */ - public void setDragImage(Element node) { - DragAndDropManager.get().setDragElement(node); - } - - /** - * TODO consider using similar smaller (than map) api as in Transferable - * - * TODO clean up when drop handler changes - * - * @return - */ - public Map getEventDetails() { - return dropDetails; - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/DropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/DropHandler.java deleted file mode 100644 index 45fbdb31df..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/DropHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.Paintable; - -/** - * Vaadin Widgets (TODO or Paintables, see {@link HasDropHandler}) that want to - * receive something via drag and drop implement this interface. - */ -public interface DropHandler { - - /** - * Called by D'D' manager when drag gets over this drop handler. - * - * @param drag - */ - public void dragEnter(DragEvent drag); - - /** - * Called by D'D' manager when drag gets out this drop handler. - * - * @param drag - */ - public void dragLeave(DragEvent drag); - - /** - * The actual drop happened on this drop handler. - * - * @param drag - * @return true if Tranferrable of this drag event needs to be sent to - * server, false if drop was finally canceled or no server visit is - * needed - */ - public boolean drop(DragEvent drag); - - /** - * When drag is over current drag handler. - * - * With drag implementation by {@link DragAndDropManager} will be called - * when mouse is moved. HTML5 implementations call this continuously even - * though mouse is not moved. - * - * @param currentDrag - */ - public void dragOver(DragEvent currentDrag); - - /** - * Returns the Paintable into which this DragHandler is assosiated - */ - public Paintable getPaintable(); - - /** - * Returns the application connection to which this {@link DropHandler} - * belongs to. DragAndDropManager uses this fucction to send Transferable to - * server side. - */ - public ApplicationConnection getApplicationConnection(); - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/HasDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/HasDropHandler.java deleted file mode 100644 index 9814a6f6b8..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/HasDropHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.vaadin.terminal.gwt.client.Paintable; - -/** - * Used to detect Widget from widget tree that has {@link #getDropHandler()} - * - * Decide whether to get rid of this class. If so, {@link AbstractDropHandler} must - * extend {@link Paintable}. - * - */ -public interface HasDropHandler { - public DropHandler getDropHandler(); -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/Html5DragEvent.java b/src/com/vaadin/terminal/gwt/client/ui/dd/Html5DragEvent.java deleted file mode 100644 index 230cda8a6f..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/Html5DragEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import com.google.gwt.core.client.JsArrayString; -import com.google.gwt.dom.client.NativeEvent; - -public class Html5DragEvent extends NativeEvent { - protected Html5DragEvent() { - } - - public final native JsArrayString getTypes() - /*-{ - return this.dataTransfer.types; - }-*/; - - public final native String getDataAsText(String type) - /*-{ - var v = this.dataTransfer.getData(type); - return v; - }-*/; - - /** - * Works on FF 3.6 and possibly with gears. - * - * @param index - * @return - */ - public final native String getFileAsString(int index) - /*-{ - if(this.dataTransfer.files.length > 0 && this.dataTransfer.files[0].getAsText) { - return this.dataTransfer.files[index].getAsText("UTF-8"); - } - return null; - }-*/; - - public final native void setDragEffect(String effect) - /*-{ - try { - this.dataTransfer.dropEffect = effect; - } catch (e){} - }-*/; - - public final native String getEffectAllowed() - /*-{ - return this.dataTransfer.effectAllowed; - }-*/; -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/Transferable.java b/src/com/vaadin/terminal/gwt/client/ui/dd/Transferable.java deleted file mode 100644 index dc0244ae24..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/Transferable.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.vaadin.terminal.gwt.client.ui.dd; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.terminal.DragSource; -import com.vaadin.terminal.gwt.client.Paintable; - -/** - * Client side counterpart for Transferable in com.vaadin.event.Transferable - * - */ -public class Transferable { - - /** - * @return the component - */ - public Paintable getComponent() { - return component; - } - - /** - * @param component - * the component to set - */ - public void setComponent(Paintable component) { - this.component = component; - } - - /** - * This is commonly actually a key to property id on client side than the - * actual propertyId. - * - * Translated by terminal and {@link DragSource} - * - * @return the propertyId - */ - public String getPropertyId() { - return (String) variables.get("propertyId"); - } - - /** - * This is commonly actually a key to property id on client side than the - * actual propertyId. - * - * Translated by terminal and {@link DragSource} - * - * @param propertyId - * the propertyId to set - */ - public void setPropertyId(String propertyId) { - variables.put("propertyId", propertyId); - } - - /** - * @return the itemId - */ - public String getItemId() { - return (String) variables.get("itemId"); - } - - /** - * This is commonly actually a key to item id on client side than the actual - * itemId. - * - * Translated by terminal and {@link DragSource} - * - * @param itemId - * the itemId to set - */ - public void setItemId(String itemId) { - variables.put("itemId", itemId); - } - - private Paintable component; - - public Object getData(String dataFlawor) { - return variables.get(dataFlawor); - } - - public void setData(String dataFlawor, Object value) { - variables.put(dataFlawor, value); - } - - public Collection getDataFlawors() { - return variables.keySet(); - } - - private final Map variables = new HashMap(); - - /** - * This method should only be called by {@link DragAndDropManager}. - * - * @return data in this Transferable that needs to be moved to server. - */ - public Map getVariableMap() { - return variables; - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java new file mode 100644 index 0000000000..81331f334e --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java @@ -0,0 +1,97 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.vaadin.terminal.gwt.client.Paintable; +import com.vaadin.terminal.gwt.client.UIDL; +import com.vaadin.terminal.gwt.client.ValueMap; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager.DragEventType; + +public abstract class VAbstractDropHandler implements VDropHandler { + + private boolean serverValidate; + private UIDL criterioUIDL; + + public void updateRules(UIDL uidl) { + serverValidate = uidl.getBooleanAttribute("serverValidate"); + int childCount = uidl.getChildCount(); + for (int i = 0; i < childCount; i++) { + UIDL childUIDL = uidl.getChildUIDL(i); + if (childUIDL.getTag().equals("acceptCriterion")) { + criterioUIDL = childUIDL; + // TODO consider parsing the criteria tree here instead of + // translating uidl during validates() + + } + } + } + + public boolean validateOnServer() { + return serverValidate; + } + + /** + * Default implementation does nothing. + */ + public void dragOver(VDragEvent currentDrag) { + + } + + /** + * Default implementation does nothing. + */ + public void dragLeave(VDragEvent drag) { + // TODO Auto-generated method stub + + } + + /** + * If transferrable is accepted (either via server visit or client side + * rules) the default implementation calls {@link #dragAccepted(VDragEvent)} + * method. + */ + public void dragEnter(final VDragEvent drag) { + if (serverValidate) { + VDragAndDropManager.get().visitServer(DragEventType.ENTER, + new VAcceptCallback() { + public void handleResponse(ValueMap responseData) { + if (responseData.containsKey("accepted")) { + dragAccepted(drag); + } + } + }); + } else if (validates(drag)) { + dragAccepted(drag); + } + } + + abstract protected void dragAccepted(VDragEvent drag); + + /** + * Returns true if client side rules are met. + * + * @param drag + * @return + */ + protected boolean validates(VDragEvent drag) { + if (criterioUIDL != null) { + String criteriaName = criterioUIDL.getStringAttribute("name"); + VAcceptCriteria acceptCriteria = VAcceptCriterion.get(criteriaName); + if (acceptCriteria != null) { + // ApplicationConnection.getConsole().log( + // "Criteria : " + acceptCriteria.getClass().getName()); + return acceptCriteria.accept(drag, criterioUIDL); + } + } + return false; + } + + public boolean drop(VDragEvent drag) { + if (serverValidate) { + return true; + } else { + return validates(drag); + } + } + + public abstract Paintable getPaintable(); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCallback.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCallback.java new file mode 100644 index 0000000000..2366105853 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCallback.java @@ -0,0 +1,19 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.vaadin.terminal.gwt.client.ValueMap; + +public interface VAcceptCallback { + + /** + * This method is called by {@link VDragAndDropManager} if the + * {@link VDragEvent} is still active. Developer can update for example drag + * icon or target emphasis based on the information returned from server + * side. If the drag and drop operation ends or the + * {@link VAbstractDropHandler} has changed before response arrives, the + * method is never called. + * + * @param responseData + */ + public void handleResponse(ValueMap responseData); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriteria.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriteria.java new file mode 100644 index 0000000000..70f163c6d7 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriteria.java @@ -0,0 +1,9 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.vaadin.terminal.gwt.client.UIDL; + +public interface VAcceptCriteria { + + public boolean accept(VDragEvent drag, UIDL configuration); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java new file mode 100644 index 0000000000..f1b6d2de34 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java @@ -0,0 +1,21 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gwt.core.client.GWT; + +public class VAcceptCriterion { + protected static Map criterion = new HashMap(); + private static VAcceptCriterionImpl impl; + + static { + impl = GWT.create(VAcceptCriterionImpl.class); + impl.populateCriterionMap(criterion); + } + + public static VAcceptCriteria get(String name) { + return criterion.get(name); + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionImpl.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionImpl.java new file mode 100644 index 0000000000..71001d09d0 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionImpl.java @@ -0,0 +1,95 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import java.util.Map; + +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.Paintable; +import com.vaadin.terminal.gwt.client.UIDL; + +public class VAcceptCriterionImpl { + + private final class OverTreeNode implements VAcceptCriteria { + public boolean accept(VDragEvent drag, UIDL configuration) { + Boolean containsKey = (Boolean) drag.getEventDetails().get( + "itemIdOverIsNode"); + if (containsKey != null && containsKey.booleanValue()) { + return true; + } + return false; + } + } + + private final class ComponentCriteria implements VAcceptCriteria { + public boolean accept(VDragEvent drag, UIDL configuration) { + try { + Paintable component = drag.getTransferrable().getComponent(); + String requiredPid = configuration + .getStringAttribute("component"); + String pid = ((Widget) component).getElement() + .getPropertyString("tkPid"); + return pid.equals(requiredPid); + } catch (Exception e) { + } + return false; + } + } + + private final class And implements VAcceptCriteria { + public boolean accept(VDragEvent drag, UIDL configuration) { + UIDL childUIDL = configuration.getChildUIDL(0); + UIDL childUIDL2 = configuration.getChildUIDL(1); + VAcceptCriteria acceptCriteria = VAcceptCriterion.get(childUIDL + .getStringAttribute("name")); + VAcceptCriteria acceptCriteria2 = VAcceptCriterion.get(childUIDL2 + .getStringAttribute("name")); + if (acceptCriteria == null || acceptCriteria2 == null) { + ApplicationConnection.getConsole().log( + "And criteria didn't found a chidl criteria"); + return false; + } + boolean accept = acceptCriteria.accept(drag, childUIDL); + boolean accept2 = acceptCriteria2.accept(drag, childUIDL2); + return accept && accept2; + } + } + + private final class AcceptAll implements VAcceptCriteria { + public boolean accept(VDragEvent drag, UIDL configuration) { + return true; + } + } + + private final class HasItemId implements VAcceptCriteria { + public boolean accept(VDragEvent drag, UIDL configuration) { + return drag.getTransferrable().getItemId() != null; + } + } + + /** + * TODO this method could be written by generator + * + * TODO consider moving implementations to top level classes + * + * TODO use fully qualified names of server side counterparts as keys + */ + public void populateCriterionMap(Map map) { + VAcceptCriteria crit; + + crit = new HasItemId(); + map.put("needsItemId", crit); + + crit = new AcceptAll(); + map.put("acceptAll", crit); + + crit = new And(); + map.put("and", crit); + + crit = new OverTreeNode(); + map.put("overTreeNode", crit); + + crit = new ComponentCriteria(); + map.put("component", crit); + + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java new file mode 100644 index 0000000000..87887c6659 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java @@ -0,0 +1,393 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.EventListener; +import com.google.gwt.user.client.Event.NativePreviewEvent; +import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.MouseEventDetails; +import com.vaadin.terminal.gwt.client.Paintable; +import com.vaadin.terminal.gwt.client.ValueMap; + +/** + * Helper class to manage the state of drag and drop event on Vaadin client + * side. Can be used to implement most of the drag and drop operation + * automatically via cross-browser event preview method or just as a helper when + * implementing own low level drag and drop operation (like with HTML5 api). + *

+ * Singleton. Only one drag and drop operation can be active anyways. Use + * {@link #get()} to get instance. + * + */ +public class VDragAndDropManager { + + public enum DragEventType { + ENTER, LEAVE, OVER, DROP + } + + private static final String DD_SERVICE = "DD"; + + private static VDragAndDropManager instance; + private HandlerRegistration handlerRegistration; + private VDragEvent currentDrag; + + /** + * If dragging is currently on a drophandler, this field has reference to it + */ + private VDropHandler currentDropHandler; + + public VDropHandler getCurrentDropHandler() { + return currentDropHandler; + } + + /** + * If drag and drop operation is not handled by {@link VDragAndDropManager}s + * internal handler, this can be used to update current {@link VDropHandler}. + * + * @param currentDropHandler + */ + public void setCurrentDropHandler(VDropHandler currentDropHandler) { + this.currentDropHandler = currentDropHandler; + } + + private VAcceptCallback acceptCallback; + + public static VDragAndDropManager get() { + if (instance == null) { + instance = new VDragAndDropManager(); + } + return instance; + } + + /* Singleton */ + private VDragAndDropManager() { + } + + /** + * This method is used to start Vaadin client side drag and drop operation. + * Operation may be started by virtually any Widget. + *

+ * Cancels possible existing drag. TODO figure out if this is always a bug + * if one is active. Maybe a good and cheap lifesaver thought. + *

+ * If possible, method automatically detects current {@link VDropHandler} and + * fires {@link VDropHandler#dragEnter(VDragEvent)} event on it. + *

+ * May also be used to control the drag and drop operation. If this option + * is used, {@link VDropHandler} is searched on mouse events and appropriate + * methods on it called automatically. + * + * @param transferable + * @param nativeEvent + * @param handleDragEvents + * if true, {@link VDragAndDropManager} handles the drag and drop + * operation GWT event preview. + * @return + */ + public VDragEvent startDrag(VTransferable transferable, + NativeEvent startEvent, boolean handleDragEvents) { + interruptDrag(); + + currentDrag = new VDragEvent(transferable, startEvent); + VDropHandler dh = null; + if (startEvent != null) { + dh = findDragTarget((Element) startEvent.getEventTarget().cast()); + } + if (dh != null) { + // drag has started on a DropHandler, kind of drag over happens + currentDropHandler = dh; + updateCurrentEvent(startEvent); + dh.dragEnter(currentDrag); + } + + if (handleDragEvents) { + + handlerRegistration = Event + .addNativePreviewHandler(new NativePreviewHandler() { + + public void onPreviewNativeEvent( + NativePreviewEvent event) { + updateCurrentEvent(event.getNativeEvent()); + updateDragImagePosition(); + + NativeEvent nativeEvent = event.getNativeEvent(); + Element targetElement = (Element) nativeEvent + .getEventTarget().cast(); + if (dragElement != null + && targetElement.isOrHasChild(dragElement)) { + ApplicationConnection.getConsole().log( + "Event on dragImage, ignored"); + event.cancel(); + nativeEvent.stopPropagation(); + return; + } + + int typeInt = event.getTypeInt(); + switch (typeInt) { + case Event.ONMOUSEOVER: + ApplicationConnection.getConsole().log( + event.getNativeEvent().getType()); + VDropHandler target = findDragTarget(targetElement); + if (target != null && target != currentDrag) { + currentDropHandler = target; + target.dragEnter(currentDrag); + } else if (target == null + && currentDropHandler != null) { + ApplicationConnection.getConsole().log( + "Invalid state!?"); + currentDropHandler = null; + } + break; + case Event.ONMOUSEOUT: + ApplicationConnection.getConsole().log( + event.getNativeEvent().getType()); + + Element relatedTarget = (Element) nativeEvent + .getRelatedEventTarget().cast(); + 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); + currentDropHandler = null; + acceptCallback = null; + } + break; + case Event.ONMOUSEMOVE: + if (currentDropHandler != null) { + currentDropHandler.dragOver(currentDrag); + } + nativeEvent.preventDefault(); + + break; + + case Event.ONMOUSEUP: + endDrag(); + break; + + default: + break; + } + + } + + }); + } + return currentDrag; + } + + private void interruptDrag() { + if (currentDrag != null) { + ApplicationConnection.getConsole() + .log("Drag operation interrupted"); + if (currentDropHandler != null) { + currentDrag.currentGwtEvent = null; + currentDropHandler.dragLeave(currentDrag); + currentDropHandler = null; + } + currentDrag = null; + } + } + + private void updateDragImagePosition() { + if (currentDrag.currentGwtEvent != null && dragElement != null) { + Style style = dragElement.getStyle(); + int clientY = currentDrag.currentGwtEvent.getClientY() + 6; + int clientX = currentDrag.currentGwtEvent.getClientX() + 6; + style.setTop(clientY, Unit.PX); + style.setLeft(clientX, Unit.PX); + } + } + + /** + * First seeks the widget from this element, then iterates widgets until one + * implement HasDropHandler. Returns DropHandler from that. + * + * @param element + * @return + */ + private VDropHandler findDragTarget(Element element) { + + EventListener eventListener = Event.getEventListener(element); + while (eventListener == null) { + element = element.getParentElement(); + if (element == null) { + break; + } + eventListener = Event.getEventListener(element); + } + if (eventListener == null) { + ApplicationConnection.getConsole().log( + "No suitable DropHandler found"); + return null; + } else { + Widget w = (Widget) eventListener; + while (!(w instanceof VHasDropHandler)) { + w = w.getParent(); + if (w == null) { + break; + } + } + if (w == null) { + ApplicationConnection.getConsole().log( + "No suitable DropHandler found2"); + return null; + } else { + VDropHandler dh = ((VHasDropHandler) w).getDropHandler(); + if (dh == null) { + ApplicationConnection.getConsole().log( + "No suitable DropHandler found3"); + } + return dh; + } + } + } + + private void updateCurrentEvent(NativeEvent event) { + currentDrag.currentGwtEvent = event; + } + + public void endDrag() { + if (handlerRegistration != null) { + handlerRegistration.removeHandler(); + handlerRegistration = null; + } + if (currentDropHandler != null) { + // we have dropped on a drop target + boolean sendTransferrableToServer = currentDropHandler + .drop(currentDrag); + if (sendTransferrableToServer) { + doRequest(DragEventType.DROP); + } + currentDropHandler = null; + acceptCallback = null; + + } + + currentDrag = null; + + if (dragElement != null) { + RootPanel.getBodyElement().removeChild(dragElement); + dragElement = null; + } + } + + private int visitId = 0; + private Element dragElement; + + /** + * Visits server during drag and drop procedure. Transferable and event type + * is given to server side counterpart of DropHandler. + * + * If another server visit is started before the current is received, the + * current is just dropped. TODO consider if callback should have + * interrupted() method for cleanup. + * + * @param acceptCallback + */ + public void visitServer(DragEventType type, VAcceptCallback acceptCallback) { + doRequest(type); + this.acceptCallback = acceptCallback; + } + + private void doRequest(DragEventType drop) { + Paintable paintable = currentDropHandler.getPaintable(); + ApplicationConnection client = currentDropHandler + .getApplicationConnection(); + /* + * For drag events we are using special id that are routed to + * "drag service" which then again finds the corresponding DropHandler + * on server side. + * + * TODO add rest of the data in Transferable + * + * TODO implement partial updates to Transferable (currently the whole + * Transferable is sent on each request) + */ + visitId++; + client.updateVariable(DD_SERVICE, "visitId", visitId, false); + client.updateVariable(DD_SERVICE, "eventId", currentDrag.getEventId(), + false); + client.updateVariable(DD_SERVICE, "dhowner", paintable, false); + + VTransferable transferable = currentDrag.getTransferrable(); + + if (transferable.getItemId() != null) { + client.updateVariable(DD_SERVICE, "itemId", transferable + .getItemId(), false); + } + if (transferable.getPropertyId() != null) { + client.updateVariable(DD_SERVICE, "propertyId", transferable + .getPropertyId(), false); + } + + client.updateVariable(DD_SERVICE, "component", transferable + .getComponent(), false); + + client.updateVariable(DD_SERVICE, "type", drop.ordinal(), false); + + if (currentDrag.currentGwtEvent != null) { + try { + MouseEventDetails mouseEventDetails = new MouseEventDetails( + currentDrag.currentGwtEvent); + currentDrag.getEventDetails().put("mouseEvent", + mouseEventDetails.serialize()); + } catch (Exception e) { + // NOP, (at least oophm on Safari) can't serialize html dd event + // to + // mouseevent + } + } else { + currentDrag.getEventDetails().put("mouseEvent", null); + } + client.updateVariable(DD_SERVICE, "evt", currentDrag.getEventDetails(), + false); + + client.updateVariable(DD_SERVICE, "tra", transferable.getVariableMap(), + true); + + } + + public void handleServerResponse(ValueMap valueMap) { + if (acceptCallback == null) { + return; + } + int visitId = valueMap.getInt("visitId"); + if (this.visitId == visitId) { + acceptCallback.handleResponse(valueMap); + acceptCallback = null; + } + } + + void setDragElement(Element node) { + if (currentDrag != null) { + if (dragElement != null && dragElement != node) { + RootPanel.getBodyElement().removeChild(dragElement); + } else if (node == dragElement) { + return; + } + + dragElement = node; + Style style = node.getStyle(); + style.setPosition(Position.ABSOLUTE); + style.setZIndex(600000); + RootPanel.getBodyElement().appendChild(node); + } + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java new file mode 100644 index 0000000000..ee31f77b94 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java @@ -0,0 +1,81 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.user.client.Element; + +/** + * DragEvent used by Vaadin client side engine. Supports components, items, + * properties and custom payload (HTML5 style). + * + * + */ +public class VDragEvent { + + private static int eventId = 0; + + private VTransferable transferable; + + NativeEvent currentGwtEvent; + + private NativeEvent startEvent; + + private int id; + + private Date start; + + private HashMap dropDetails = new HashMap(); + + VDragEvent(VTransferable t, NativeEvent startEvent) { + transferable = t; + this.startEvent = startEvent; + id = eventId++; + start = new Date(); + } + + public VTransferable getTransferrable() { + return transferable; + } + + public NativeEvent getCurrentGwtEvent() { + return currentGwtEvent; + } + + public int getEventId() { + return id; + } + + public long sinceStart() { + return new Date().getTime() - start.getTime(); + } + + /** + * Sets the element that will be used as "drag icon". + * + * TODO decide if this method should be here or in {@link VTransferable} (in + * HTML5 it is in DataTransfer) or {@link VDragAndDropManager} + * + * TODO should be possible to override behaviour an set to HTML5 + * DataTransfer + * + * @param node + */ + public void setDragImage(Element node) { + VDragAndDropManager.get().setDragElement(node); + } + + /** + * TODO consider using similar smaller (than map) api as in Transferable + * + * TODO clean up when drop handler changes + * + * @return + */ + public Map getEventDetails() { + return dropDetails; + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java new file mode 100644 index 0000000000..5a4701fd9f --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDropHandler.java @@ -0,0 +1,59 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.Paintable; + +/** + * Vaadin Widgets (TODO or Paintables, see {@link VHasDropHandler}) that want to + * receive something via drag and drop implement this interface. + */ +public interface VDropHandler { + + /** + * Called by D'D' manager when drag gets over this drop handler. + * + * @param drag + */ + public void dragEnter(VDragEvent drag); + + /** + * Called by D'D' manager when drag gets out this drop handler. + * + * @param drag + */ + public void dragLeave(VDragEvent drag); + + /** + * The actual drop happened on this drop handler. + * + * @param drag + * @return true if Tranferrable of this drag event needs to be sent to + * server, false if drop was finally canceled or no server visit is + * needed + */ + public boolean drop(VDragEvent drag); + + /** + * When drag is over current drag handler. + * + * With drag implementation by {@link VDragAndDropManager} will be called + * when mouse is moved. HTML5 implementations call this continuously even + * though mouse is not moved. + * + * @param currentDrag + */ + public void dragOver(VDragEvent currentDrag); + + /** + * Returns the Paintable into which this DragHandler is assosiated + */ + public Paintable getPaintable(); + + /** + * Returns the application connection to which this {@link VDropHandler} + * belongs to. DragAndDropManager uses this fucction to send Transferable to + * server side. + */ + public ApplicationConnection getApplicationConnection(); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java new file mode 100644 index 0000000000..ea58757a36 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java @@ -0,0 +1,14 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.vaadin.terminal.gwt.client.Paintable; + +/** + * Used to detect Widget from widget tree that has {@link #getDropHandler()} + * + * Decide whether to get rid of this class. If so, {@link VAbstractDropHandler} must + * extend {@link Paintable}. + * + */ +public interface VHasDropHandler { + public VDropHandler getDropHandler(); +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java new file mode 100644 index 0000000000..6689fbe307 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java @@ -0,0 +1,46 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import com.google.gwt.core.client.JsArrayString; +import com.google.gwt.dom.client.NativeEvent; + +public class VHtml5DragEvent extends NativeEvent { + protected VHtml5DragEvent() { + } + + public final native JsArrayString getTypes() + /*-{ + return this.dataTransfer.types; + }-*/; + + public final native String getDataAsText(String type) + /*-{ + var v = this.dataTransfer.getData(type); + return v; + }-*/; + + /** + * Works on FF 3.6 and possibly with gears. + * + * @param index + * @return + */ + public final native String getFileAsString(int index) + /*-{ + if(this.dataTransfer.files.length > 0 && this.dataTransfer.files[0].getAsText) { + return this.dataTransfer.files[index].getAsText("UTF-8"); + } + return null; + }-*/; + + public final native void setDragEffect(String effect) + /*-{ + try { + this.dataTransfer.dropEffect = effect; + } catch (e){} + }-*/; + + public final native String getEffectAllowed() + /*-{ + return this.dataTransfer.effectAllowed; + }-*/; +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java new file mode 100644 index 0000000000..f04a4d8e33 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java @@ -0,0 +1,101 @@ +package com.vaadin.terminal.gwt.client.ui.dd; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.vaadin.terminal.DragSource; +import com.vaadin.terminal.gwt.client.Paintable; + +/** + * Client side counterpart for Transferable in com.vaadin.event.Transferable + * + */ +public class VTransferable { + + private Paintable component; + + private final Map variables = new HashMap(); + + /** + * @return the component + */ + public Paintable getComponent() { + return component; + } + + /** + * @param component + * the component to set + */ + public void setComponent(Paintable component) { + this.component = component; + } + + /** + * This is commonly actually a key to property id on client side than the + * actual propertyId. + * + * Translated by terminal and {@link DragSource} + * + * @return the propertyId + */ + public String getPropertyId() { + return (String) variables.get("propertyId"); + } + + /** + * This is commonly actually a key to property id on client side than the + * actual propertyId. + * + * Translated by terminal and {@link DragSource} + * + * @param propertyId + * the propertyId to set + */ + public void setPropertyId(String propertyId) { + variables.put("propertyId", propertyId); + } + + /** + * @return the itemId + */ + public String getItemId() { + return (String) variables.get("itemId"); + } + + /** + * This is commonly actually a key to item id on client side than the actual + * itemId. + * + * Translated by terminal and {@link DragSource} + * + * @param itemId + * the itemId to set + */ + public void setItemId(String itemId) { + variables.put("itemId", itemId); + } + + public Object getData(String dataFlawor) { + return variables.get(dataFlawor); + } + + public void setData(String dataFlawor, Object value) { + variables.put(dataFlawor, value); + } + + public Collection getDataFlawors() { + return variables.keySet(); + } + + /** + * This method should only be called by {@link VDragAndDropManager}. + * + * @return data in this Transferable that needs to be moved to server. + */ + public Map getVariableMap() { + return variables; + } + +} diff --git a/tests/src/com/vaadin/tests/dd/VMyDragSource.java b/tests/src/com/vaadin/tests/dd/VMyDragSource.java index 2be0dc8d7e..a5f52522ad 100644 --- a/tests/src/com/vaadin/tests/dd/VMyDragSource.java +++ b/tests/src/com/vaadin/tests/dd/VMyDragSource.java @@ -13,8 +13,8 @@ import com.google.gwt.user.client.ui.HTML; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; -import com.vaadin.terminal.gwt.client.ui.dd.Transferable; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.VTransferable; /** * Example code to implement Component that has something to drag. @@ -67,13 +67,13 @@ public class VMyDragSource extends Composite implements Paintable, // Start the drag and drop operation // create Transferable, that contains the payload - Transferable transferable = new Transferable(); + VTransferable transferable = new VTransferable(); transferable.setData("Text", "myPayload"); // Tell DragAndDropManager to start a drag and drop operation. // Also let it handle all events (last parameter true). Could // also do all event handling here too. - DragAndDropManager.get().startDrag(transferable, + VDragAndDropManager.get().startDrag(transferable, mDownEvent.getNativeEvent(), true); mouseDown = false; diff --git a/tests/src/com/vaadin/tests/dd/VMyDropTarget.java b/tests/src/com/vaadin/tests/dd/VMyDropTarget.java index 9bc7920335..8e9616bb38 100644 --- a/tests/src/com/vaadin/tests/dd/VMyDropTarget.java +++ b/tests/src/com/vaadin/tests/dd/VMyDropTarget.java @@ -5,36 +5,36 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.ValueMap; -import com.vaadin.terminal.gwt.client.ui.dd.AcceptCallback; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; -import com.vaadin.terminal.gwt.client.ui.dd.DragEvent; -import com.vaadin.terminal.gwt.client.ui.dd.DropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.HasDropHandler; -import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager.DragEventType; +import com.vaadin.terminal.gwt.client.ui.dd.VAcceptCallback; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.VDragEvent; +import com.vaadin.terminal.gwt.client.ui.dd.VDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VHasDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager.DragEventType; -public class VMyDropTarget extends Composite implements HasDropHandler, - DropHandler, Paintable { +public class VMyDropTarget extends Composite implements VHasDropHandler, + VDropHandler, Paintable { private ApplicationConnection client; - public void dragEnter(DragEvent drag) { - DragAndDropManager.get().visitServer(DragEventType.ENTER, - new AcceptCallback() { + public void dragEnter(VDragEvent drag) { + VDragAndDropManager.get().visitServer(DragEventType.ENTER, + new VAcceptCallback() { public void handleResponse(ValueMap responseData) { // show hints, error messages etc } }); } - public void dragLeave(DragEvent drag) { + public void dragLeave(VDragEvent drag) { // TODO Auto-generated method stub } - public void dragOver(DragEvent currentDrag) { + public void dragOver(VDragEvent currentDrag) { // TODO Auto-generated method stub } - public boolean drop(DragEvent drag) { + public boolean drop(VDragEvent drag) { // TODO Auto-generated method stub // return true to tell DDManager do server visit return false; @@ -45,7 +45,7 @@ public class VMyDropTarget extends Composite implements HasDropHandler, return this; } - public DropHandler getDropHandler() { + public VDropHandler getDropHandler() { // Drophandler implemented by Paintable itself return this; }