]> source.dussan.org Git - vaadin-framework.git/commitdiff
merged fix for #6320
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Wed, 20 Apr 2011 13:49:32 +0000 (13:49 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Wed, 20 Apr 2011 13:49:32 +0000 (13:49 +0000)
svn changeset:18415/svn branch:6.6

src/com/vaadin/ui/Tree.java
tests/src/com/vaadin/tests/dd/TreeDragStart.java [new file with mode: 0644]

index 79ce7cf47fd1768fbb946a86505c2d408f93ad3f..523f3fe739ad99e32d2c732e7edfc70fb84f2af0 100644 (file)
@@ -107,7 +107,7 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
      */
     public enum TreeDragMode {
         /**
-         * When drag mode is NONE, draggin from Tree is not supported. Browsers
+         * When drag mode is NONE, dragging from Tree is not supported. Browsers
          * may still support selecting text/icons from Tree which can initiate
          * HTML 5 style drag and drop operation.
          */
@@ -1293,6 +1293,7 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
      */
     public void setDragMode(TreeDragMode dragMode) {
         this.dragMode = dragMode;
+        requestRepaint();
     }
 
     /**
diff --git a/tests/src/com/vaadin/tests/dd/TreeDragStart.java b/tests/src/com/vaadin/tests/dd/TreeDragStart.java
new file mode 100644 (file)
index 0000000..4a719bf
--- /dev/null
@@ -0,0 +1,324 @@
+package com.vaadin.tests.dd;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.data.util.HierarchicalContainer;
+import com.vaadin.event.DataBoundTransferable;
+import com.vaadin.event.dd.DragAndDropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.event.dd.acceptcriteria.Not;
+import com.vaadin.event.dd.acceptcriteria.Or;
+import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
+import com.vaadin.ui.AbstractSelect.VerticalLocationIs;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.TableDragMode;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.Tree.TreeDragMode;
+import com.vaadin.ui.Tree.TreeTargetDetails;
+
+public class TreeDragStart extends TestBase {
+
+    @Override
+    protected void setup() {
+        final Tree tree = new Tree("Inventory");
+
+        CheckBox checkBox = new CheckBox("Enabled");
+        checkBox.setImmediate(true);
+        checkBox.setValue(true);
+        checkBox.addListener(new ValueChangeListener() {
+            public void valueChange(ValueChangeEvent event) {
+                tree.setEnabled(!tree.isEnabled());
+            }
+        });
+        addComponent(checkBox);
+        checkBox = new CheckBox("Drag start");
+        checkBox.setImmediate(true);
+        checkBox.setValue(true);
+        checkBox.addListener(new ValueChangeListener() {
+            public void valueChange(ValueChangeEvent event) {
+                if (((CheckBox) event.getProperty()).booleanValue()) {
+                    tree.setDragMode(TreeDragMode.NODE);
+                } else {
+                    tree.setDragMode(TreeDragMode.NONE);
+                }
+            }
+        });
+        addComponent(checkBox);
+
+        tree.setContainerDataSource(createTreeContent());
+        tree.setItemCaptionMode(Tree.ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID);
+        for (Object item : tree.getItemIds().toArray()) {
+            tree.setItemCaption(item, (String) ((BeanItem<?>) item)
+                    .getItemProperty("name").getValue());
+        }
+        getLayout().addComponent(tree);
+
+        // Expand all items
+        for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) {
+            tree.expandItemsRecursively(it.next());
+        }
+
+        // Set the tree in drag source mode
+        tree.setDragMode(TreeDragMode.NODE);
+
+        // Allow the tree to receive drag drops and handle them
+        tree.setDropHandler(new DropHandler() {
+            public AcceptCriterion getAcceptCriterion() {
+                // Accept drops in the middle of container items
+                // and below and above all items.
+                return new Or(Tree.TargetItemAllowsChildren.get(), new Not(
+                        VerticalLocationIs.MIDDLE));
+            }
+
+            public void drop(DragAndDropEvent event) {
+                // Wrapper for the object that is dragged
+                DataBoundTransferable t = (DataBoundTransferable) event
+                        .getTransferable();
+
+                TreeTargetDetails target = (TreeTargetDetails) event
+                        .getTargetDetails();
+
+                // Get ids of the dragged item and the target item
+                Object sourceItemId = t.getData("itemId");
+                Object targetItemId = target.getItemIdOver();
+
+                // On which side of the target the item was dropped
+                VerticalDropLocation location = target.getDropLocation();
+
+                HierarchicalContainer container = (HierarchicalContainer) tree
+                        .getContainerDataSource();
+
+                BeanItem<?> beanItem = null;
+                if (sourceItemId instanceof BeanItem<?>) {
+                    beanItem = (BeanItem<?>) sourceItemId;
+                } else if (sourceItemId instanceof InventoryObject) {
+                    beanItem = new BeanItem<InventoryObject>(
+                            (InventoryObject) sourceItemId);
+                }
+
+                // Remove the item from the source container and
+                // add it to the tree's container
+                Container sourceContainer = t.getSourceContainer();
+                sourceContainer.removeItem(sourceItemId);
+                tree.addItem(beanItem);
+                InventoryObject bean = (InventoryObject) beanItem.getBean();
+                tree.setChildrenAllowed(beanItem, bean.isContainer());
+
+                // Drop right on an item -> make it a child
+                if (location == VerticalDropLocation.MIDDLE) {
+                    tree.setParent(beanItem, targetItemId);
+                } else if (location == VerticalDropLocation.TOP) {
+                    Object parentId = container.getParent(targetItemId);
+                    tree.setParent(beanItem, parentId);
+                    container.moveAfterSibling(beanItem, targetItemId);
+                    container.moveAfterSibling(targetItemId, beanItem);
+                }
+
+                // Drop below another item -> make it next
+                else if (location == VerticalDropLocation.BOTTOM) {
+                    Object parentId = container.getParent(targetItemId);
+                    tree.setParent(beanItem, parentId);
+                    container.moveAfterSibling(beanItem, targetItemId);
+                }
+
+                tree.setItemCaption(beanItem, bean.getName());
+            }
+        });
+
+        // Have a table that allows dragging from
+        final Table table = new Table("Inventory List");
+        table.setDragMode(TableDragMode.ROW);
+
+        // Initialize the table container
+        ArrayList<InventoryObject> collection = new ArrayList<InventoryObject>();
+        collection.add(new InventoryObject("Dummy Item", 0.0, false));
+        final BeanItemContainer<InventoryObject> tableContainer = new BeanItemContainer<InventoryObject>(
+                collection);
+        table.setContainerDataSource(tableContainer);
+        table.setVisibleColumns(new String[] { "name", "weight" });
+        table.removeAllItems();
+
+        // Allow the table to receive drops and handle them
+        table.setDropHandler(new DropHandler() {
+            public AcceptCriterion getAcceptCriterion() {
+                return new Not(VerticalLocationIs.MIDDLE);
+            }
+
+            public void drop(DragAndDropEvent event) {
+                // Wrapper for the object that is dragged
+                DataBoundTransferable t = (DataBoundTransferable) event
+                        .getTransferable();
+
+                // Make sure the drag source is the same tree
+                if (t.getSourceComponent() != tree
+                        && t.getSourceComponent() != table) {
+                    return;
+                }
+
+                AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event
+                        .getTargetDetails();
+
+                // Get ids of the dragged item and the target item
+                Object sourceItemId = t.getData("itemId");
+                Object targetItemId = target.getItemIdOver();
+
+                // Do not allow drop on the item itself
+                if (sourceItemId.equals(targetItemId)) {
+                    return;
+                }
+
+                InventoryObject bean = null;
+                if (sourceItemId instanceof BeanItem<?>) {
+                    bean = (InventoryObject) ((BeanItem<?>) sourceItemId)
+                            .getBean();
+                } else if (sourceItemId instanceof InventoryObject) {
+                    bean = (InventoryObject) sourceItemId;
+                }
+
+                // Remove the item from the source container
+                t.getSourceContainer().removeItem(sourceItemId);
+
+                // On which side of the target the item was dropped
+                VerticalDropLocation location = target.getDropLocation();
+
+                // The table was empty or otherwise not on an item
+                if (targetItemId == null) {
+                    tableContainer.addItem(bean); // Add to the end
+                } else if (location == VerticalDropLocation.TOP) {
+                    tableContainer.addItemAt(
+                            tableContainer.indexOfId(targetItemId), bean);
+                } else if (location == VerticalDropLocation.BOTTOM) {
+                    tableContainer.addItemAfter(targetItemId, bean);
+                }
+            }
+        });
+        getLayout().addComponent(table);
+    }
+
+    public class InventoryObject implements Serializable {
+        private static final long serialVersionUID = -8943498783302996516L;
+
+        String name;
+        double weight;
+        boolean container;
+
+        public InventoryObject(String name, double weight, boolean container) {
+            this.name = name;
+            this.weight = weight;
+            this.container = container;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public double getWeight() {
+            return weight;
+        }
+
+        public void setWeight(double weight) {
+            this.weight = weight;
+        }
+
+        public boolean isContainer() {
+            return container;
+        }
+
+        public void setContainer(boolean container) {
+            this.container = container;
+        }
+    }
+
+    HashMap<String, InventoryObject> inventoryStore = new HashMap<String, InventoryObject>();
+
+    public HierarchicalContainer createTreeContent() {
+        final Object[] inventory = new Object[] {
+                new InventoryObject("root", 0.0, true),
+                new InventoryObject("+5 Quarterstaff (blessed)", 3.5, false),
+                new InventoryObject("+3 Elven Dagger (blessed)", 0.2, false),
+                new InventoryObject("+5 Helmet (greased)", 1.5, false),
+                new Object[] {
+                        new InventoryObject("Sack", 0.2, true),
+                        new InventoryObject("Pick-Axe", 2.5, false),
+                        new InventoryObject("Lock Pick", 0.1, false),
+                        new InventoryObject("Tinning Kit", 0.5, false),
+                        new InventoryObject("Potion of Healing (blessed)", 0.7,
+                                false), },
+                new Object[] {
+                        new InventoryObject("Bag of Holding", 0.1, true),
+                        new InventoryObject("Magic Marker", 0.05, false),
+                        new InventoryObject("Can of Grease (blessed)", 0.5,
+                                false), },
+                new Object[] {
+                        new InventoryObject("Chest", 10.0, true),
+                        new InventoryObject("Scroll of Identify", 0.1, false),
+                        new InventoryObject("Scroll of Genocide", 0.1, false),
+                        new InventoryObject("Towel", 0.3, false),
+                        new Object[] {
+                                new InventoryObject("Large Box", 8.0, true),
+                                new InventoryObject("Figurine of Vaadin", 0.4,
+                                        false),
+                                new InventoryObject("Expensive Camera", 1.5,
+                                        false), },
+                        new InventoryObject("Tin Opener", 0.02, false), }, };
+
+        HierarchicalContainer container = new HierarchicalContainer();
+
+        new Object() {
+            public void put(Object[] data, Object parent,
+                    HierarchicalContainer container) {
+                for (int i = 1; i < data.length; i++) {
+                    BeanItem<InventoryObject> item;
+                    if (data[i].getClass() == InventoryObject.class) {
+                        InventoryObject object = (InventoryObject) data[i];
+                        item = new BeanItem<InventoryObject>(object);
+                        container.addItem(item);
+                        container.setParent(item, parent);
+                        container.setChildrenAllowed(item, false);
+                    } else {// It's an Object[]
+                        Object[] sub = (Object[]) data[i];
+                        InventoryObject object = (InventoryObject) sub[0];
+                        item = new BeanItem<InventoryObject>(object);
+                        container.addItem(item);
+                        container.setParent(item, parent);
+
+                        // Add children recursively
+                        put(sub, item, container);
+                    }
+
+                    inventoryStore
+                            .put(item.getBean().getName(), item.getBean());
+                }
+            }
+        }.put(inventory, null, container);
+
+        return container;
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Should work";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 6320;
+    }
+
+}