From 360c553e7794119aa4514626325e47c539b6b8e9 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Wed, 10 Mar 2010 16:41:11 +0000 Subject: [PATCH] small enhancements + developing web desktop test svn changeset:11757/svn branch:6.3 --- .../acceptCriteria/IsSameSourceAndTarget.java | 12 + .../gwt/client/ui/VDragAndDropWrapper.java | 13 +- src/com/vaadin/ui/AbsoluteLayout.java | 5 + src/com/vaadin/ui/DragAndDropWrapper.java | 15 +- tests/src/com/vaadin/tests/dd/DDTest6.java | 262 +++++++++++++++++- .../HorizontalLayoutSortableWithWrappers.java | 8 +- 6 files changed, 292 insertions(+), 23 deletions(-) diff --git a/src/com/vaadin/event/dd/acceptCriteria/IsSameSourceAndTarget.java b/src/com/vaadin/event/dd/acceptCriteria/IsSameSourceAndTarget.java index 73609e592b..5f4d3db116 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/IsSameSourceAndTarget.java +++ b/src/com/vaadin/event/dd/acceptCriteria/IsSameSourceAndTarget.java @@ -21,6 +21,11 @@ import com.vaadin.ui.Component; @ClientCriterion(VSourceIsSameAsTarget.class) public class IsSameSourceAndTarget extends ClientSideCriterion { + private static IsSameSourceAndTarget instance; + + private IsSameSourceAndTarget() { + } + public boolean accepts(DragAndDropEvent dragEvent) { if (dragEvent.getTransferable() instanceof TransferableImpl) { Component sourceComponent = ((TransferableImpl) dragEvent @@ -32,4 +37,11 @@ public class IsSameSourceAndTarget extends ClientSideCriterion { return false; } + public static IsSameSourceAndTarget get() { + if (instance == null) { + instance = new IsSameSourceAndTarget(); + } + return instance; + } + } \ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java index 65130d7813..17bee7f318 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java @@ -53,15 +53,18 @@ public class VDragAndDropWrapper extends VCustomComponent implements // COMPONENT VTransferable transferable = new VTransferable(); transferable.setDragSource(VDragAndDropWrapper.this); - Paintable paintable = client.getPaintable((Element) event - .getNativeEvent().getEventTarget().cast()); + + Paintable paintable; + Widget w = Util.findWidget((Element) event.getNativeEvent() + .getEventTarget().cast(), null); + while (w != null && !(w instanceof Paintable)) { + w = w.getParent(); + } + paintable = (Paintable) w; transferable.setData("component", paintable); VDragEvent startDrag = VDragAndDropManager.get().startDrag( transferable, event.getNativeEvent(), true); - if (dragStarMode == WRAPPER || paintable == null) { - paintable = VDragAndDropWrapper.this; - } transferable.setData("mouseDown", new MouseEventDetails( event.getNativeEvent()).serialize()); diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index e8a6ae5a9d..b2f0f5539f 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -341,6 +341,11 @@ public class AbsoluteLayout extends AbstractLayout { return zIndex; } + @Override + public String toString() { + return getCSSString(); + } + } @Override diff --git a/src/com/vaadin/ui/DragAndDropWrapper.java b/src/com/vaadin/ui/DragAndDropWrapper.java index aab3155262..848e728bae 100644 --- a/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/src/com/vaadin/ui/DragAndDropWrapper.java @@ -5,8 +5,8 @@ package com.vaadin.ui; import java.util.Map; -import com.vaadin.event.TransferableImpl; import com.vaadin.event.Transferable; +import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragSource; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropTarget; @@ -98,7 +98,18 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, } public enum DragStartMode { - NONE, COMPONENT, WRAPPER + /** + * {@link DragAndDropWrapper} does not start drag events at all + */ + NONE, + /** + * The component on which the drag started will be shown as drag image. + */ + COMPONENT, + /** + * The whole wrapper is used as a drag image when dragging. + */ + WRAPPER } private DragStartMode dragStartMode = DragStartMode.NONE; diff --git a/tests/src/com/vaadin/tests/dd/DDTest6.java b/tests/src/com/vaadin/tests/dd/DDTest6.java index a00f411334..39d1f1fb7b 100644 --- a/tests/src/com/vaadin/tests/dd/DDTest6.java +++ b/tests/src/com/vaadin/tests/dd/DDTest6.java @@ -1,23 +1,43 @@ package com.vaadin.tests.dd; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import com.google.gwt.dev.util.collect.HashSet; +import com.vaadin.data.Property; +import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.data.util.ContainerHierarchicalWrapper; import com.vaadin.event.Action; import com.vaadin.event.DataBoundTransferable; import com.vaadin.event.Action.Handler; +import com.vaadin.event.LayoutEvents.LayoutClickEvent; +import com.vaadin.event.LayoutEvents.LayoutClickListener; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptCriteria.AcceptAll; import com.vaadin.event.dd.acceptCriteria.AcceptCriterion; +import com.vaadin.event.dd.acceptCriteria.IsSameSourceAndTarget; +import com.vaadin.event.dd.acceptCriteria.Not; import com.vaadin.terminal.Resource; import com.vaadin.terminal.ThemeResource; +import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.tests.components.TestBase; import com.vaadin.tests.util.TestUtils; +import com.vaadin.ui.AbsoluteLayout; +import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.Embedded; +import com.vaadin.ui.Label; import com.vaadin.ui.SplitPanel; import com.vaadin.ui.Tree; +import com.vaadin.ui.AbsoluteLayout.ComponentPosition; import com.vaadin.ui.Tree.TreeDragMode; import com.vaadin.ui.Tree.TreeDropTargetDetails; +import com.vaadin.ui.Tree.TreeTransferable; public class DDTest6 extends TestBase { @@ -29,18 +49,27 @@ public class DDTest6 extends TestBase { private DropHandler dh; + private static Tree tree1; + + private SplitPanel sp; + private static int count; + private static DDTest6 instance; + @Override protected void setup() { - SplitPanel sp = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); + instance = this; // Note, test only works with single app per server if + // get() + // not converted to thread local + sp = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); + sp.setSplitPosition(20); CssLayout l = new CssLayout(); sp.setFirstComponent(l); - CssLayout l2 = new CssLayout(); - sp.setSecondComponent(l2); - final Tree tree1 = new Tree("Volume 1"); + tree1 = new Tree("Volume 1"); + tree1.setImmediate(true); BeanItemContainer fs1 = new BeanItemContainer(File.class); tree1.setContainerDataSource(fs1); @@ -66,14 +95,22 @@ public class DDTest6 extends TestBase { } public void drop(DragAndDropEvent dropEvent) { - DataBoundTransferable transferable = (DataBoundTransferable) dropEvent - .getTransferable(); + File file = null; + Folder folder = null; TreeDropTargetDetails dropTargetData = (TreeDropTargetDetails) dropEvent .getDropTargetDetails(); - - tree1.setParent(transferable.getItemId(), dropTargetData - .getItemIdInto()); - + folder = (Folder) dropTargetData.getItemIdInto(); + if (dropEvent.getTransferable() instanceof DataBoundTransferable) { + DataBoundTransferable transferable = (DataBoundTransferable) dropEvent + .getTransferable(); + file = (File) transferable.getItemId(); + } else if (dropEvent.getTransferable().getSourceComponent() instanceof FileIcon) { + FileIcon draggedIcon = (FileIcon) dropEvent + .getTransferable().getSourceComponent(); + file = draggedIcon.file; + + } + setParent(file, folder); } }; @@ -95,14 +132,29 @@ public class DDTest6 extends TestBase { }; tree1.addActionHandler(actionHandler); + tree1.addListener(new Property.ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { + Object value = event.getProperty().getValue(); + if (value != null && !(value instanceof Folder)) { + value = tree1.getParent(value); + } + FolderView folderView = FolderView.get((Folder) value); + sp.setSecondComponent(folderView); + folderView.reload(); + } + }); + l.addComponent(tree1); + sp.setSecondComponent(FolderView.get(null)); + getLayout().setSizeFull(); getLayout().addComponent(sp); TestUtils .injectCSS( getLayout().getWindow(), "" + + ".v-tree .v-icon {height:16px;} " + ".v-tree-node-caption-drag-top {/*border-top: none;*/} " + ".v-tree-node-caption-drag-bottom {border-bottom: none ;} " + ".v-tree-node-caption-drag-center {background-color: transparent;}" @@ -111,9 +163,9 @@ public class DDTest6 extends TestBase { } private final static ThemeResource FOLDER = new ThemeResource( - "../runo/icons/16/folder.png"); + "../runo/icons/64/folder.png"); private final static ThemeResource DOC = new ThemeResource( - "../runo/icons/16/document.png"); + "../runo/icons/64/document.png"); public static class File { private Resource icon = DOC; @@ -159,4 +211,190 @@ public class DDTest6 extends TestBase { return 119; } + static class FolderView extends DragAndDropWrapper implements DropHandler { + + static final HashMap views = new HashMap(); + + public static FolderView get(Folder f) { + + FolderView folder2 = views.get(f); + if (folder2 == null) { + folder2 = new FolderView(f); + views.put(f, folder2); + } + return folder2; + } + + private Folder folder; + private AbsoluteLayout l; + private int x; + private int y; + + private FolderView(Folder f) { + super(new AbsoluteLayout()); + l = (AbsoluteLayout) getCompositionRoot(); + setSizeFull(); + l.setSizeFull(); + folder = f; + + setDropHandler(this); + } + + @Override + public void attach() { + reload(); + super.attach(); + } + + void reload() { + Collection children = folder == null ? DDTest6.get().tree1 + .rootItemIds() : DDTest6.get().tree1.getChildren(folder); + if (children == null) { + l.removeAllComponents(); + return; + } else { + // make modifiable + children = new HashSet(children); + } + Set removed = new HashSet(); + for (Iterator componentIterator = l + .getComponentIterator(); componentIterator.hasNext();) { + FileIcon next = (FileIcon) componentIterator.next(); + if (!children.contains(next.file)) { + removed.add(next); + } else { + children.remove(next.file); + } + } + + for (Component component : removed) { + l.removeComponent(component); + } + + for (Object object : children) { + FileIcon fileIcon = new FileIcon((File) object); + l.addComponent(fileIcon); + ComponentPosition position = l.getPosition(fileIcon); + position.setTop((y++ / 5) % 5 * 100, UNITS_PIXELS); + position.setLeft(x++ % 5 * 100, UNITS_PIXELS); + } + + } + + public void drop(DragAndDropEvent dropEvent) { + + if (dropEvent.getTransferable().getSourceComponent() instanceof FileIcon) { + // update the position + + DragAndDropWrapper.WrapperTransferable transferable = (WrapperTransferable) dropEvent + .getTransferable(); + MouseEventDetails mouseDownEvent = transferable + .getMouseDownEvent(); + + WrapperDropDetails dropTargetDetails = (WrapperDropDetails) dropEvent + .getDropTargetDetails(); + MouseEventDetails mouseEvent = dropTargetDetails + .getMouseEvent(); + + int deltaX = mouseEvent.getClientX() + - mouseDownEvent.getClientX(); + int deltaY = mouseEvent.getClientY() + - mouseDownEvent.getClientY(); + + ComponentPosition position = l.getPosition(transferable + .getSourceComponent()); + position.setTop(position.getTopValue() + deltaY, UNITS_PIXELS); + position + .setLeft(position.getLeftValue() + deltaX, UNITS_PIXELS); + + } else if (dropEvent.getTransferable().getSourceComponent() == tree1) { + + // dragged something from tree to the folder shown + + File draggedFile = (File) ((TreeTransferable) dropEvent + .getTransferable()).getItemId(); + DDTest6.get().setParent(draggedFile, folder); + } + } + + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } + + } + + static class FileIcon extends DragAndDropWrapper { + private final File file; + private CssLayout l; + + public FileIcon(final File file) { + super(new CssLayout()); + l = (CssLayout) getCompositionRoot(); + setWidth(null); + l.setWidth(null); + setDragStartMode(DragStartMode.WRAPPER); // drag all contained + // components, not just the + // one on it started + this.file = file; + Resource icon2 = file.getIcon(); + String name = file.getName(); + l.addComponent(new Embedded(null, icon2)); + l.addComponent(new Label(name)); + + l.addListener(new LayoutClickListener() { + public void layoutClick(LayoutClickEvent event) { + if (file instanceof Folder) { + if (event.isDoubleClick()) { + get().tree1.setValue(file); + } + + } + + } + }); + + if (file instanceof Folder) { + + setDropHandler(new DropHandler() { + + public AcceptCriterion getAcceptCriterion() { + return new Not(IsSameSourceAndTarget.get()); + } + + public void drop(DragAndDropEvent dropEvent) { + File f = null; + + if (dropEvent.getTransferable().getSourceComponent() instanceof FileIcon) { + FileIcon new_name = (FileIcon) dropEvent + .getTransferable().getSourceComponent(); + f = new_name.file; + } else if (dropEvent.getTransferable() + .getSourceComponent() == tree1) { + f = (File) ((DataBoundTransferable) dropEvent + .getTransferable()).getItemId(); + } + // TODO accept drags from Tree too + + if (f != null) { + get().setParent(f, (Folder) FileIcon.this.file); + } + + } + }); + + } + } + } + + static DDTest6 get() { + return instance; + } + + public void setParent(File file, Folder newParent) { + tree1.setParent(file, newParent); + if (sp.getSecondComponent() instanceof FolderView) { + FolderView view = (FolderView) sp.getSecondComponent(); + view.reload(); + } + } } diff --git a/tests/src/com/vaadin/tests/dd/HorizontalLayoutSortableWithWrappers.java b/tests/src/com/vaadin/tests/dd/HorizontalLayoutSortableWithWrappers.java index 715fbe60e1..95011ffd42 100644 --- a/tests/src/com/vaadin/tests/dd/HorizontalLayoutSortableWithWrappers.java +++ b/tests/src/com/vaadin/tests/dd/HorizontalLayoutSortableWithWrappers.java @@ -2,8 +2,8 @@ package com.vaadin.tests.dd; import java.util.Iterator; -import com.vaadin.event.TransferableImpl; import com.vaadin.event.Transferable; +import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropTarget; @@ -11,8 +11,8 @@ import com.vaadin.event.dd.DropTargetDetails; import com.vaadin.event.dd.acceptCriteria.AcceptCriterion; import com.vaadin.event.dd.acceptCriteria.And; import com.vaadin.event.dd.acceptCriteria.DropTargetDetailEquals; -import com.vaadin.event.dd.acceptCriteria.Not; import com.vaadin.event.dd.acceptCriteria.IsSameSourceAndTarget; +import com.vaadin.event.dd.acceptCriteria.Not; import com.vaadin.ui.Component; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.HorizontalLayout; @@ -52,8 +52,8 @@ public class HorizontalLayoutSortableWithWrappers extends Window { private DropHandler dh = new DropHandler() { AcceptCriterion crit = new And(new DropTargetDetailEquals( - "horizontalLocation", "LEFT"), new Not( - new IsSameSourceAndTarget())); + "horizontalLocation", "LEFT"), new Not(IsSameSourceAndTarget + .get())); public AcceptCriterion getAcceptCriterion() { return crit; -- 2.39.5