]> source.dussan.org Git - vaadin-framework.git/commitdiff
draft of DragAndDropWrapper + small changes
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 16 Feb 2010 15:58:56 +0000 (15:58 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 16 Feb 2010 15:58:56 +0000 (15:58 +0000)
svn changeset:11349/svn branch:6.3_dd

25 files changed:
WebContent/VAADIN/themes/base/common/common.css
WebContent/VAADIN/themes/base/styles.css
WebContent/VAADIN/themes/base/tree/tree.css
WebContent/VAADIN/themes/reindeer/styles.css
WebContent/VAADIN/themes/runo/styles.css
src/com/vaadin/event/ComponentTransferable.java
src/com/vaadin/event/dd/DragSource.java
src/com/vaadin/event/dd/DropHandler.java
src/com/vaadin/event/dd/TargetDetails.java
src/com/vaadin/event/dd/TargetDetailsImpl.java
src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VDragDropPane.java
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
src/com/vaadin/terminal/gwt/client/ui/VTree.java
src/com/vaadin/terminal/gwt/client/ui/dd/ComponentCriteria.java
src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java
src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java
src/com/vaadin/terminal/gwt/client/ui/dd/VHasDropHandler.java
src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java
src/com/vaadin/ui/CustomComponent.java
src/com/vaadin/ui/DragAndDropWrapper.java [new file with mode: 0644]
src/com/vaadin/ui/DragDropPane.java
tests/src/com/vaadin/tests/dd/DDTest1.java
tests/src/com/vaadin/tests/dd/DDTest5.java [new file with mode: 0644]

index 082f6b4f7f2ea6c1ff42693c738a91335e4276cb..29fb1363d407842d3d5c00740832a5d0828295a4 100644 (file)
@@ -226,4 +226,19 @@ div.v-app-loading {
     opacity: 0.4;
     filter: alpha(opacity=40);
     border: 1px solid #999;
-}
\ No newline at end of file
+}
+
+
+.v-ddwrapper {
+       background-color: cyan;
+}
+
+.v-ddwrapper-over-center {
+       background-color: LightGreen;
+}
+.v-ddwrapper-over-top {
+       border-top: 2px solid green;
+}
+.v-ddwrapper-over-bottom {
+       border-bottom: 2px solid green;
+}
index eca4525510011e1af97ee286d80c812efaaabc8a..770f1c9d4cef924d22aff199c1a5833a7b5b7ba3 100644 (file)
@@ -458,6 +458,21 @@ div.v-app-loading {
     border: 1px solid #999;
 }
 
+
+.v-ddwrapper {
+       background-color: cyan;
+}
+
+.v-ddwrapper-over-center {
+       background-color: LightGreen;
+}
+.v-ddwrapper-over-top {
+       border-top: 2px solid green;
+}
+.v-ddwrapper-over-bottom {
+       border-bottom: 2px solid green;
+}
+
 .v-csslayout {
        overflow: hidden;
 }
@@ -1621,17 +1636,16 @@ div.v-tree-node-leaf {
        color: #fff;
 }
 
