aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatti Tahvonen <matti.tahvonen@itmill.com>2010-02-16 11:39:34 +0000
committerMatti Tahvonen <matti.tahvonen@itmill.com>2010-02-16 11:39:34 +0000
commit7affda148684f0359856eaba85a3d381aec7faa9 (patch)
treeeb4803daf93363b1faa724a44703dde65da851ab
parent020312bc89558c8c5a28840dc979c6b80f64f912 (diff)
downloadvaadin-framework-7affda148684f0359856eaba85a3d381aec7faa9.tar.gz
vaadin-framework-7affda148684f0359856eaba85a3d381aec7faa9.zip
styles, table drop handler, small changes
svn changeset:11339/svn branch:6.3_dd
-rw-r--r--WebContent/VAADIN/themes/base/styles.css30
-rw-r--r--WebContent/VAADIN/themes/base/table/table.css13
-rw-r--r--WebContent/VAADIN/themes/base/tree/tree.css12
-rw-r--r--WebContent/VAADIN/themes/reindeer/styles.css30
-rw-r--r--WebContent/VAADIN/themes/runo/styles.css30
-rw-r--r--src/com/vaadin/terminal/gwt/client/Util.java31
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java175
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTree.java62
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java16
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java52
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/dd/VerticalDropLocation.java24
-rw-r--r--src/com/vaadin/ui/Table.java64
-rw-r--r--src/com/vaadin/ui/Tree.java2
-rw-r--r--tests/src/com/vaadin/tests/dd/DDTest4.java131
14 files changed, 588 insertions, 84 deletions
diff --git a/WebContent/VAADIN/themes/base/styles.css b/WebContent/VAADIN/themes/base/styles.css
index f8cd9a8f8b..eca4525510 100644
--- a/WebContent/VAADIN/themes/base/styles.css
+++ b/WebContent/VAADIN/themes/base/styles.css
@@ -1,5 +1,5 @@
-.v-theme-version:after {content:"6_3_0_dev-20100215";}
-.v-theme-version-6_3_0_dev-20100215 {display: none;}
+.v-theme-version:after {content:"6_3_0_dev-20100216";}
+.v-theme-version-6_3_0_dev-20100216 {display: none;}
/* Automatically compiled css file from subdirectories. */
.v-absolutelayout-wrapper {
@@ -1330,6 +1330,19 @@ div.v-progressindicator-indeterminate-disabled {
padding: 0;
cursor: pointer;
}
+
+/* TODO remove important, replace with better anchors or order */
+.v-table tr.v-table-row-drag-center {
+ background-color: cyan !important;
+}
+/* TODO consider using height neutral styling (scrollbar issues when pagelength = table.length ) */
+.v-table-row-drag-top .v-table-cell-content {
+ border-top: 1px solid cyan ;
+}
+.v-table-row-drag-bottom .v-table-cell-content {
+ border-bottom: 1px solid cyan;
+}
+
.v-table-body-noselection .v-table-row,
.v-table-body-noselection .v-table-row-odd {
cursor: default;
@@ -1602,10 +1615,23 @@ div.v-tree-node-leaf {
.v-tree-node-caption .v-icon {
vertical-align: middle;
}
+
.v-tree-node-selected span {
background: #999;
color: #fff;
}
+
+.v-tree-node-drag-top .v-tree-node-caption {
+ border-top:2px solid green;
+}
+.v-tree-node-drag-bottom .v-tree-node-caption {
+ border-bottom:2px solid green;
+}
+.v-tree-node-drag-center .v-tree-node-caption {
+ background-color:green;
+}
+
+
.v-tree-node-children {
padding-left: 1em;
}
diff --git a/WebContent/VAADIN/themes/base/table/table.css b/WebContent/VAADIN/themes/base/table/table.css
index 7747cd14f1..235594493f 100644
--- a/WebContent/VAADIN/themes/base/table/table.css
+++ b/WebContent/VAADIN/themes/base/table/table.css
@@ -86,6 +86,19 @@
padding: 0;
cursor: pointer;
}
+
+/* TODO remove important, replace with better anchors or order */
+.v-table tr.v-table-row-drag-center {
+ background-color: cyan !important;
+}
+/* TODO consider using height neutral styling (scrollbar issues when pagelength = table.length ) */
+.v-table-row-drag-top .v-table-cell-content {
+ border-top: 1px solid cyan ;
+}
+.v-table-row-drag-bottom .v-table-cell-content {
+ border-bottom: 1px solid cyan;
+}
+
.v-table-body-noselection .v-table-row,
.v-table-body-noselection .v-table-row-odd {
cursor: default;
diff --git a/WebContent/VAADIN/themes/base/tree/tree.css b/WebContent/VAADIN/themes/base/tree/tree.css
index 21e41d74a0..8a6fc3b878 100644
--- a/WebContent/VAADIN/themes/base/tree/tree.css
+++ b/WebContent/VAADIN/themes/base/tree/tree.css
@@ -24,10 +24,22 @@ div.v-tree-node-leaf {
.v-tree-node-caption .v-icon {
vertical-align: middle;
}
+
.v-tree-node-selected span {
background: #999;
color: #fff;
}
+
+.v-tree-node-drag-top .v-tree-node-caption {
+ border-top:2px solid green;
+}
+.v-tree-node-drag-bottom .v-tree-node-caption {
+ border-bottom:2px solid green;
+}
+.v-tree-node-drag-center .v-tree-node-caption {
+ background-color:green;
+}
+
.v-tree-node-children {
padding-left: 1em;
}
diff --git a/WebContent/VAADIN/themes/reindeer/styles.css b/WebContent/VAADIN/themes/reindeer/styles.css
index eebbff3ee2..c4081182c8 100644
--- a/WebContent/VAADIN/themes/reindeer/styles.css
+++ b/WebContent/VAADIN/themes/reindeer/styles.css
@@ -1,5 +1,5 @@
-.v-theme-version:after {content:"6_3_0_dev-20100215";}
-.v-theme-version-6_3_0_dev-20100215 {display: none;}
+.v-theme-version:after {content:"6_3_0_dev-20100216";}
+.v-theme-version-6_3_0_dev-20100216 {display: none;}
/* Automatically compiled css file from subdirectories. */
.v-absolutelayout-wrapper {
@@ -1330,6 +1330,19 @@ div.v-progressindicator-indeterminate-disabled {
padding: 0;
cursor: pointer;
}
+
+/* TODO remove important, replace with better anchors or order */
+.v-table tr.v-table-row-drag-center {
+ background-color: cyan !important;
+}
+/* TODO consider using height neutral styling (scrollbar issues when pagelength = table.length ) */
+.v-table-row-drag-top .v-table-cell-content {
+ border-top: 1px solid cyan ;
+}
+.v-table-row-drag-bottom .v-table-cell-content {
+ border-bottom: 1px solid cyan;
+}
+
.v-table-body-noselection .v-table-row,
.v-table-body-noselection .v-table-row-odd {
cursor: default;
@@ -1602,10 +1615,23 @@ div.v-tree-node-leaf {
.v-tree-node-caption .v-icon {
vertical-align: middle;
}
+
.v-tree-node-selected span {
background: #999;
color: #fff;
}
+
+.v-tree-node-drag-top .v-tree-node-caption {
+ border-top:2px solid green;
+}
+.v-tree-node-drag-bottom .v-tree-node-caption {
+ border-bottom:2px solid green;
+}
+.v-tree-node-drag-center .v-tree-node-caption {
+ background-color:green;
+}
+
+
.v-tree-node-children {
padding-left: 1em;
}
diff --git a/WebContent/VAADIN/themes/runo/styles.css b/WebContent/VAADIN/themes/runo/styles.css
index 29929ae32e..8d07f54c53 100644
--- a/WebContent/VAADIN/themes/runo/styles.css
+++ b/WebContent/VAADIN/themes/runo/styles.css
@@ -1,5 +1,5 @@
-.v-theme-version:after {content:"6_3_0_dev-20100215";}
-.v-theme-version-6_3_0_dev-20100215 {display: none;}
+.v-theme-version:after {content:"6_3_0_dev-20100216";}
+.v-theme-version-6_3_0_dev-20100216 {display: none;}
/* Automatically compiled css file from subdirectories. */
.v-absolutelayout-wrapper {
@@ -1330,6 +1330,19 @@ div.v-progressindicator-indeterminate-disabled {
padding: 0;
cursor: pointer;
}
+
+/* TODO remove important, replace with better anchors or order */
+.v-table tr.v-table-row-drag-center {
+ background-color: cyan !important;
+}
+/* TODO consider using height neutral styling (scrollbar issues when pagelength = table.length ) */
+.v-table-row-drag-top .v-table-cell-content {
+ border-top: 1px solid cyan ;
+}
+.v-table-row-drag-bottom .v-table-cell-content {
+ border-bottom: 1px solid cyan;
+}
+
.v-table-body-noselection .v-table-row,
.v-table-body-noselection .v-table-row-odd {
cursor: default;
@@ -1602,10 +1615,23 @@ div.v-tree-node-leaf {
.v-tree-node-caption .v-icon {
vertical-align: middle;
}
+
.v-tree-node-selected span {
background: #999;
color: #fff;
}
+
+.v-tree-node-drag-top .v-tree-node-caption {
+ border-top:2px solid green;
+}
+.v-tree-node-drag-bottom .v-tree-node-caption {
+ border-bottom:2px solid green;
+}
+.v-tree-node-drag-center .v-tree-node-caption {
+ background-color:green;
+}
+
+
.v-tree-node-children {
padding-left: 1em;
}
diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java
index 9c6d998adc..5738e1ba49 100644
--- a/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/src/com/vaadin/terminal/gwt/client/Util.java
@@ -16,6 +16,8 @@ import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasWidgets;
@@ -845,4 +847,33 @@ public class Util {
}
}-*/;
+ /**
+ * Helper method to find first instance of given Widget type found by
+ * traversing DOM upwards.
+ *
+ * @param element
+ * @param class1
+ */
+ public static <T> T findWidget(Element element, Class class1) {
+ if (element != null) {
+ EventListener eventListener = null;
+ while (eventListener == null && element != null) {
+ eventListener = Event.getEventListener(element);
+ if (eventListener == null) {
+ element = (Element) element.getParentElement();
+ }
+ }
+ if (eventListener != null) {
+ Widget w = (Widget) eventListener;
+ while (w != null) {
+ if (class1 == null || w.getClass() == class1) {
+ return (T) w;
+ }
+ w = w.getParent();
+ }
+ }
+ }
+ return null;
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index f878dbd954..99e3ddb3ad 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -40,9 +40,13 @@ 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.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.VHasDropHandler;
import com.vaadin.terminal.gwt.client.ui.dd.VTransferable;
+import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
/**
* VScrollTable
@@ -67,7 +71,8 @@ import com.vaadin.terminal.gwt.client.ui.dd.VTransferable;
*
* TODO implement unregistering for child components in Cells
*/
-public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
+public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
+ VHasDropHandler {
public static final String CLASSNAME = "v-table";
public static final String ITEM_CLICK_EVENT_ID = "itemClick";
@@ -263,6 +268,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
}
UIDL rowData = null;
+ UIDL ac = null;
for (final Iterator it = uidl.getChildIterator(); it.hasNext();) {
final UIDL c = (UIDL) it.next();
if (c.getTag().equals("rows")) {
@@ -271,8 +277,21 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
updateActionMap(c);
} else if (c.getTag().equals("visiblecolumns")) {
tHead.updateCellsFromUIDL(c);
+ } else if (c.getTag().equals("-ac")) {
+ ac = c;
}
}
+ if (ac == null) {
+ if (dropHandler != null) {
+ // remove dropHandler if not present anymore
+ dropHandler = null;
+ }
+ } else {
+ if (dropHandler == null) {
+ dropHandler = new VScrollTableDropHandler();
+ }
+ dropHandler.updateAcceptRules(ac);
+ }
updateHeader(uidl.getStringArrayAttribute("vcolorder"));
if (!recalcWidths && initializedAndAttached) {
@@ -2921,6 +2940,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
private int contentAreaBorderHeight = -1;
private int scrollLeft;
private int scrollTop;
+ private VScrollTableDropHandler dropHandler;
/**
* @return border top + border bottom of the scrollable area of table
@@ -3099,4 +3119,157 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
}
}
+ public VScrollTableDropHandler getDropHandler() {
+ return dropHandler;
+ }
+
+ private static class TableDDDetails {
+ int overkey = -1;
+ VerticalDropLocation dropLocation;
+ String colkey;
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof TableDDDetails) {
+ TableDDDetails other = (TableDDDetails) obj;
+ return dropLocation == other.dropLocation
+ && overkey == other.overkey
+ && ((colkey != null && colkey.equals(other.colkey)) || (colkey == null && other.colkey == null));
+ }
+ return false;
+ }
+
+ // @Override
+ // public int hashCode() {
+ // return overkey;
+ // }
+ }
+
+ public class VScrollTableDropHandler extends VAbstractDropHandler {
+
+ private static final String ROWSTYLEBASE = "v-table-row-drag-";
+ private TableDDDetails dropDetails;
+ private TableDDDetails lastEmphasized;
+
+ @Override
+ public void dragEnter(VDragEvent drag) {
+ updateDropDetails(drag);
+ super.dragEnter(drag);
+ }
+
+ private void updateDropDetails(VDragEvent drag) {
+ dropDetails = new TableDDDetails();
+ Element elementOver = drag.getElementOver();
+
+ VScrollTableRow row = Util.findWidget(elementOver,
+ VScrollTableRow.class);
+ if (row != null) {
+ dropDetails.overkey = row.rowKey;
+ Element tr = row.getElement();
+ Element element = elementOver;
+ while (element != null && element.getParentElement() != tr) {
+ element = (Element) element.getParentElement();
+ }
+ int childIndex = DOM.getChildIndex(tr, element);
+ dropDetails.colkey = tHead.getHeaderCell(childIndex)
+ .getColKey();
+ dropDetails.dropLocation = VerticalDropLocation.get(row
+ .getElement(), drag.getCurrentGwtEvent().getClientY(),
+ 0.2);
+ }
+
+ drag.getDropDetails().put("itemIdOver", dropDetails.overkey + "");
+ drag.getDropDetails().put(
+ "detail",
+ dropDetails.dropLocation != null ? dropDetails.dropLocation
+ .toString() : null);
+
+ }
+
+ @Override
+ public void dragOver(VDragEvent drag) {
+ TableDDDetails oldDetails = dropDetails;
+ updateDropDetails(drag);
+ if (!oldDetails.equals(dropDetails)) {
+ deEmphasis();
+ VAcceptCallback cb = new VAcceptCallback() {
+ public void accepted(VDragEvent event) {
+ dragAccepted(event);
+ }
+ };
+ validate(cb, drag);
+ }
+ }
+
+ @Override
+ public void dragLeave(VDragEvent drag) {
+ deEmphasis();
+ super.dragLeave(drag);
+ }
+
+ @Override
+ public boolean drop(VDragEvent drag) {
+ deEmphasis();
+ return super.drop(drag);
+ }
+
+ private void deEmphasis() {
+ if (lastEmphasized == null) {
+ return;
+ }
+ for (Widget w : scrollBody.renderedRows) {
+ VScrollTableRow row = (VScrollTableRow) w;
+ if (lastEmphasized != null
+ && row.rowKey == lastEmphasized.overkey) {
+ if (row != null) {
+ String stylename = ROWSTYLEBASE
+ + lastEmphasized.dropLocation.toString()
+ .toLowerCase();
+ VScrollTableRow.setStyleName(row.getElement(),
+ stylename, false);
+ }
+ lastEmphasized = null;
+ return;
+ }
+ }
+ }
+
+ /**
+ * TODO needs different drop modes ?? (on cells, on rows), now only
+ * supports rows
+ */
+ private void emphasis(TableDDDetails details) {
+ deEmphasis();
+ // iterate old and new emphasized row
+ for (Widget w : scrollBody.renderedRows) {
+ VScrollTableRow row = (VScrollTableRow) w;
+ if (details != null && details.overkey == row.rowKey) {
+ if (row != null) {
+ String stylename = ROWSTYLEBASE
+ + details.dropLocation.toString().toLowerCase();
+ VScrollTableRow.setStyleName(row.getElement(),
+ stylename, true);
+ }
+ lastEmphasized = details;
+ return;
+ }
+ }
+ }
+
+ @Override
+ protected void dragAccepted(VDragEvent drag) {
+ emphasis(dropDetails);
+ }
+
+ @Override
+ public Paintable getPaintable() {
+ return VScrollTable.this;
+ }
+
+ public ApplicationConnection getApplicationConnection() {
+ return client;
+ }
+
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java
index 1a3edd32be..d0f50d2632 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java
@@ -10,14 +10,13 @@ import java.util.Iterator;
import java.util.Set;
import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
@@ -32,6 +31,7 @@ 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.VerticalDropLocation;
/**
*
@@ -179,25 +179,7 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
}
private String findCurrentMouseOverKey(Element elementOver) {
- TreeNode treeNode = null;
- Element curEl = elementOver;
- while (curEl != null) {
- try {
- EventListener eventListener = Event.getEventListener(curEl);
- if (eventListener != null) {
- // found a widget
- if (eventListener instanceof TreeNode) {
- treeNode = (TreeNode) eventListener;
- }
- break;
- } else {
- curEl = (Element) curEl.getParentElement();
- }
- } catch (Exception e) {
- ApplicationConnection.getConsole().log(e.getMessage());
- e.printStackTrace();
- }
- }
+ TreeNode treeNode = Util.findWidget(elementOver, TreeNode.class);
return treeNode == null ? null : treeNode.key;
}
@@ -290,24 +272,9 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
if (treeNode == null) {
return null;
}
- // TODO no scroll support
- int offsetHeight = treeNode.nodeCaptionDiv.getOffsetHeight();
- int absoluteTop = treeNode.getAbsoluteTop();
- int clientY = event.getClientY();
- int fromTop = clientY - absoluteTop;
-
- String detail;
- float percentageFromTop = (fromTop / (float) offsetHeight);
- if (percentageFromTop < 0.2) {
- detail = "Top";
- } else if (percentageFromTop > 0.8) {
- detail = "Bottom";
- } else {
- detail = "Center";
- }
-
- return detail;
-
+ VerticalDropLocation verticalDropLocation = VerticalDropLocation.get(
+ treeNode.getElement(), event.getClientY(), 0.2);
+ return verticalDropLocation.toString();
}
private void handleUpdate(UIDL uidl) {
@@ -387,16 +354,13 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
}
public void emphasis(String string) {
- // ApplicationConnection.getConsole().log("OUTLINE" + string);
- Style style = nodeCaptionDiv.getStyle();
- String top = "Top".equals(string) ? "2px solid green" : "";
- String bottom = "Bottom".equals(string) ? "2px solid green" : "";
- String bg = "Center".equals(string) ? "green" : "";
-
- style.setProperty("borderTop", top);
- style.setProperty("borderBottom", bottom);
- style.setBackgroundColor(bg);
-
+ String base = "v-tree-node-drag-";
+ UIObject.setStyleName(getElement(), base + "top", "Top"
+ .equals(string));
+ UIObject.setStyleName(getElement(), base + "bottom", "Bottom"
+ .equals(string));
+ UIObject.setStyleName(getElement(), base + "center", "Center"
+ .equals(string));
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java
index 74e4d4ca98..f6a3d09b71 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAbstractDropHandler.java
@@ -1,5 +1,7 @@
package com.vaadin.terminal.gwt.client.ui.dd;
+import java.util.Iterator;
+
import com.google.gwt.user.client.Command;
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DropTarget;
@@ -10,7 +12,7 @@ import com.vaadin.terminal.gwt.client.UIDL;
public abstract class VAbstractDropHandler implements VDropHandler {
private UIDL criterioUIDL;
- private VAcceptCriteria acceptCriteria;
+ private VAcceptCriteria acceptCriteria = new AcceptAll();
/**
* Implementor/user of {@link VAbstractDropHandler} must pass the UIDL
@@ -21,6 +23,16 @@ public abstract class VAbstractDropHandler implements VDropHandler {
*/
public void updateAcceptRules(UIDL uidl) {
criterioUIDL = uidl;
+ /*
+ * supports updating the accept rule root directly or so that it is
+ * contained in given uidl node
+ */
+ if (!uidl.getTag().equals("-ac")) {
+ Iterator<Object> childIterator = uidl.getChildIterator();
+ while (!uidl.getTag().equals("-ac") && childIterator.hasNext()) {
+ uidl = (UIDL) childIterator.next();
+ }
+ }
acceptCriteria = VAcceptCriterion.get(uidl.getStringAttribute("name"));
if (acceptCriteria == null) {
throw new IllegalArgumentException(
@@ -32,7 +44,7 @@ public abstract class VAbstractDropHandler implements VDropHandler {
/**
* Default implementation does nothing.
*/
- public void dragOver(VDragEvent currentDrag) {
+ public void dragOver(VDragEvent drag) {
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java
index 69053f45ec..8d301c70f2 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java
@@ -11,7 +11,6 @@ import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
@@ -66,8 +65,8 @@ public class VDragAndDropManager {
return;
} else {
- ApplicationConnection.getConsole().log(
- "Event on dragImage, target changed");
+ // ApplicationConnection.getConsole().log(
+ // "Event on dragImage, target changed");
// special handling for events over dragImage
// pretty much all events are mousemove althout below
// kind of happens mouseover
@@ -89,6 +88,13 @@ public class VDragAndDropManager {
}
// dragenter on new
currentDropHandler = findDragTarget;
+ if (findDragTarget != null) {
+ ApplicationConnection.getConsole().log(
+ "DropHandler now"
+ + currentDropHandler
+ .getPaintable());
+ }
+
if (currentDropHandler != null) {
currentDrag
.setElementOver((com.google.gwt.user.client.Element) targetElement);
@@ -114,10 +120,10 @@ public class VDragAndDropManager {
}
}
- } catch (Exception e) {
+ } catch (RuntimeException e) {
ApplicationConnection.getConsole().log(
- "FIXME : ERROR in elementFromPoint hack.");
- throw new RuntimeException(e);
+ "ERROR during elementFromPoint hack.");
+ throw e;
} finally {
dragElement.getStyle().setProperty("display", display);
}
@@ -133,7 +139,11 @@ public class VDragAndDropManager {
if (currentDropHandler != null) {
currentDropHandler.dragLeave(currentDrag);
}
+
currentDropHandler = target;
+ ApplicationConnection.getConsole().log(
+ "DropHandler now"
+ + currentDropHandler.getPaintable());
target.dragEnter(currentDrag);
} else if (target == null && currentDropHandler != null) {
ApplicationConnection.getConsole().log("Invalid state!?");
@@ -402,25 +412,12 @@ public class VDragAndDropManager {
* @return
*/
private VDropHandler findDragTarget(Element element) {
- EventListener eventListener = Event.getEventListener(element);
- while (eventListener == null) {
- element = element.getParentElement();
- if (element == null) {
- break;
- }
- try {
- eventListener = Event.getEventListener(element);
- } catch (Exception e) {
- // CCE Should not happen but it does to me // MT 1.2.2010
- e.printStackTrace();
+ try {
+ Widget w = Util.findWidget(
+ (com.google.gwt.user.client.Element) element, null);
+ if (w == null) {
+ return null;
}
- }
- 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) {
@@ -439,7 +436,14 @@ public class VDragAndDropManager {
}
return dh;
}
+
+ } catch (Exception e) {
+ ApplicationConnection.getConsole().log(
+ "FIXME: Exception when detecting drop handler");
+ e.printStackTrace();
+ return null;
}
+
}
private void updateCurrentEvent(NativeEvent event) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VerticalDropLocation.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VerticalDropLocation.java
new file mode 100644
index 0000000000..8c1f1a7aa1
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VerticalDropLocation.java
@@ -0,0 +1,24 @@
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.google.gwt.user.client.Element;
+
+public enum VerticalDropLocation {
+ Top, Bottom, Center;
+
+ public static VerticalDropLocation get(Element element, int clientY,
+ double topBottomRatio) {
+
+ int absoluteTop = element.getAbsoluteTop();
+ int offsetHeight = element.getOffsetHeight();
+ int fromTop = clientY - absoluteTop;
+
+ float percentageFromTop = (fromTop / (float) offsetHeight);
+ if (percentageFromTop < topBottomRatio) {
+ return Top;
+ } else if (percentageFromTop > 1 - topBottomRatio) {
+ return Bottom;
+ } else {
+ return Center;
+ }
+ }
+}
diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java
index afc91d7bcf..aae0c95456 100644
--- a/src/com/vaadin/ui/Table.java
+++ b/src/com/vaadin/ui/Table.java
@@ -30,12 +30,17 @@ import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ItemClickEvent.ItemClickSource;
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.event.dd.TargetDetailsImpl;
import com.vaadin.terminal.KeyMapper;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.ui.VScrollTable;
+import com.vaadin.ui.Tree.Location;
/**
* <p>
@@ -57,7 +62,8 @@ import com.vaadin.terminal.gwt.client.ui.VScrollTable;
@SuppressWarnings("serial")
@ClientWidget(VScrollTable.class)
public class Table extends AbstractSelect implements Action.Container,
- Container.Ordered, Container.Sortable, ItemClickSource, DragSource {
+ Container.Ordered, Container.Sortable, ItemClickSource, DragSource,
+ DropTarget {
/**
* Modes that Table support as drag sourse.
@@ -339,6 +345,8 @@ public class Table extends AbstractSelect implements Action.Container,
private DragModes dragMode = DragModes.NONE;
+ private DropHandler dropHandler;
+
/* Table constructors */
/**
@@ -2372,6 +2380,10 @@ public class Table extends AbstractSelect implements Action.Container,
}
}
target.endTag("visiblecolumns");
+
+ if (dropHandler != null) {
+ dropHandler.getAcceptCriterion().paint(target);
+ }
}
/**
@@ -3367,4 +3379,54 @@ public class Table extends AbstractSelect implements Action.Container,
updateTransferable(rawVariables, transferable);
return (TableTransferable) transferable;
}
+
+ public DropHandler getDropHandler() {
+ return dropHandler;
+ }
+
+ public void setDropHandler(DropHandler dropHandler) {
+ this.dropHandler = dropHandler;
+ }
+
+ /*
+ * TODO add propertyId
+ */
+ public class TableTargetDetails extends TargetDetailsImpl {
+ private Object idOver;
+
+ public TableTargetDetails(Map<String, Object> rawDropData) {
+ super(rawDropData);
+ // eagar fetch itemid, mapper may be emptied
+ String keyover = (String) getData("itemIdOver");
+ if (keyover != null) {
+ idOver = itemIdMapper.get(keyover);
+ }
+ }
+
+ public Object getItemIdOver() {
+ return idOver;
+ }
+
+ public Location getDropLocation() {
+ String s = (String) getData("detail");
+ if ("Top".equals(s)) {
+ return Location.TOP;
+ } else if ("Bottom".equals(s)) {
+ return Location.BOTTOM;
+ } else {
+ return Location.MIDDLE;
+ }
+ }
+
+ @Override
+ public Table getTarget() {
+ return (Table) super.getTarget();
+ }
+
+ }
+
+ public TargetDetails translateDragDropDetails(
+ Map<String, Object> clientVariables) {
+ return new TableTargetDetails(clientVariables);
+ }
}
diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java
index 15990500d6..3bb1e6f696 100644
--- a/src/com/vaadin/ui/Tree.java
+++ b/src/com/vaadin/ui/Tree.java
@@ -1157,7 +1157,7 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
}
public enum Location {
- TOP, BOTTOM, MIDDLE
+ TOP, BOTTOM, MIDDLE;
}
public class TreeDropDetails extends TargetDetailsImpl {
diff --git a/tests/src/com/vaadin/tests/dd/DDTest4.java b/tests/src/com/vaadin/tests/dd/DDTest4.java
new file mode 100644
index 0000000000..fd922c9f4e
--- /dev/null
+++ b/tests/src/com/vaadin/tests/dd/DDTest4.java
@@ -0,0 +1,131 @@
+package com.vaadin.tests.dd;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.demo.tutorial.addressbook.data.Person;
+import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
+import com.vaadin.event.DataBoundTransferable;
+import com.vaadin.event.dd.DropEvent;
+import com.vaadin.event.dd.DropHandler;
+import com.vaadin.event.dd.acceptCriteria.AcceptCriterion;
+import com.vaadin.event.dd.acceptCriteria.ComponentFilter;
+import com.vaadin.terminal.ThemeResource;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Tree;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.Table.TableTargetDetails;
+import com.vaadin.ui.Tree.Location;
+
+public class DDTest4 extends TestBase {
+
+ java.util.Random r = new java.util.Random(1);
+
+ HorizontalLayout hl = new HorizontalLayout();
+ Table table = new Table("Drag and drop sortable table");
+
+ private Tree tree3;
+
+ @Override
+ protected void setup() {
+ Window w = getLayout().getWindow();
+ /* darn reindeer has no icons */
+
+ // hl.addComponent(tree1);
+ hl.addComponent(table);
+ // hl.addComponent(tree2);
+ hl.setWidth("100%");
+ hl.setSpacing(true);
+ hl.setExpandRatio(table, 1);
+ table.setWidth("100%");
+ table.setPageLength(10);
+ populateTable();
+ addComponent(hl);
+
+ /*
+ * Make table rows draggable
+ */
+ table.setDragMode(Table.DragModes.ROWS);
+
+ table.setDropHandler(new DropHandler() {
+ // accept only drags from this table
+ AcceptCriterion crit = new ComponentFilter(table);
+
+ public AcceptCriterion getAcceptCriterion() {
+ return crit;
+ }
+
+ public void drop(DropEvent dropEvent) {
+ Table.TableTargetDetails dropTargetData = (TableTargetDetails) dropEvent
+ .getDropTargetData();
+ DataBoundTransferable transferable = (DataBoundTransferable) dropEvent
+ .getTransferable();
+ Object itemIdOver = dropTargetData.getItemIdOver();
+ Object itemId = transferable.getItemId();
+ if (itemId == null || itemIdOver == null
+ || itemId.equals(itemIdOver)) {
+ return; // no move happened
+ }
+
+ // IndexedContainer goodies... (hint: don't use it in real apps)
+ IndexedContainer containerDataSource = (IndexedContainer) table
+ .getContainerDataSource();
+ IndexedContainer clone = null;
+ try {
+ clone = (IndexedContainer) containerDataSource.clone();
+ int newIndex = containerDataSource.indexOfId(itemIdOver);
+ if (dropTargetData.getDropLocation() != Location.TOP) {
+ newIndex++;
+ }
+ containerDataSource.removeItem(itemId);
+ Item newItem = containerDataSource.addItemAt(newIndex,
+ itemId);
+
+ Item item = clone.getItem(itemId);
+ for (Object propId : item.getItemPropertyIds()) {
+ newItem.getItemProperty(propId).setValue(
+ item.getItemProperty(propId).getValue());
+ }
+ } catch (CloneNotSupportedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+ });
+
+ }
+
+ private void populateTable() {
+ table.addContainerProperty("Name", String.class, "");
+ table.addContainerProperty("Weight", Integer.class, 0);
+
+ PersonContainer testData = PersonContainer.createWithTestData();
+
+ for (int i = 0; i < 10; i++) {
+ Item addItem = table.addItem("Item" + i);
+ Person p = testData.getIdByIndex(i);
+ addItem.getItemProperty("Name").setValue(
+ p.getFirstName() + " " + p.getLastName());
+ addItem.getItemProperty("Weight").setValue(50 + r.nextInt(60));
+ }
+
+ }
+
+ 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;
+ }
+
+}