-.v-tree-node-drag-top .v-tree-node-caption {
+.v-tree-node-caption-drag-top {
        border-top:2px solid green;
 }
-.v-tree-node-drag-bottom .v-tree-node-caption {
+.v-tree-node-caption-drag-bottom {
        border-bottom:2px solid green;
 }
-.v-tree-node-drag-center .v-tree-node-caption {
+.v-tree-node-caption-drag-center {
        background-color:green;
 }
 
-
 .v-tree-node-children {
        padding-left: 1em;
 }
index 8a6fc3b878213b0b38c88eba9eb5694d4245d1a0..084247e7d523ea1401ddf151897baaa0c5f2bd92 100644 (file)
@@ -30,13 +30,13 @@ div.v-tree-node-leaf {
        color: #fff;
 }
 
-.v-tree-node-drag-top .v-tree-node-caption {
+.v-tree-node-caption-drag-top {
        border-top:2px solid green;
 }
-.v-tree-node-drag-bottom .v-tree-node-caption {
+.v-tree-node-caption-drag-bottom {
        border-bottom:2px solid green;
 }
-.v-tree-node-drag-center .v-tree-node-caption {
+.v-tree-node-caption-drag-center {
        background-color:green;
 }
 
index c4081182c804e2eb704b5b4b0d892f1ec297fb5d..e927ab81cbd9c0bcab003d5e75ae55428e06057d 100644 (file)
@@ -458,6 +458,21 @@ div.v-app-loading {
     border: 1px solid #999;
 }
 
+
+.v-ddwrapper {
+       background-color: cyan;
+}
+
+.v-ddwrapper-over-center {
+       background-color: LightGreen;
+}
+.v-ddwrapper-over-top {
+       border-top: 2px solid green;
+}
+.v-ddwrapper-over-bottom {
+       border-bottom: 2px solid green;
+}
+
 .v-csslayout {
        overflow: hidden;
 }
@@ -1621,17 +1636,16 @@ div.v-tree-node-leaf {
        color: #fff;
 }
 
-.v-tree-node-drag-top .v-tree-node-caption {
+.v-tree-node-caption-drag-top {
        border-top:2px solid green;
 }
-.v-tree-node-drag-bottom .v-tree-node-caption {
+.v-tree-node-caption-drag-bottom {
        border-bottom:2px solid green;
 }
-.v-tree-node-drag-center .v-tree-node-caption {
+.v-tree-node-caption-drag-center {
        background-color:green;
 }
 
-
 .v-tree-node-children {
        padding-left: 1em;
 }
index 8d07f54c530065616b8118285efd72896b46f9b4..a3ad1f1f862a38b0cf12005f93953853fe143df3 100644 (file)
@@ -458,6 +458,21 @@ div.v-app-loading {
     border: 1px solid #999;
 }
 
+
+.v-ddwrapper {
+       background-color: cyan;
+}
+
+.v-ddwrapper-over-center {
+       background-color: LightGreen;
+}
+.v-ddwrapper-over-top {
+       border-top: 2px solid green;
+}
+.v-ddwrapper-over-bottom {
+       border-bottom: 2px solid green;
+}
+
 .v-csslayout {
        overflow: hidden;
 }
@@ -1621,17 +1636,16 @@ div.v-tree-node-leaf {
        color: #fff;
 }
 
-.v-tree-node-drag-top .v-tree-node-caption {
+.v-tree-node-caption-drag-top {
        border-top:2px solid green;
 }
-.v-tree-node-drag-bottom .v-tree-node-caption {
+.v-tree-node-caption-drag-bottom {
        border-bottom:2px solid green;
 }
-.v-tree-node-drag-center .v-tree-node-caption {
+.v-tree-node-caption-drag-center {
        background-color:green;
 }
 
-
 .v-tree-node-children {
        padding-left: 1em;
 }
index f3d7e04162a73b8a9261aeff4b0f97ccff2aa8a8..c1b713690ac249ef1d6de50d5820eb2da0e7dbe2 100644 (file)
@@ -5,7 +5,7 @@ import com.vaadin.ui.Component;
 public interface ComponentTransferable extends Transferable {
 
     /**
-     * @return the component where the drag operation started
+     * @return the component that started the drag operation
      */
     public Component getSourceComponent();
 
index 9d901f0d41d4934d11d6795d2042952017ce9331..3b69f1b028e830b263241d241c7afead985907c9 100644 (file)
@@ -1,10 +1,11 @@
 package com.vaadin.event.dd;
 
+import java.io.Serializable;
 import java.util.Map;
 
 import com.vaadin.event.Transferable;
 
-public interface DragSource {
+public interface DragSource extends Serializable {
 
     /**
      * DragSource may convert client side variables to meaningful values on
index 2bb03aa7b07a3fdcc5e1e4ce48a2e02590239c9e..b5ebbc0fa16e459fd703d38acf5849bc5092fefd 100644 (file)
@@ -1,9 +1,11 @@
 package com.vaadin.event.dd;
 
+import java.io.Serializable;
+
 import com.vaadin.event.dd.acceptCriteria.AcceptAll;
 import com.vaadin.event.dd.acceptCriteria.AcceptCriterion;
 
-public interface DropHandler {
+public interface DropHandler extends Serializable {
 
     public void drop(DropEvent dropEvent);
 
index d3f488052b83ee3e9e9f473f99751a8666e74a4e..7711160f6ee7bd9123cd26249ca5f11535cfa85a 100644 (file)
@@ -1,6 +1,9 @@
 package com.vaadin.event.dd;
 
-public interface TargetDetails {
+import java.io.Serializable;
+
+public interface TargetDetails extends Serializable {
+
     public Object getData(String key);
 
     public Object setData(String key, Object value);
index be9fa5598f7c290cc253a822816003ad21cc933a..ae7c7d0a5eb9b38da680a2de61eedd35d6d7264f 100644 (file)
@@ -24,4 +24,5 @@ public class TargetDetailsImpl implements TargetDetails {
     public DropTarget getTarget() {
         return (DropTarget) data.get(DragAndDropService.DROPTARGET_KEY);
     }
+
 }
\ No newline at end of file
index 919c267eb009968f44f9864131531088e4446298..8ee6b0bb14af268298a54e71077373884fc42b9f 100644 (file)
@@ -9,6 +9,7 @@ import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ui.VButton;
 import com.vaadin.terminal.gwt.client.ui.VCheckBox;
 import com.vaadin.terminal.gwt.client.ui.VDateFieldCalendar;
+import com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper;
 import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
 import com.vaadin.terminal.gwt.client.ui.VListSelect;
 import com.vaadin.terminal.gwt.client.ui.VNativeSelect;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
new file mode 100644 (file)
index 0000000..f6b4baa
--- /dev/null
@@ -0,0 +1,336 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Map;
+
+import com.google.gwt.core.client.JsArrayString;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Element;
+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;
+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.VHtml5DragEvent;
+import com.vaadin.terminal.gwt.client.ui.dd.VTransferable;
+import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
+
+/**
+ * 
+ * Must have features:
+ * 
+ * stylenames to root element depending on place on component
+ * 
+ * 
+ * allow size to change on emphasis/deemphasis (behave well for vaadin layout
+ * system)
+ * 
+ * html5 drops
+ * 
+ * drop details: locations + sizes in document hierarchy up to wrapper
+ * 
+ * 
+ */
+public class VDragAndDropWrapper extends VCustomComponent implements
+        VHasDropHandler {
+
+    private static final String CLASSNAME = "v-ddwrapper";
+
+    public VDragAndDropWrapper() {
+        super();
+        hookHtml5Events(getElement());
+        setStyleName(CLASSNAME);
+        addDomHandler(new MouseDownHandler() {
+            public void onMouseDown(MouseDownEvent event) {
+                if (dragStarMode > 0) {
+                    // TODO should support drag mode WRAPPER too, now works for
+                    // COMPONENT
+                    VTransferable transferable = new VTransferable();
+                    transferable.setDragSource(VDragAndDropWrapper.this);
+                    Paintable paintable = client.getPaintable((Element) event
+                            .getNativeEvent().getEventTarget().cast());
+
+                    transferable.setData("component", paintable);
+                    VDragEvent startDrag = VDragAndDropManager.get().startDrag(
+                            transferable, event.getNativeEvent(), true);
+                    if (dragStarMode == WRAPPER) {
+                        paintable = VDragAndDropWrapper.this;
+                    }
+
+                    startDrag.createDragImage(
+                            ((Widget) paintable).getElement(), true);
+                    event.preventDefault(); // prevent text selection
+
+                }
+            }
+        }, MouseDownEvent.getType());
+    }
+
+    private ApplicationConnection client;
+    private VAbstractDropHandler dropHandler;
+    private VDragEvent vaadinDragEvent;
+
+    private final static int NONE = 0;
+    private final static int COMPONENT = 1;
+    private final static int WRAPPER = 2;
+    private int dragStarMode;
+
+    @Override
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+        this.client = client;
+        super.updateFromUIDL(uidl, client);
+        if (!uidl.hasAttribute("cached") && !uidl.hasAttribute("hidden")) {
+            int childCount = uidl.getChildCount();
+            if (childCount > 1) {
+                UIDL childUIDL = uidl.getChildUIDL(1);
+                if (dropHandler == null) {
+                    dropHandler = new CustomDropHandler();
+                }
+                dropHandler.updateAcceptRules(childUIDL);
+            } else {
+                dropHandler = null;
+            }
+
+            dragStarMode = uidl.getIntAttribute("dragStartMode");
+        }
+    }
+
+    public boolean html5DragEnter(VHtml5DragEvent event) {
+        if (dropHandler == null) {
+            return true;
+        }
+        ApplicationConnection.getConsole().log("HTML 5 Drag Enter");
+        VTransferable transferable = new VTransferable();
+
+        vaadinDragEvent = VDragAndDropManager.get().startDrag(transferable,
+                event, false);
+        event.preventDefault();
+        event.stopPropagation();
+        return false;
+    }
+
+    public boolean html5DragLeave(VHtml5DragEvent event) {
+        if (dropHandler == null) {
+            return true;
+        }
+
+        ApplicationConnection.getConsole().log("HTML 5 Drag Leave posponed...");
+        DeferredCommand.addCommand(new Command() {
+            public void execute() {
+                // Yes, dragleave happens before drop. Makes no sense to me.
+                // IMO shouldn't fire leave at all if drop happens (I guess this
+                // is what IE does).
+                // In Vaadin we fire it only if drop did not happen.
+                if (vaadinDragEvent != null) {
+                    ApplicationConnection.getConsole().log(
+                            "...HTML 5 Drag Leave");
+                    getDropHandler().dragLeave(vaadinDragEvent);
+                }
+            }
+        });
+        event.preventDefault();
+        event.stopPropagation();
+        return false;
+    }
+
+    public boolean html5DragOver(VHtml5DragEvent event) {
+        if (dropHandler == null) {
+            return true;
+        }
+
+        ApplicationConnection.getConsole().log("HTML 5 Drag Over");
+        getDropHandler().dragOver(vaadinDragEvent);
+        // needed to be set for Safari, otherwise drop will not happen
+        String s = event.getEffectAllowed();
+        if ("all".equals(s) || s.contains("opy")) {
+            event.setDragEffect("copy");
+        } else {
+            event.setDragEffect(s);
+            ApplicationConnection.getConsole().log("Drag effect set to " + s);
+        }
+        event.preventDefault();
+        event.stopPropagation();
+        return false;
+    }
+
+    public boolean html5DragDrop(VHtml5DragEvent event) {
+        if (dropHandler == null) {
+            return true;
+        }
+
+        ApplicationConnection.getConsole().log("HTML 5 Drag Drop");
+        VTransferable transferable = vaadinDragEvent.getTransferable();
+
+        JsArrayString types = event.getTypes();
+        for (int i = 0; i < types.length(); i++) {
+            String type = types.get(i);
+            ApplicationConnection.getConsole().log("Type: " + type);
+            if ("text/plain".equals(type)) {
+                String data = event.getDataAsText(type);
+                ApplicationConnection.getConsole().log(type + " : " + data);
+                transferable.setData("text/plain", data);
+            }
+        }
+
+        String fileAsString = event.getFileAsString(0);
+        if (fileAsString != null) {
+            ApplicationConnection.getConsole().log(fileAsString);
+            transferable.setData("fileContents", fileAsString);
+        }
+
+        VDragAndDropManager.get().endDrag();
+        vaadinDragEvent = null;
+        event.preventDefault();
+        event.stopPropagation();
+
+        return false;
+    }
+
+    public VDropHandler getDropHandler() {
+        return dropHandler;
+    }
+
+    private class CustomDropHandler extends VAbstractDropHandler {
+
+        private static final String OVER_STYLE = "v-ddwrapper-over";
+        private VerticalDropLocation verticalDropLocation;
+
+        @Override
+        public void dragEnter(VDragEvent drag) {
+            ApplicationConnection.getConsole().log("DDWrapper DragEnter");
+            super.dragEnter(drag);
+        }
+
+        @Override
+        public void dragLeave(VDragEvent drag) {
+            ApplicationConnection.getConsole().log("DDWrapper DragLeave");
+            deEmphasis();
+        }
+
+        @Override
+        public void dragOver(final VDragEvent drag) {
+            validate(new VAcceptCallback() {
+                public void accepted(VDragEvent event) {
+                    dragAccepted(drag);
+                }
+            }, drag);
+        }
+
+        @Override
+        public boolean drop(VDragEvent drag) {
+            ApplicationConnection.getConsole().log("Drop" + drag.sinceStart());
+            deEmphasis();
+
+            Map<String, Object> dd = drag.getDropDetails();
+
+            // this is absolute layout based, and we may want to set
+            // component
+            // relatively to where the drag ended.
+            // need to add current location of the drop area
+
+            int absoluteLeft = getAbsoluteLeft();
+            int absoluteTop = getAbsoluteTop();
+
+            dd.put("absoluteLeft", absoluteLeft);
+            dd.put("absoluteTop", absoluteTop);
+
+            dd.put("verticalLocation", verticalDropLocation.toString());
+
+            return super.drop(drag);
+        }
+
+        private void deEmphasis() {
+            if (verticalDropLocation != null) {
+                VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE,
+                        false);
+                VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE + "-"
+                        + verticalDropLocation.toString().toLowerCase(), false);
+            }
+        }
+
+        @Override
+        protected void dragAccepted(VDragEvent drag) {
+            emphasis(drag);
+        }
+
+        private void emphasis(VDragEvent drag) {
+            deEmphasis();
+            verticalDropLocation = VerticalDropLocation.get(getElement(), drag
+                    .getCurrentGwtEvent().getClientY(), 0.2);
+            // TODO add more detailed stylenames depending on which part of
+            // wrapper the drag currently is (vertical done, needs horizontal)
+            VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE, true);
+            VDragAndDropWrapper.setStyleName(getElement(), OVER_STYLE + "-"
+                    + verticalDropLocation.toString().toLowerCase(), true);
+
+            // TODO build (to be an example) an emphasis mode where drag image
+            // is fitted before or after the content
+
+        }
+
+        @Override
+        public Paintable getPaintable() {
+            return VDragAndDropWrapper.this;
+        }
+
+        public ApplicationConnection getApplicationConnection() {
+            return client;
+        }
+
+    }
+
+    /**
+     * Prototype code, memory leak risk.
+     * 
+     * @param el
+     */
+    private native void hookHtml5Events(Element el)
+    /*-{
+
+            var me = this;
+            
+            if(el.addEventListener) {
+                el.addEventListener("dragenter",  function(ev) {
+                    return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                }, false);
+                
+                el.addEventListener("dragleave",  function(ev) {
+                    return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                }, false);
+        
+                el.addEventListener("dragover",  function(ev) {
+                    return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                }, false);
+        
+                el.addEventListener("drop",  function(ev) {
+                    return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                }, false);
+            
+            } else {
+                el.attachEvent("ondragenter",  function(ev) {
+                            return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                });
+                
+                el.attachEvent("ondragleave",  function(ev) {
+                        return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                });
+        
+                el.attachEvent("ondragover",  function(ev) {
+                    return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                });
+        
+                el.attachEvent("ondrop",  function(ev) {
+                    return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+                });
+            }
+        
+    }-*/;
+
+}
index 937f2f6bed490090dd15c2c35dc6c072b887895b..22fd48f54d06ae2c34b07600eb0e830703380cf0 100644 (file)
@@ -11,7 +11,6 @@ import com.google.gwt.user.client.DeferredCommand;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.Container;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.Paintable;
@@ -43,7 +42,8 @@ public class VDragDropPane extends VAbsoluteLayout implements Container,
                         .cast());
                 if (paintable != null) {
                     VTransferable transferable = new VTransferable();
-                    transferable.setComponent(paintable);
+                    transferable.setDragSource(VDragDropPane.this);
+                    transferable.setData("component", paintable);
                     VDragEvent drag = VDragAndDropManager.get().startDrag(
                             transferable, event.getNativeEvent(), true);
                     drag.createDragImage(((Widget) paintable).getElement(),
@@ -57,10 +57,8 @@ public class VDragDropPane extends VAbsoluteLayout implements Container,
             }
         }, MouseDownEvent.getType());
 
-        if (!BrowserInfo.get().isIE()) {
-            // TODO make this IE compatible
-            hookHtml5Events(getElement());
-        }
+        hookHtml5Events(getElement());
+
         getStyleElement().getStyle().setBackgroundColor("yellow");
 
     }
index 99e3ddb3ad7337aa20dcf065b86603cef5fbc07f..8b75cfa76140120b8f003da446772ef5be847215 100644 (file)
@@ -2520,7 +2520,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                         case Event.ONMOUSEMOVE:
                             if (mDown && dragmode != 0) {
                                 VTransferable transferable = new VTransferable();
-                                transferable.setComponent(VScrollTable.this);
+                                transferable.setDragSource(VScrollTable.this);
                                 transferable.setData("itemId", "" + rowKey);
 
                                 // TODO propertyId
index d0f50d2632bc61ba15d333fa2d8b76b1967d1434..22b897d9c7d02de8cfbd6feac3b92afd3f40adcc 100644 (file)
@@ -207,7 +207,7 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
                     final String detail = getDropDetail(currentDrag
                             .getCurrentGwtEvent());
                     boolean nodeHasChanged = (currentMouseOverKey != null && currentMouseOverKey != oldIdOver)
-                            || (oldIdOver != null);
+                            || (currentMouseOverKey == null && oldIdOver != null);
                     boolean detailHasChanded = (detail != null && !detail
                             .equals(oldDetail))
                             || (detail == null && oldDetail != null);
@@ -273,7 +273,7 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
             return null;
         }
         VerticalDropLocation verticalDropLocation = VerticalDropLocation.get(
-                treeNode.getElement(), event.getClientY(), 0.2);
+                treeNode.nodeCaptionDiv, event.getClientY(), 0.2);
         return verticalDropLocation.toString();
     }
 
@@ -361,6 +361,13 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
                     .equals(string));
             UIObject.setStyleName(getElement(), base + "center", "Center"
                     .equals(string));
+            base = "v-tree-node-caption-drag-";
+            UIObject.setStyleName(nodeCaptionDiv, base + "top", "Top"
+                    .equals(string));
+            UIObject.setStyleName(nodeCaptionDiv, base + "bottom", "Bottom"
+                    .equals(string));
+            UIObject.setStyleName(nodeCaptionDiv, base + "center", "Center"
+                    .equals(string));
         }
 
         @Override
@@ -405,7 +412,7 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
                                 "TreeNode drag start " + event.getType());
                         // start actual drag on slight move when mouse is down
                         VTransferable t = new VTransferable();
-                        t.setComponent(VTree.this);
+                        t.setDragSource(VTree.this);
                         t.setData("itemId", key);
                         VDragEvent drag = VDragAndDropManager.get().startDrag(
                                 t, mouseDownEvent, true);
index 860653b67ab9f80cc4cdcf22ede79123dbbf35eb..ae129365c40f3eaaf177982d200c0803790a76b5 100644 (file)
@@ -11,7 +11,7 @@ final class ComponentCriteria implements VAcceptCriteria {
     public void accept(VDragEvent drag, UIDL configuration,
             VAcceptCallback callback) {
         try {
-            Paintable component = drag.getTransferable().getComponent();
+            Paintable component = drag.getTransferable().getDragSource();
             int c = configuration.getIntAttribute("c");
             for (int i = 0; i < c; i++) {
                 String requiredPid = configuration
index f6a3d09b71c3947c88ac28f6ff40a12489a01b55..aaf90f899dadc6e64635ff08c56acb784b8716a2 100644 (file)
@@ -72,7 +72,6 @@ public abstract class VAbstractDropHandler implements VDropHandler {
      */
     public void dragEnter(final VDragEvent drag) {
         validate(new VAcceptCallback() {
-
             public void accepted(VDragEvent event) {
                 dragAccepted(drag);
             }
index 8d301c70f26ddd5f8c9a5e29085d449bbe822802..e499f929b8999db3d2bc17c11a61e40826ac628b 100644 (file)
@@ -362,11 +362,7 @@ public class VDragAndDropManager {
                                 deferredStartRegistration.removeHandler();
                                 deferredStartRegistration = null;
                                 currentDrag = null;
-                                if (dragElement != null) {
-                                    RootPanel.getBodyElement().removeChild(
-                                            dragElement);
-                                    dragElement = null;
-                                }
+                                clearDragElement();
                                 break;
                             }
 
@@ -469,6 +465,10 @@ public class VDragAndDropManager {
 
         currentDrag = null;
 
+        clearDragElement();
+    }
+
+    private void clearDragElement() {
         if (dragElement != null) {
             if (dragElement.getParentElement() != null) {
                 RootPanel.getBodyElement().removeChild(dragElement);
@@ -518,7 +518,7 @@ public class VDragAndDropManager {
         VTransferable transferable = currentDrag.getTransferable();
 
         client.updateVariable(DD_SERVICE, "component", transferable
-                .getComponent(), false);
+                .getDragSource(), false);
 
         client.updateVariable(DD_SERVICE, "type", drop.ordinal(), false);
 
@@ -572,7 +572,7 @@ public class VDragAndDropManager {
     void setDragElement(Element node) {
         if (currentDrag != null) {
             if (dragElement != null && dragElement != node) {
-                RootPanel.getBodyElement().removeChild(dragElement);
+                clearDragElement();
             } else if (node == dragElement) {
                 return;
             }
index ea58757a36ddf0ddbefe98a994301b3058969378..7fc358223c2883eb7ef9d0eabbd39d44d9913b03 100644 (file)
@@ -5,8 +5,8 @@ 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}.
+ * Decide whether to get rid of this class. If so, {@link VAbstractDropHandler}
+ * must extend {@link Paintable}.
  * 
  */
 public interface VHasDropHandler {
index e2ef58cc2d832079509c675543170054ce704f61..e810fa6ceaed6a6e827932b66e7eef5df034c1ce 100644 (file)
@@ -18,12 +18,12 @@ public class VTransferable {
     private final Map<String, Object> variables = new HashMap<String, Object>();
 
     /**
-     * Returns the component currently being dragged or from which the
-     * transferable is created (eg. a tree which node is dragged).
+     * Returns the component from which the transferable is created (eg. a tree
+     * which node is dragged).
      * 
      * @return the component
      */
-    public Paintable getComponent() {
+    public Paintable getDragSource() {
         return component;
     }
 
@@ -38,7 +38,7 @@ public class VTransferable {
      * @param component
      *            the component to set
      */
-    public void setComponent(Paintable component) {
+    public void setDragSource(Paintable component) {
         this.component = component;
     }
 
index 976775b8f3874844c0e6fb7fe37dc685fc22b0db..661c72b951eb1c8b4eb9e6e7eb82998d34ce83a6 100644 (file)
@@ -126,8 +126,11 @@ public class CustomComponent extends AbstractComponentContainer {
      * The component type is textual type of the component. This is included in
      * the UIDL as component tag attribute.
      * 
+     * @deprecated not more useful as the whole tag system has been removed
+     * 
      * @return the component type.
      */
+    @Deprecated
     public String getComponentType() {
         return componentType;
     }
@@ -138,9 +141,12 @@ public class CustomComponent extends AbstractComponentContainer {
      * The component type is textual type of the component. This is included in
      * the UIDL as component tag attribute.
      * 
+     * @deprecated not more useful as the whole tag system has been removed
+     * 
      * @param componentType
      *            the componentType to set.
      */
+    @Deprecated
     public void setComponentType(String componentType) {
         this.componentType = componentType;
     }
diff --git a/src/com/vaadin/ui/DragAndDropWrapper.java b/src/com/vaadin/ui/DragAndDropWrapper.java
new file mode 100644 (file)
index 0000000..827aa35
--- /dev/null
@@ -0,0 +1,109 @@
+package com.vaadin.ui;
+
+import java.util.Collection;
+import java.util.Map;
+
+import com.vaadin.event.ComponentTransferable;
+import com.vaadin.event.Transferable;
+import com.vaadin.event.dd.DragSource;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.DropTarget;
+import com.vaadin.event.dd.TargetDetails;
+import com.vaadin.terminal.PaintException;
+import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper;
+
+@ClientWidget(VDragAndDropWrapper.class)
+public class DragAndDropWrapper extends CustomComponent implements DropTarget,
+        DragSource {
+
+    public class DDWrapperTransferable implements ComponentTransferable {
+        private final Map<String, Object> rawVariables;
+
+        private DDWrapperTransferable(Map<String, Object> rawVariables) {
+            this.rawVariables = rawVariables;
+        }
+
+        public void setData(String dataFlawor, Object value) {
+            // TODO Auto-generated method stub
+
+        }
+
+        public Collection<String> getDataFlawors() {
+            return rawVariables.keySet();
+        }
+
+        public Object getData(String dataFlawor) {
+            return rawVariables.get(dataFlawor);
+        }
+
+        public Component getSourceComponent() {
+            return DragAndDropWrapper.this;
+        }
+
+        /**
+         * The component in wrapper that is being dragged or null if the
+         * transferrable is not a component (most likely an html5 drag).
+         * 
+         * @return
+         */
+        public Component getDraggedComponent() {
+            Component object = (Component) rawVariables.get("component");
+            return object;
+        }
+    }
+
+    public enum DragStartMode {
+        NONE, COMPONENT, WRAPPER
+    }
+
+    private DragStartMode dragStartMode = DragStartMode.NONE;
+
+    public DragAndDropWrapper(Component root) {
+        super(root);
+    }
+
+    @Override
+    public void paintContent(PaintTarget target) throws PaintException {
+        super.paintContent(target);
+        target.addAttribute("dragStartMode", dragStartMode.ordinal());
+        if (getDropHandler() != null) {
+            getDropHandler().getAcceptCriterion().paint(target);
+        }
+    }
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    private DropHandler dropHandler;
+
+    public DropHandler getDropHandler() {
+        return dropHandler;
+    }
+
+    public void setDropHandler(DropHandler dropHandler) {
+        this.dropHandler = dropHandler;
+        requestRepaint();
+    }
+
+    public TargetDetails translateDragDropDetails(
+            Map<String, Object> clientVariables) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Transferable getTransferable(Transferable transferable,
+            final Map<String, Object> rawVariables) {
+        return new DDWrapperTransferable(rawVariables);
+    }
+
+    public void setDragStartMode(DragStartMode dragStartMode) {
+        this.dragStartMode = dragStartMode;
+        requestRepaint();
+    }
+
+    public DragStartMode getDragStartMode() {
+        return dragStartMode;
+    }
+}
index 24c366156cfdaa89a3324564daef772baf5162ff..923c5945519ab062b3f0a15e12a47011231e5824 100644 (file)
@@ -78,7 +78,12 @@ public class DragDropPane extends AbsoluteLayout implements DropTarget {
             Transferable transferable = event.getTransferable();
             if (transferable instanceof ComponentTransferable) {
                 ComponentTransferable ctr = (ComponentTransferable) transferable;
-                Component component = ctr.getSourceComponent();
+                // use "component" (from DragDropPane) if available, else take
+                // the source component
+                Component component = (Component) ctr.getData("component");
+                if (component == null) {
+                    component = ctr.getSourceComponent();
+                }
 
                 if (component.getParent() != pane) {
                     if (transferable instanceof DataBoundTransferable) {
index 49f47da436d9f7c07c5ed03f0af501d57ecb8ac4..0fad439afed9bad62b73457923f42ab3fdffd23c 100644 (file)
@@ -74,7 +74,8 @@ public class DDTest1 extends TestBase {
                     if (transferable instanceof ComponentTransferable) {
                         ComponentTransferable ct = (ComponentTransferable) transferable;
 
-                        Component component = ct.getSourceComponent();
+                        Component component = (Component) ct
+                                .getData("component");
                         if (component != null) {
                             if (component.toString() != null
                                     && component.toString().contains("Bar")) {
diff --git a/tests/src/com/vaadin/tests/dd/DDTest5.java b/tests/src/com/vaadin/tests/dd/DDTest5.java
new file mode 100644 (file)
index 0000000..6150808
--- /dev/null
@@ -0,0 +1,170 @@
+package com.vaadin.tests.dd;
+
+import java.util.Iterator;
+
+import com.vaadin.event.dd.DropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.DropTarget;
+import com.vaadin.event.dd.acceptCriteria.AcceptAll;
+import com.vaadin.event.dd.acceptCriteria.AcceptCriterion;
+import com.vaadin.terminal.ThemeResource;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.DragAndDropWrapper.DDWrapperTransferable;
+import com.vaadin.ui.DragAndDropWrapper.DragStartMode;
+
+public class DDTest5 extends TestBase {
+
+    java.util.Random r = new java.util.Random(1);
+
+    HorizontalLayout hl = new HorizontalLayout();
+
+    private DragAndDropWrapper dragAndDropWrapper2;
+
+    private DropHandler dh;
+
+    private static int count;
+
+    class WrappedLabel extends DragAndDropWrapper {
+
+        private static final long serialVersionUID = 1L;
+
+        public WrappedLabel(String content) {
+            super(new Label(content + " c:" + ++count));
+            setDragStartMode(DragStartMode.WRAPPER);
+        }
+
+        @Override
+        public DropHandler getDropHandler() {
+            return dh;
+        }
+
+    }
+
+    @Override
+    protected void setup() {
+        Window w = getLayout().getWindow();
+
+        Label l;
+
+        l = new Label("Drag me");
+        DragAndDropWrapper dragAndDropWrapper = new DragAndDropWrapper(l);
+        dragAndDropWrapper.setDragStartMode(DragStartMode.COMPONENT);
+        dragAndDropWrapper.setWidth("100px");
+        dragAndDropWrapper.setHeight("100px");
+        getLayout().addComponent(dragAndDropWrapper);
+
+        l = new Label("Drag me too");
+        dragAndDropWrapper = new DragAndDropWrapper(l);
+        dragAndDropWrapper.setDragStartMode(DragStartMode.WRAPPER);
+        dragAndDropWrapper.setWidth("100px");
+        dragAndDropWrapper.setHeight("100px");
+        getLayout().addComponent(dragAndDropWrapper);
+
+        final CssLayout cssLayout = new CssLayout();
+        cssLayout.setHeight("300px");
+
+        dragAndDropWrapper2 = new DragAndDropWrapper(cssLayout);
+        dragAndDropWrapper2.setCaption("Drop here");
+
+        dh = new DropHandler() {
+
+            public AcceptCriterion getAcceptCriterion() {
+                return AcceptAll.get();
+            }
+
+            public void drop(DropEvent dropEvent) {
+
+                /*
+                 * TODO wrap componentns in wrappers (so we can build reordering
+                 * here)
+                 */
+
+                if (dropEvent.getTransferable() instanceof DDWrapperTransferable) {
+                    DDWrapperTransferable transferable = (DDWrapperTransferable) dropEvent
+                            .getTransferable();
+                    Component sourceComponent = transferable
+                            .getSourceComponent();
+
+                    Component draggedComponent = transferable
+                            .getDraggedComponent();
+
+                    DropTarget target = dropEvent.getDropTargetData()
+                            .getTarget();
+
+                    WrappedLabel wrappedLabel = new WrappedLabel(
+                            draggedComponent.toString());
+                    if (target instanceof WrappedLabel) {
+                        int i = 1; // add next to reference by default
+                        Iterator<Component> componentIterator = cssLayout
+                                .getComponentIterator();
+                        Component next = componentIterator.next();
+                        while (next != target && componentIterator.hasNext()) {
+                            if (next != sourceComponent) {
+                                // don't count on index if component is being
+                                // moved
+                                i++;
+                            }
+                            next = componentIterator.next();
+                        }
+
+                        if (sourceComponent instanceof WrappedLabel) {
+                            cssLayout.removeComponent(sourceComponent);
+                            wrappedLabel = (WrappedLabel) sourceComponent;
+                        }
+                        if (dropEvent.getDropTargetData().getData(
+                                "verticalLocation").equals("Top")) {
+                            // before reference if dropped on topmost part
+                            i--;
+                            if (i < 0) {
+                                i = 0;
+                            }
+                        }
+                        cssLayout.addComponent(wrappedLabel, i);
+
+                    } else {
+                        cssLayout.addComponent(wrappedLabel);
+                    }
+
+                } else {
+                    // no component, add label with "Text"
+
+                    String data = (String) dropEvent.getTransferable().getData(
+                            "text/plain");
+                    if (data == null || "".equals(data)) {
+                        data = "-- no Text --";
+                    }
+                    cssLayout.addComponent(new WrappedLabel(data));
+
+                }
+
+            }
+        };
+
+        dragAndDropWrapper2.setDropHandler(dh);
+
+        getLayout().addComponent(dragAndDropWrapper2);
+
+    }
+
+    private final static ThemeResource FOLDER = new ThemeResource(
+            "../runo/icons/16/folder.png");
+    private final static ThemeResource DOC = new ThemeResource(
+            "../runo/icons/16/document.png");
+
+    @Override
+    protected String getDescription() {
+        return "dd";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 119;
+    }
+
+}