.v-theme-version:after {content:"6_3_0_dev-20100217";} | |||||
.v-theme-version-6_3_0_dev-20100217 {display: none;} | |||||
.v-theme-version:after {content:"6_3_0_dev-20100304";} | |||||
.v-theme-version-6_3_0_dev-20100304 {display: none;} | |||||
/* Automatically compiled css file from subdirectories. */ | /* Automatically compiled css file from subdirectories. */ | ||||
.v-absolutelayout-wrapper { | .v-absolutelayout-wrapper { | ||||
cursor: pointer; | 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, | ||||
.v-table-body-noselection .v-table-row-odd { | .v-table-body-noselection .v-table-row-odd { | ||||
cursor: default; | cursor: default; | ||||
color: #ddd; | color: #ddd; | ||||
} | } | ||||
/* TODO remove important, replace with better anchors or order */ | |||||
.v-table-row-drag-middle .v-table-cell-content { | |||||
background-color: cyan; | |||||
} | |||||
/* 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-tabsheet, | .v-tabsheet, | ||||
.v-tabsheet-content, | .v-tabsheet-content, | ||||
.v-tabsheet-deco { | .v-tabsheet-deco { |
cursor: pointer; | 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, | ||||
.v-table-body-noselection .v-table-row-odd { | .v-table-body-noselection .v-table-row-odd { | ||||
cursor: default; | cursor: default; | ||||
} | } | ||||
.v-off { | .v-off { | ||||
color: #ddd; | color: #ddd; | ||||
} | |||||
} | |||||
/* TODO remove important, replace with better anchors or order */ | |||||
.v-table-row-drag-middle .v-table-cell-content { | |||||
background-color: cyan; | |||||
} | |||||
/* 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-theme-version:after {content:"6_3_0_dev-20100217";} | |||||
.v-theme-version-6_3_0_dev-20100217 {display: none;} | |||||
.v-theme-version:after {content:"6_3_0_dev-20100304";} | |||||
.v-theme-version-6_3_0_dev-20100304 {display: none;} | |||||
/* Automatically compiled css file from subdirectories. */ | /* Automatically compiled css file from subdirectories. */ | ||||
.v-absolutelayout-wrapper { | .v-absolutelayout-wrapper { | ||||
cursor: pointer; | 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, | ||||
.v-table-body-noselection .v-table-row-odd { | .v-table-body-noselection .v-table-row-odd { | ||||
cursor: default; | cursor: default; | ||||
color: #ddd; | color: #ddd; | ||||
} | } | ||||
/* TODO remove important, replace with better anchors or order */ | |||||
.v-table-row-drag-middle .v-table-cell-content { | |||||
background-color: cyan; | |||||
} | |||||
/* 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-tabsheet, | .v-tabsheet, | ||||
.v-tabsheet-content, | .v-tabsheet-content, | ||||
.v-tabsheet-deco { | .v-tabsheet-deco { |
.v-theme-version:after {content:"6_3_0_dev-20100217";} | |||||
.v-theme-version-6_3_0_dev-20100217 {display: none;} | |||||
.v-theme-version:after {content:"6_3_0_dev-20100304";} | |||||
.v-theme-version-6_3_0_dev-20100304 {display: none;} | |||||
/* Automatically compiled css file from subdirectories. */ | /* Automatically compiled css file from subdirectories. */ | ||||
.v-absolutelayout-wrapper { | .v-absolutelayout-wrapper { | ||||
cursor: pointer; | 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, | ||||
.v-table-body-noselection .v-table-row-odd { | .v-table-body-noselection .v-table-row-odd { | ||||
cursor: default; | cursor: default; | ||||
color: #ddd; | color: #ddd; | ||||
} | } | ||||
/* TODO remove important, replace with better anchors or order */ | |||||
.v-table-row-drag-middle .v-table-cell-content { | |||||
background-color: cyan; | |||||
} | |||||
/* 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-tabsheet, | .v-tabsheet, | ||||
.v-tabsheet-content, | .v-tabsheet-content, | ||||
.v-tabsheet-deco { | .v-tabsheet-deco { |
if (newParentId == null) { | if (newParentId == null) { | ||||
// Remove from old parents children list | // Remove from old parents children list | ||||
final LinkedList<Object> l = children.get(itemId); | |||||
final LinkedList<Object> l = children.get(oldParentId); | |||||
if (l != null) { | if (l != null) { | ||||
l.remove(itemId); | l.remove(itemId); | ||||
if (l.isEmpty()) { | if (l.isEmpty()) { |
import com.vaadin.event.dd.DragAndDropEvent; | import com.vaadin.event.dd.DragAndDropEvent; | ||||
import com.vaadin.terminal.PaintException; | import com.vaadin.terminal.PaintException; | ||||
import com.vaadin.terminal.PaintTarget; | import com.vaadin.terminal.PaintTarget; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VIsDragSource; | |||||
import com.vaadin.terminal.gwt.client.ui.dd.VDragSourceIs; | |||||
import com.vaadin.ui.Component; | import com.vaadin.ui.Component; | ||||
/** | /** | ||||
* | * | ||||
* @since 6.3 | * @since 6.3 | ||||
*/ | */ | ||||
@ClientCriterion(VIsDragSource.class) | |||||
public class IsDragSource extends ClientSideCriterion { | |||||
@ClientCriterion(VDragSourceIs.class) | |||||
public class DragSourceIs extends ClientSideCriterion { | |||||
private Component[] component; | private Component[] component; | ||||
public IsDragSource(Component... component) { | |||||
public DragSourceIs(Component... component) { | |||||
this.component = component; | this.component = component; | ||||
} | } | ||||
return 'd'; | return 'd'; | ||||
} else if (value instanceof Long) { | } else if (value instanceof Long) { | ||||
return 'l'; | return 'l'; | ||||
} else if (value instanceof Enum) { | |||||
return 's'; // transported as string representation | |||||
} | } | ||||
return 'u'; | return 'u'; | ||||
} | } |
case Event.ONMOUSEDOWN: | case Event.ONMOUSEDOWN: | ||||
if (dragmode != 0) { | if (dragmode != 0) { | ||||
mDown = true; | mDown = true; | ||||
event.preventDefault(); | |||||
event.stopPropagation(); | |||||
} | |||||
break; | |||||
case Event.ONMOUSEOUT: | |||||
mDown = false; | |||||
break; | |||||
case Event.ONMOUSEMOVE: | |||||
if (mDown && dragmode != 0) { | |||||
VTransferable transferable = new VTransferable(); | VTransferable transferable = new VTransferable(); | ||||
transferable.setDragSource(VScrollTable.this); | transferable.setDragSource(VScrollTable.this); | ||||
transferable.setData("itemId", "" + rowKey); | transferable.setData("itemId", "" + rowKey); | ||||
VDragEvent ev = VDragAndDropManager.get() | VDragEvent ev = VDragAndDropManager.get() | ||||
.startDrag(transferable, event, true); | .startDrag(transferable, event, true); | ||||
ev.createDragImage(getElement(), true); | ev.createDragImage(getElement(), true); | ||||
mDown = false; | |||||
// prevent text selection | |||||
event.preventDefault(); | event.preventDefault(); | ||||
event.stopPropagation(); | event.stopPropagation(); | ||||
} | } | ||||
break; | |||||
case Event.ONMOUSEOUT: | |||||
mDown = false; | |||||
break; | |||||
default: | default: | ||||
break; | break; | ||||
} | } |
private boolean rendering; | private boolean rendering; | ||||
private int dragMode = 0; | |||||
private VAbstractDropHandler dropHandler; | private VAbstractDropHandler dropHandler; | ||||
private int dragMode; | |||||
public VTree() { | public VTree() { | ||||
super(); | super(); | ||||
setStyleName(CLASSNAME); | setStyleName(CLASSNAME); | ||||
disabled = uidl.getBooleanAttribute("disabled"); | disabled = uidl.getBooleanAttribute("disabled"); | ||||
readonly = uidl.getBooleanAttribute("readonly"); | readonly = uidl.getBooleanAttribute("readonly"); | ||||
dragMode = uidl.hasAttribute("dragMode") ? uidl | |||||
.getIntAttribute("dragMode") : 0; | |||||
isNullSelectionAllowed = uidl.getBooleanAttribute("nullselect"); | isNullSelectionAllowed = uidl.getBooleanAttribute("nullselect"); | ||||
clear(); | clear(); | ||||
selectedIds = uidl.getStringArrayVariableAsSet("selected"); | selectedIds = uidl.getStringArrayVariableAsSet("selected"); | ||||
if (uidl.hasAttribute("dragMode")) { | |||||
dragMode = uidl.getIntAttribute("dragMode"); | |||||
} else { | |||||
dragMode = 0; | |||||
} | |||||
rendering = false; | rendering = false; | ||||
} | } | ||||
currentMouseOverKey = findCurrentMouseOverKey(drag.getElementOver()); | currentMouseOverKey = findCurrentMouseOverKey(drag.getElementOver()); | ||||
drag.getDropDetails().put("itemIdOver", currentMouseOverKey); | |||||
if (currentMouseOverKey != null) { | if (currentMouseOverKey != null) { | ||||
String detail = getDropDetail(drag.getCurrentGwtEvent()); | |||||
VerticalDropLocation detail = getDropDetail(drag | |||||
.getCurrentGwtEvent()); | |||||
Boolean overTreeNode = null; | Boolean overTreeNode = null; | ||||
TreeNode treeNode = keyToNode.get(currentMouseOverKey); | TreeNode treeNode = keyToNode.get(currentMouseOverKey); | ||||
if (treeNode != null && !treeNode.isLeaf() | if (treeNode != null && !treeNode.isLeaf() | ||||
&& "MIDDLE".equals(detail)) { | |||||
&& detail == VerticalDropLocation.MIDDLE) { | |||||
overTreeNode = true; | overTreeNode = true; | ||||
} | } | ||||
drag.getDropDetails().put("itemIdOver", currentMouseOverKey); | |||||
drag.getDropDetails().put("itemIdOverIsNode", overTreeNode); | drag.getDropDetails().put("itemIdOverIsNode", overTreeNode); | ||||
drag.getDropDetails().put("detail", detail); | drag.getDropDetails().put("detail", detail); | ||||
public void dragOver(final VDragEvent currentDrag) { | public void dragOver(final VDragEvent currentDrag) { | ||||
final Object oldIdOver = currentDrag.getDropDetails().get( | final Object oldIdOver = currentDrag.getDropDetails().get( | ||||
"itemIdOver"); | "itemIdOver"); | ||||
final String oldDetail = (String) currentDrag | |||||
final VerticalDropLocation oldDetail = (VerticalDropLocation) currentDrag | |||||
.getDropDetails().get("detail"); | .getDropDetails().get("detail"); | ||||
updateTreeRelatedDragData(currentDrag); | updateTreeRelatedDragData(currentDrag); | ||||
final String detail = getDropDetail(currentDrag | |||||
final VerticalDropLocation detail = getDropDetail(currentDrag | |||||
.getCurrentGwtEvent()); | .getCurrentGwtEvent()); | ||||
boolean nodeHasChanged = (currentMouseOverKey != null && currentMouseOverKey != oldIdOver) | boolean nodeHasChanged = (currentMouseOverKey != null && currentMouseOverKey != oldIdOver) | ||||
|| (currentMouseOverKey == null && oldIdOver != null); | || (currentMouseOverKey == null && oldIdOver != null); | ||||
boolean detailHasChanded = (detail != null && !detail | |||||
.equals(oldDetail)) | |||||
boolean detailHasChanded = (detail != null && detail != oldDetail) | |||||
|| (detail == null && oldDetail != null); | || (detail == null && oldDetail != null); | ||||
if (nodeHasChanged || detailHasChanded) { | if (nodeHasChanged || detailHasChanded) { | ||||
"Change in Transferable " + currentMouseOverKey | "Change in Transferable " + currentMouseOverKey | ||||
+ " " + detail); | + " " + detail); | ||||
final String newKey = currentMouseOverKey; | final String newKey = currentMouseOverKey; | ||||
validate(new VAcceptCallback() { | |||||
public void accepted(VDragEvent event) { | |||||
if (newKey != null) { | |||||
keyToNode.get(newKey).emphasis(detail); | |||||
} | |||||
} | |||||
}, currentDrag); | |||||
if (oldIdOver != null | if (oldIdOver != null | ||||
&& oldIdOver != currentMouseOverKey) { | && oldIdOver != currentMouseOverKey) { | ||||
TreeNode treeNode = keyToNode.get(oldIdOver); | TreeNode treeNode = keyToNode.get(oldIdOver); | ||||
treeNode.emphasis(null); | treeNode.emphasis(null); | ||||
} | } | ||||
} | } | ||||
validate(new VAcceptCallback() { | |||||
public void accepted(VDragEvent event) { | |||||
if (newKey != null) { | |||||
keyToNode.get(newKey).emphasis(detail); | |||||
} | |||||
} | |||||
}, currentDrag); | |||||
} | } | ||||
} | } | ||||
dropHandler.updateAcceptRules(childUidl); | dropHandler.updateAcceptRules(childUidl); | ||||
} | } | ||||
public String getDropDetail(NativeEvent event) { | |||||
public VerticalDropLocation getDropDetail(NativeEvent event) { | |||||
TreeNode treeNode = keyToNode.get(currentMouseOverKey); | TreeNode treeNode = keyToNode.get(currentMouseOverKey); | ||||
if (treeNode == null) { | if (treeNode == null) { | ||||
return null; | return null; | ||||
} | } | ||||
VerticalDropLocation verticalDropLocation = VerticalDropLocation.get( | VerticalDropLocation verticalDropLocation = VerticalDropLocation.get( | ||||
treeNode.nodeCaptionDiv, event.getClientY(), 0.2); | treeNode.nodeCaptionDiv, event.getClientY(), 0.2); | ||||
return verticalDropLocation.toString(); | |||||
return verticalDropLocation; | |||||
} | } | ||||
private void handleUpdate(UIDL uidl) { | private void handleUpdate(UIDL uidl) { | ||||
return selectedIds.contains(treeNode.key); | return selectedIds.contains(treeNode.key); | ||||
} | } | ||||
protected class TreeNode extends SimplePanel implements ActionOwner { | |||||
public class TreeNode extends SimplePanel implements ActionOwner { | |||||
public static final String CLASSNAME = "v-tree-node"; | public static final String CLASSNAME = "v-tree-node"; | ||||
String key; | |||||
public String key; | |||||
private String[] actionKeys = null; | private String[] actionKeys = null; | ||||
| Event.ONCONTEXTMENU); | | Event.ONCONTEXTMENU); | ||||
} | } | ||||
public void emphasis(String string) { | |||||
protected void emphasis(VerticalDropLocation detail) { | |||||
String base = "v-tree-node-drag-"; | 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", "MIDDLE" | |||||
.equals(string)); | |||||
UIObject.setStyleName(getElement(), base + "top", | |||||
VerticalDropLocation.TOP == detail); | |||||
UIObject.setStyleName(getElement(), base + "bottom", | |||||
VerticalDropLocation.BOTTOM == detail); | |||||
UIObject.setStyleName(getElement(), base + "center", | |||||
VerticalDropLocation.MIDDLE == detail); | |||||
base = "v-tree-node-caption-drag-"; | 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", "MIDDLE" | |||||
.equals(string)); | |||||
UIObject.setStyleName(nodeCaptionDiv, base + "top", | |||||
VerticalDropLocation.TOP == detail); | |||||
UIObject.setStyleName(nodeCaptionDiv, base + "bottom", | |||||
VerticalDropLocation.BOTTOM == detail); | |||||
UIObject.setStyleName(nodeCaptionDiv, base + "center", | |||||
VerticalDropLocation.MIDDLE == detail); | |||||
// also add classname to "folder node" into which the drag is | |||||
// targeted | |||||
TreeNode folder = null; | |||||
/* Possible parent of this TreeNode will be stored here */ | |||||
TreeNode parentFolder = getParentNode(); | |||||
// TODO fix my bugs | |||||
if (isLeaf()) { | |||||
folder = parentFolder; | |||||
// note, parent folder may be null if this is root node => no | |||||
// folder target exists | |||||
} else { | |||||
if (detail == VerticalDropLocation.TOP) { | |||||
folder = parentFolder; | |||||
} else { | |||||
folder = this; | |||||
} | |||||
// ensure we remove the dragfolder classname from the previous | |||||
// folder node | |||||
setDragFolderStyleName(this, false); | |||||
setDragFolderStyleName(parentFolder, false); | |||||
} | |||||
if (folder != null) { | |||||
setDragFolderStyleName(folder, detail != null); | |||||
} | |||||
} | |||||
private TreeNode getParentNode() { | |||||
Widget parent2 = getParent().getParent(); | |||||
if (parent2 instanceof TreeNode) { | |||||
return (TreeNode) parent2; | |||||
} | |||||
return null; | |||||
} | |||||
private void setDragFolderStyleName(TreeNode folder, boolean add) { | |||||
if (folder != null) { | |||||
UIObject.setStyleName(folder.getElement(), | |||||
"v-tree-node-dragfolder", add); | |||||
UIObject.setStyleName(folder.nodeCaptionDiv, | |||||
"v-tree-node-caption-dragfolder", add); | |||||
} | |||||
} | } | ||||
@Override | @Override | ||||
if (dragMode != 0 || dropHandler != null) { | if (dragMode != 0 || dropHandler != null) { | ||||
if (type == Event.ONMOUSEDOWN) { | if (type == Event.ONMOUSEDOWN) { | ||||
if (nodeCaptionDiv.isOrHasChild(event.getTarget())) { | if (nodeCaptionDiv.isOrHasChild(event.getTarget())) { | ||||
ApplicationConnection.getConsole().log( | |||||
"TreeNode m down"); | |||||
event.preventDefault(); // prevent text selection | |||||
mouseDownEvent = event; | |||||
if (dragMode > 0) { | |||||
ApplicationConnection.getConsole().log( | |||||
"TreeNode m down"); | |||||
event.preventDefault(); // prevent text selection | |||||
mouseDownEvent = event; | |||||
} | |||||
} | } | ||||
} else if (type == Event.ONMOUSEMOVE | } else if (type == Event.ONMOUSEMOVE | ||||
|| type == Event.ONMOUSEOUT) { | || type == Event.ONMOUSEOUT) { | ||||
public VDropHandler getDropHandler() { | public VDropHandler getDropHandler() { | ||||
return dropHandler; | return dropHandler; | ||||
} | } | ||||
public TreeNode getNodeByKey(String key) { | |||||
return keyToNode.get(key); | |||||
} | |||||
} | } |
* <p> | * <p> | ||||
* Using this method may be handy if criterion that uses lazy initialization | * Using this method may be handy if criterion that uses lazy initialization | ||||
* are used. Check | * are used. Check | ||||
* <p> | |||||
* TODO Optimization: consider if we actually only need to keep the last | |||||
* command in queue here. | |||||
* | * | ||||
* @param command | * @param command | ||||
*/ | */ |
* | * | ||||
* @since 6.3 | * @since 6.3 | ||||
*/ | */ | ||||
final public class VIsDragSource extends VAcceptCriterion { | |||||
final public class VDragSourceIs extends VAcceptCriterion { | |||||
@Override | @Override | ||||
public boolean validates(VDragEvent drag, UIDL configuration) { | public boolean validates(VDragEvent drag, UIDL configuration) { |
/** | /** | ||||
* | * | ||||
* @deprecated example class testing custom behavior | |||||
*/ | */ | ||||
@Deprecated | |||||
final public class VLazyInitItemIdentifiers extends VAcceptCriterion { | final public class VLazyInitItemIdentifiers extends VAcceptCriterion { | ||||
private boolean loaded = false; | private boolean loaded = false; | ||||
private HashSet<String> hashSet; | private HashSet<String> hashSet; |
/** | |||||
* | |||||
*/ | |||||
package com.vaadin.terminal.gwt.client.ui.dd; | |||||
import com.google.gwt.user.client.ui.Widget; | |||||
import com.vaadin.terminal.gwt.client.UIDL; | |||||
import com.vaadin.terminal.gwt.client.ui.VTree; | |||||
import com.vaadin.terminal.gwt.client.ui.VTree.TreeNode; | |||||
final public class VTargetNodeIsChildOf extends VAcceptCriterion { | |||||
@Override | |||||
public boolean validates(VDragEvent drag, UIDL configuration) { | |||||
VTree tree = (VTree) VDragAndDropManager.get().getCurrentDropHandler() | |||||
.getPaintable(); | |||||
TreeNode treeNode = tree.getNodeByKey((String) drag.getDropDetails() | |||||
.get("itemIdOver")); | |||||
if (treeNode != null) { | |||||
Widget parent2 = treeNode.getParent().getParent(); | |||||
int depth = configuration.getIntAttribute("depth"); | |||||
if (depth < 0) { | |||||
depth = Integer.MAX_VALUE; | |||||
} | |||||
for (int i = 0; i < depth && parent2 instanceof TreeNode; i++) { | |||||
if (configuration.getStringAttribute("key").equals( | |||||
((TreeNode) parent2).key)) { | |||||
return true; | |||||
} | |||||
parent2 = parent2.getParent().getParent(); | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
} |
.getCriterion(); | .getCriterion(); | ||||
for (Class<? extends AcceptCriterion> class1 : clientSideVerifiableCriterion) { | for (Class<? extends AcceptCriterion> class1 : clientSideVerifiableCriterion) { | ||||
logger.log(Type.INFO, "creating mapping for " | |||||
+ class1.getCanonicalName()); | |||||
String canonicalName = class1.getCanonicalName(); | String canonicalName = class1.getCanonicalName(); | ||||
Class<? extends VAcceptCriterion> clientClass = class1 | Class<? extends VAcceptCriterion> clientClass = class1 | ||||
.getAnnotation(ClientCriterion.class).value(); | .getAnnotation(ClientCriterion.class).value(); |
import com.vaadin.terminal.Resource; | import com.vaadin.terminal.Resource; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VIsOverId; | import com.vaadin.terminal.gwt.client.ui.dd.VIsOverId; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VItemIdIs; | import com.vaadin.terminal.gwt.client.ui.dd.VItemIdIs; | ||||
import com.vaadin.ui.Tree.Location; | |||||
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
*/ | */ | ||||
public class AbstractSelectDropTargetDetails extends DropTargetDetailsImpl { | public class AbstractSelectDropTargetDetails extends DropTargetDetailsImpl { | ||||
private Object idOver; | |||||
/** | |||||
* The treenode id over which the drag event happened. | |||||
*/ | |||||
protected Object idOver; | |||||
/** | /** | ||||
* TODO Javadoc! | * TODO Javadoc! | ||||
} | } | ||||
/** | /** | ||||
* TODO Javadoc! | |||||
* If the drag operation is currently over an Item, this method returns | |||||
* the identifier of the Item. | |||||
* | * | ||||
*/ | */ | ||||
public Object getItemIdOver() { | public Object getItemIdOver() { | ||||
/** | /** | ||||
* TODO Javadoc! | * TODO Javadoc! | ||||
* | * | ||||
* @since 6.3 | |||||
*/ | */ | ||||
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; | |||||
} | |||||
public VerticalDropLocation getDropLocation() { | |||||
VerticalDropLocation valueOf = VerticalDropLocation | |||||
.valueOf((String) getData("detail")); | |||||
return valueOf; | |||||
} | } | ||||
} | } |
import java.util.Map; | import java.util.Map; | ||||
import com.vaadin.event.TransferableImpl; | |||||
import com.vaadin.event.DataBoundTransferable; | import com.vaadin.event.DataBoundTransferable; | ||||
import com.vaadin.event.Transferable; | import com.vaadin.event.Transferable; | ||||
import com.vaadin.event.dd.DragAndDropEvent; | import com.vaadin.event.dd.DragAndDropEvent; | ||||
DragDropPane pane = (DragDropPane) event.getDropTargetDetails() | DragDropPane pane = (DragDropPane) event.getDropTargetDetails() | ||||
.getTarget(); | .getTarget(); | ||||
DragEventDetails ed = (DragEventDetails) event.getDropTargetDetails(); | |||||
Transferable transferable = event.getTransferable(); | |||||
if (transferable instanceof TransferableImpl) { | |||||
TransferableImpl ctr = (TransferableImpl) transferable; | |||||
DragEventDetails ed = (DragEventDetails) event | |||||
.getDropTargetDetails(); | |||||
Transferable ctr = event.getTransferable(); | |||||
if (ctr.getSourceComponent() != null) { | |||||
// use "component" (from DragDropPane) if available, else take | // use "component" (from DragDropPane) if available, else take | ||||
// the source component | // the source component | ||||
Component component = (Component) ctr.getData("component"); | Component component = (Component) ctr.getData("component"); | ||||
} | } | ||||
if (component.getParent() != pane) { | if (component.getParent() != pane) { | ||||
if (transferable instanceof DataBoundTransferable) { | |||||
if (ctr instanceof DataBoundTransferable) { | |||||
// Item has been dragged, construct a Label from | // Item has been dragged, construct a Label from | ||||
// Item id | // Item id | ||||
Label l = new Label(); | Label l = new Label(); | ||||
l.setSizeUndefined(); | l.setSizeUndefined(); | ||||
l.setValue("ItemId : " | l.setValue("ItemId : " | ||||
+ ((DataBoundTransferable) transferable) | |||||
.getItemId()); | |||||
+ ((DataBoundTransferable) ctr).getItemId()); | |||||
pane.addComponent(l); | pane.addComponent(l); | ||||
component = l; | component = l; | ||||
} else { | } else { | ||||
// drag coming outside of Vaadin | // drag coming outside of Vaadin | ||||
String object = (String) transferable.getData("text/plain"); | |||||
String object = (String) ctr.getData("text/plain"); | |||||
String content = (String) transferable.getData("fileContents"); | |||||
String content = (String) ctr.getData("fileContents"); | |||||
Label l = new Label(); | Label l = new Label(); | ||||
l.setCaption("Generated from HTML5 drag:"); | l.setCaption("Generated from HTML5 drag:"); |
import com.vaadin.terminal.gwt.client.ui.VTree; | import com.vaadin.terminal.gwt.client.ui.VTree; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers; | import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VOverTreeNode; | import com.vaadin.terminal.gwt.client.ui.dd.VOverTreeNode; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VTargetNodeIsChildOf; | |||||
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; | |||||
/** | /** | ||||
* Tree component. A Tree can be used to select an item (or multiple items) from | * Tree component. A Tree can be used to select an item (or multiple items) from | ||||
*/ | */ | ||||
private boolean initialPaint = true; | private boolean initialPaint = true; | ||||
private DragMode dragMode = DragMode.NONE; | |||||
/** | /** | ||||
* Supported drag modes for Tree. | * Supported drag modes for Tree. | ||||
*/ | */ | ||||
public enum DragMode { | |||||
NONE, NODES; | |||||
public enum TreeDragMode { | |||||
NONE, NODE | |||||
// , SUBTREE | |||||
} | } | ||||
private TreeDragMode dragMode = TreeDragMode.NONE; | |||||
/* Tree constructors */ | /* Tree constructors */ | ||||
/** | /** | ||||
target.addAttribute("nullselect", true); | target.addAttribute("nullselect", true); | ||||
} | } | ||||
if (dragMode != DragMode.NONE) { | |||||
if (dragMode != TreeDragMode.NONE) { | |||||
target.addAttribute("dragMode", dragMode.ordinal()); | target.addAttribute("dragMode", dragMode.ordinal()); | ||||
} | } | ||||
this.dropHandler = dropHandler; | this.dropHandler = dropHandler; | ||||
} | } | ||||
public enum Location { | |||||
TOP, BOTTOM, MIDDLE; | |||||
} | |||||
/** | /** | ||||
* TODO Javadoc! | * TODO Javadoc! | ||||
* | * | ||||
return (Tree) super.getTarget(); | return (Tree) super.getTarget(); | ||||
} | } | ||||
/** | |||||
* If the event is on a node that can not have children (see | |||||
* {@link Tree#areChildrenAllowed(Object)}), this method returns the | |||||
* parent item id of the target item (see {@link #getItemIdOver()} ). | |||||
* The identifier of the parent node is also returned if the cursor is | |||||
* on the top part of node. Else this method returns the same as | |||||
* {@link #getItemIdOver()}. | |||||
* <p> | |||||
* In other words this method returns the identifier of the "folder" | |||||
* into the drag operation is targeted. | |||||
* <p> | |||||
* If the method returns null, the current target is on a root node or | |||||
* on other undefined area over the tree component. | |||||
* <p> | |||||
* The default Tree implementation marks the targetted tree node with | |||||
* CSS classnames v-tree-node-dragfolder and | |||||
* v-tree-node-caption-dragfolder (for the caption element). | |||||
*/ | |||||
public Object getItemIdInto() { | |||||
Object itemIdOver = getItemIdOver(); | |||||
if (areChildrenAllowed(itemIdOver) | |||||
&& getDropLocation() != VerticalDropLocation.TOP) { | |||||
return itemIdOver; | |||||
} | |||||
return getParent(itemIdOver); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
return itemIdMapper.key(itemId); | return itemIdMapper.key(itemId); | ||||
} | } | ||||
public void setDragMode(TreeDragMode dragMode) { | |||||
this.dragMode = dragMode; | |||||
} | |||||
public TreeDragMode getDragMode() { | |||||
return dragMode; | |||||
} | |||||
/** | /** | ||||
* TODO Javadoc! | * TODO Javadoc! | ||||
* | * | ||||
* Accepts transferable only on tree Node (middle of the node + can has | * Accepts transferable only on tree Node (middle of the node + can has | ||||
* child) | * child) | ||||
* | * | ||||
* TODO replace by composition of itemIdIs + drop property | |||||
* | |||||
* @since 6.3 | * @since 6.3 | ||||
*/ | */ | ||||
@ClientCriterion(VOverTreeNode.class) | @ClientCriterion(VOverTreeNode.class) | ||||
public static class OverTreeNode extends ClientSideCriterion { | |||||
public static class OverFolderNode extends ClientSideCriterion { | |||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
public boolean accepts(DragAndDropEvent dragEvent) { | public boolean accepts(DragAndDropEvent dragEvent) { | ||||
try { | try { | ||||
// must be over tree node and in the middle of it (not top or | // must be over tree node and in the middle of it (not top or | ||||
// bottom part) | |||||
// bottom | |||||
// part) | |||||
TreeDropTargetDetails eventDetails = (TreeDropTargetDetails) dragEvent | TreeDropTargetDetails eventDetails = (TreeDropTargetDetails) dragEvent | ||||
.getDropTargetDetails(); | .getDropTargetDetails(); | ||||
if (!eventDetails.getTarget().areChildrenAllowed(itemIdOver)) { | if (!eventDetails.getTarget().areChildrenAllowed(itemIdOver)) { | ||||
return false; | return false; | ||||
} | } | ||||
// return true if directly over | |||||
return eventDetails.getDropLocation() == VerticalDropLocation.MIDDLE; | |||||
} catch (Exception e) { | |||||
return false; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Checks to parent (or parent hierarchy) for the item identifier given in | |||||
* constructor. If the parent is found, content is accepted. | |||||
*/ | |||||
@ClientCriterion(VTargetNodeIsChildOf.class) | |||||
public class TargetNodeIsChildOf extends ClientSideCriterion { | |||||
private Object parentItemId; | |||||
private int depthToCheck = 1; | |||||
return eventDetails.getDropLocation() == Location.MIDDLE; | |||||
/** | |||||
* | |||||
* @param parentItemId | |||||
*/ | |||||
public TargetNodeIsChildOf(Object parentItemId) { | |||||
this.parentItemId = parentItemId; | |||||
} | |||||
/** | |||||
* | |||||
* @param parentItemId | |||||
* @param depthToCheck | |||||
* the depth that tree is traversed upwards to seek for the | |||||
* parent, -1 means that the whole structure should be | |||||
* checked | |||||
*/ | |||||
public TargetNodeIsChildOf(Object parentItemId, int depthToCheck) { | |||||
this.parentItemId = parentItemId; | |||||
this.depthToCheck = depthToCheck; | |||||
} | |||||
private static final long serialVersionUID = 1L; | |||||
public boolean accepts(DragAndDropEvent dragEvent) { | |||||
try { | |||||
TreeDropTargetDetails eventDetails = (TreeDropTargetDetails) dragEvent | |||||
.getDropTargetDetails(); | |||||
if (eventDetails.getItemIdOver() != null) { | |||||
Object itemIdOver = eventDetails.getItemIdOver(); | |||||
Object parent2 = getParent(itemIdOver); | |||||
int i = 0; | |||||
while (parent2 != null && i < depthToCheck) { | |||||
if (parent2.equals(parentItemId)) { | |||||
return true; | |||||
} | |||||
i++; | |||||
} | |||||
} | |||||
return false; | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
@Override | |||||
public void paintContent(PaintTarget target) throws PaintException { | |||||
super.paintContent(target); | |||||
target.addAttribute("depth", depthToCheck); | |||||
target.addAttribute("key", key(parentItemId)); | |||||
} | |||||
} | } | ||||
} | } |
import com.vaadin.data.Item; | import com.vaadin.data.Item; | ||||
import com.vaadin.data.util.HierarchicalContainer; | import com.vaadin.data.util.HierarchicalContainer; | ||||
import com.vaadin.event.TransferableImpl; | |||||
import com.vaadin.event.DataBoundTransferable; | import com.vaadin.event.DataBoundTransferable; | ||||
import com.vaadin.event.Transferable; | import com.vaadin.event.Transferable; | ||||
import com.vaadin.event.dd.DragAndDropEvent; | import com.vaadin.event.dd.DragAndDropEvent; | ||||
import com.vaadin.event.dd.acceptCriteria.IsDataBound; | import com.vaadin.event.dd.acceptCriteria.IsDataBound; | ||||
import com.vaadin.event.dd.acceptCriteria.ServerSideCriterion; | import com.vaadin.event.dd.acceptCriteria.ServerSideCriterion; | ||||
import com.vaadin.terminal.ExternalResource; | import com.vaadin.terminal.ExternalResource; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; | |||||
import com.vaadin.tests.components.TestBase; | import com.vaadin.tests.components.TestBase; | ||||
import com.vaadin.ui.Component; | import com.vaadin.ui.Component; | ||||
import com.vaadin.ui.DragDropPane; | import com.vaadin.ui.DragDropPane; | ||||
import com.vaadin.ui.Link; | import com.vaadin.ui.Link; | ||||
import com.vaadin.ui.Table; | import com.vaadin.ui.Table; | ||||
import com.vaadin.ui.Tree; | import com.vaadin.ui.Tree; | ||||
import com.vaadin.ui.AbstractSelect.AbstractSelectDropTargetDetails; | |||||
import com.vaadin.ui.Table.DragModes; | import com.vaadin.ui.Table.DragModes; | ||||
import com.vaadin.ui.Tree.Location; | |||||
import com.vaadin.ui.Tree.TreeDragMode; | |||||
import com.vaadin.ui.Tree.TreeDropTargetDetails; | |||||
/** | /** | ||||
* DD playground. Better quality example/prototype codes in {@link DDTest2}. | * DD playground. Better quality example/prototype codes in {@link DDTest2}. | ||||
Transferable transferable = dragEvent.getTransferable(); | Transferable transferable = dragEvent.getTransferable(); | ||||
// System.out.println("Simulating 500ms processing..."); | // System.out.println("Simulating 500ms processing..."); | ||||
// try { | // try { | ||||
// Thread.sleep(9000); | |||||
// Thread.sleep(200); | |||||
// } catch (InterruptedException e) { | // } catch (InterruptedException e) { | ||||
// // TODO Auto-generated catch block | // // TODO Auto-generated catch block | ||||
// e.printStackTrace(); | // e.printStackTrace(); | ||||
// } | // } | ||||
// System.out.println("Done get to work."); | // System.out.println("Done get to work."); | ||||
if (transferable instanceof TransferableImpl) { | |||||
TransferableImpl ct = (TransferableImpl) transferable; | |||||
Component component = (Component) ct | |||||
.getData("component"); | |||||
if (component != null) { | |||||
if (component.toString() != null | |||||
&& component.toString().contains("Bar")) { | |||||
return true; | |||||
} | |||||
Component component = (Component) transferable | |||||
.getData("component"); | |||||
if (component == null) { | |||||
component = transferable.getSourceComponent(); | |||||
} | |||||
if (component != null) { | |||||
if (component.toString() != null | |||||
&& component.toString().contains("Bar")) { | |||||
return true; | |||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
t.addItem("Child"); | t.addItem("Child"); | ||||
t.setParent("Child", "Foo"); | t.setParent("Child", "Foo"); | ||||
t.setSizeFull(); | t.setSizeFull(); | ||||
t.setDragMode(TreeDragMode.NODE); | |||||
/* | /* | ||||
* Moves items in tree (and could work in Table too). Also supports | * Moves items in tree (and could work in Table too). Also supports | ||||
} | } | ||||
public void drop(DragAndDropEvent event) { | public void drop(DragAndDropEvent event) { | ||||
AbstractSelectDropTargetDetails details = (AbstractSelectDropTargetDetails) event | |||||
TreeDropTargetDetails details = (TreeDropTargetDetails) event | |||||
.getDropTargetDetails(); | .getDropTargetDetails(); | ||||
// TODO set properties, so same sorter could be used in Table | // TODO set properties, so same sorter could be used in Table | ||||
Transferable transferable = event.getTransferable(); | Transferable transferable = event.getTransferable(); | ||||
Object itemIdOver = details.getItemIdOver(); | Object itemIdOver = details.getItemIdOver(); | ||||
Location dropLocation = details.getDropLocation(); | |||||
// TODO could use the "folder" node id to make the drop | |||||
// logic simpler | |||||
Object itemIdInto = details.getItemIdInto(); | |||||
VerticalDropLocation dropLocation = details | |||||
.getDropLocation(); | |||||
if (dropLocation == Location.MIDDLE) { | |||||
if (dropLocation == VerticalDropLocation.MIDDLE) { | |||||
t.setParent(itemId, itemIdOver); | t.setParent(itemId, itemIdOver); | ||||
return; | return; | ||||
} else if (Location.TOP == dropLocation) { | |||||
} else if (VerticalDropLocation.TOP == dropLocation) { | |||||
// if on top of the caption area, add before | // if on top of the caption area, add before | ||||
itemIdOver = idx.prevItemId(itemIdOver); | itemIdOver = idx.prevItemId(itemIdOver); | ||||
} | } |
import com.vaadin.event.dd.DropHandler; | import com.vaadin.event.dd.DropHandler; | ||||
import com.vaadin.event.dd.acceptCriteria.AcceptCriterion; | import com.vaadin.event.dd.acceptCriteria.AcceptCriterion; | ||||
import com.vaadin.event.dd.acceptCriteria.And; | import com.vaadin.event.dd.acceptCriteria.And; | ||||
import com.vaadin.event.dd.acceptCriteria.IsDragSource; | |||||
import com.vaadin.event.dd.acceptCriteria.DragSourceIs; | |||||
import com.vaadin.event.dd.acceptCriteria.IsDataBound; | import com.vaadin.event.dd.acceptCriteria.IsDataBound; | ||||
import com.vaadin.event.dd.acceptCriteria.Or; | import com.vaadin.event.dd.acceptCriteria.Or; | ||||
import com.vaadin.event.dd.acceptCriteria.ServerSideCriterion; | import com.vaadin.event.dd.acceptCriteria.ServerSideCriterion; | ||||
import com.vaadin.ui.Tree; | import com.vaadin.ui.Tree; | ||||
import com.vaadin.ui.Window; | import com.vaadin.ui.Window; | ||||
import com.vaadin.ui.AbstractSelect.AbstractSelectDropTargetDetails; | import com.vaadin.ui.AbstractSelect.AbstractSelectDropTargetDetails; | ||||
import com.vaadin.ui.Tree.OverTreeNode; | |||||
import com.vaadin.ui.Tree.OverFolderNode; | |||||
import com.vaadin.ui.Tree.TreeDragMode; | |||||
import com.vaadin.ui.Tree.TreeDropTargetDetails; | import com.vaadin.ui.Tree.TreeDropTargetDetails; | ||||
public class DDTest2 extends TestBase { | public class DDTest2 extends TestBase { | ||||
Window w = getLayout().getWindow(); | Window w = getLayout().getWindow(); | ||||
/* darn reindeer has no icons */ | /* darn reindeer has no icons */ | ||||
/* Make all trees (their nodes actually) draggable */ | |||||
tree1.setDragMode(TreeDragMode.NODE); | |||||
tree2.setDragMode(TreeDragMode.NODE); | |||||
hl.addComponent(tree1); | hl.addComponent(tree1); | ||||
hl.addComponent(table); | hl.addComponent(table); | ||||
hl.addComponent(tree2); | hl.addComponent(tree2); | ||||
tree3 = new Tree( | tree3 = new Tree( | ||||
"Tree with lazy loading criteria, of first server visit caches accept rules for all captions"); | "Tree with lazy loading criteria, of first server visit caches accept rules for all captions"); | ||||
tree3.setDragMode(TreeDragMode.NODE); | |||||
tree3.addItem("Drag on me"); | tree3.addItem("Drag on me"); | ||||
tree3.addItem("Or me"); | tree3.addItem("Or me"); | ||||
*/ | */ | ||||
table.setDragMode(Table.DragModes.ROWS); | table.setDragMode(Table.DragModes.ROWS); | ||||
OverTreeNode onNode = new OverTreeNode(); | |||||
IsDragSource fromTable = new IsDragSource(table); | |||||
OverFolderNode onNode = new OverFolderNode(); | |||||
DragSourceIs fromTable = new DragSourceIs(table); | |||||
IsDragSource fromTree = new IsDragSource(tree1); | |||||
DragSourceIs fromTree = new DragSourceIs(tree1); | |||||
final Or fromTree1OrTable = new Or(fromTable, fromTree); | final Or fromTree1OrTable = new Or(fromTable, fromTree); | ||||
// Or could in the case be replaced with, keeping here as an example and | |||||
// test | |||||
DragSourceIs treeOrTable = new DragSourceIs(table, tree1); | |||||
final And and = new And(fromTree1OrTable, onNode); | final And and = new And(fromTree1OrTable, onNode); | ||||
DropHandler dropHandler = new DropHandler() { | DropHandler dropHandler = new DropHandler() { |
import com.vaadin.event.dd.DragAndDropEvent; | import com.vaadin.event.dd.DragAndDropEvent; | ||||
import com.vaadin.event.dd.DropHandler; | import com.vaadin.event.dd.DropHandler; | ||||
import com.vaadin.event.dd.acceptCriteria.AcceptCriterion; | import com.vaadin.event.dd.acceptCriteria.AcceptCriterion; | ||||
import com.vaadin.event.dd.acceptCriteria.IsDragSource; | |||||
import com.vaadin.event.dd.acceptCriteria.DragSourceIs; | |||||
import com.vaadin.terminal.ThemeResource; | import com.vaadin.terminal.ThemeResource; | ||||
import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; | |||||
import com.vaadin.tests.components.TestBase; | import com.vaadin.tests.components.TestBase; | ||||
import com.vaadin.tests.util.TestUtils; | |||||
import com.vaadin.ui.HorizontalLayout; | import com.vaadin.ui.HorizontalLayout; | ||||
import com.vaadin.ui.Table; | import com.vaadin.ui.Table; | ||||
import com.vaadin.ui.Tree; | |||||
import com.vaadin.ui.Window; | import com.vaadin.ui.Window; | ||||
import com.vaadin.ui.AbstractSelect.AbstractSelectDropTargetDetails; | import com.vaadin.ui.AbstractSelect.AbstractSelectDropTargetDetails; | ||||
import com.vaadin.ui.Tree.Location; | |||||
public class DDTest4 extends TestBase { | public class DDTest4 extends TestBase { | ||||
HorizontalLayout hl = new HorizontalLayout(); | HorizontalLayout hl = new HorizontalLayout(); | ||||
Table table = new Table("Drag and drop sortable table"); | Table table = new Table("Drag and drop sortable table"); | ||||
private Tree tree3; | |||||
@Override | @Override | ||||
protected void setup() { | protected void setup() { | ||||
Window w = getLayout().getWindow(); | Window w = getLayout().getWindow(); | ||||
TestUtils | |||||
.injectCSS( | |||||
w, | |||||
".v-table-row-drag-middle .v-table-cell-content {" | |||||
+ " background-color: inherit ; border-bottom: 1px solid cyan;" | |||||
+ "}"); | |||||
/* darn reindeer has no icons */ | /* darn reindeer has no icons */ | ||||
// hl.addComponent(tree1); | // hl.addComponent(tree1); | ||||
hl.setExpandRatio(table, 1); | hl.setExpandRatio(table, 1); | ||||
table.setWidth("100%"); | table.setWidth("100%"); | ||||
table.setPageLength(10); | table.setPageLength(10); | ||||
table.setRowHeaderMode(Table.ROW_HEADER_MODE_ID); | |||||
table.setSelectable(true); | |||||
populateTable(); | populateTable(); | ||||
addComponent(hl); | addComponent(hl); | ||||
table.setDropHandler(new DropHandler() { | table.setDropHandler(new DropHandler() { | ||||
// accept only drags from this table | // accept only drags from this table | ||||
AcceptCriterion crit = new IsDragSource(table); | |||||
AcceptCriterion crit = new DragSourceIs(table); | |||||
public AcceptCriterion getAcceptCriterion() { | public AcceptCriterion getAcceptCriterion() { | ||||
return crit; | return crit; | ||||
IndexedContainer clone = null; | IndexedContainer clone = null; | ||||
try { | try { | ||||
clone = (IndexedContainer) containerDataSource.clone(); | clone = (IndexedContainer) containerDataSource.clone(); | ||||
int newIndex = containerDataSource.indexOfId(itemIdOver); | |||||
if (dropTargetData.getDropLocation() != Location.TOP) { | |||||
int newIndex = containerDataSource.indexOfId(itemIdOver) - 1; | |||||
if (dropTargetData.getDropLocation() != VerticalDropLocation.TOP) { | |||||
newIndex++; | newIndex++; | ||||
} | } | ||||
if (newIndex < 0) { | |||||
newIndex = 0; | |||||
} | |||||
containerDataSource.removeItem(itemId); | containerDataSource.removeItem(itemId); | ||||
Item newItem = containerDataSource.addItemAt(newIndex, | Item newItem = containerDataSource.addItemAt(newIndex, | ||||
itemId); | itemId); |
import com.vaadin.ui.HorizontalLayout; | import com.vaadin.ui.HorizontalLayout; | ||||
import com.vaadin.ui.Label; | import com.vaadin.ui.Label; | ||||
import com.vaadin.ui.Window; | import com.vaadin.ui.Window; | ||||
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable; | |||||
import com.vaadin.ui.DragAndDropWrapper.DragStartMode; | import com.vaadin.ui.DragAndDropWrapper.DragStartMode; | ||||
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable; | |||||
public class DDTest5 extends TestBase { | public class DDTest5 extends TestBase { | ||||
package com.vaadin.tests.dd; | |||||
import com.vaadin.data.util.BeanItemContainer; | |||||
import com.vaadin.event.DataBoundTransferable; | |||||
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.terminal.Resource; | |||||
import com.vaadin.terminal.ThemeResource; | |||||
import com.vaadin.tests.components.TestBase; | |||||
import com.vaadin.tests.util.TestUtils; | |||||
import com.vaadin.ui.CssLayout; | |||||
import com.vaadin.ui.SplitPanel; | |||||
import com.vaadin.ui.Tree; | |||||
import com.vaadin.ui.Tree.TreeDragMode; | |||||
import com.vaadin.ui.Tree.TreeDropTargetDetails; | |||||
public class DDTest6 extends TestBase { | |||||
java.util.Random r = new java.util.Random(1); | |||||
File[] files = new File[] { new Folder("Docs"), new Folder("Music"), | |||||
new Folder("Images"), new File("document.doc"), | |||||
new File("song.mp3"), new File("photo.jpg") }; | |||||
private DropHandler dh; | |||||
private static int count; | |||||
@Override | |||||
protected void setup() { | |||||
SplitPanel sp = new SplitPanel(SplitPanel.ORIENTATION_HORIZONTAL); | |||||
CssLayout l = new CssLayout(); | |||||
sp.setFirstComponent(l); | |||||
CssLayout l2 = new CssLayout(); | |||||
sp.setSecondComponent(l2); | |||||
final Tree tree1 = new Tree("Volume 1"); | |||||
BeanItemContainer<File> fs1 = new BeanItemContainer<File>(File.class); | |||||
tree1.setContainerDataSource(fs1); | |||||
for (int i = 0; i < files.length; i++) { | |||||
fs1.addBean(files[i]); | |||||
if (files[i] instanceof Folder) { | |||||
tree1.setChildrenAllowed(files[i], true); | |||||
} else { | |||||
tree1.setChildrenAllowed(files[i], false); | |||||
} | |||||
if (i >= files.length / 2) { | |||||
tree1.setParent(files[i], files[i - files.length / 2]); | |||||
} | |||||
} | |||||
tree1.setItemCaptionPropertyId("name"); | |||||
tree1.setItemIconPropertyId("icon"); | |||||
tree1.setDragMode(TreeDragMode.NODE); | |||||
DropHandler dropHandler = new DropHandler() { | |||||
public AcceptCriterion getAcceptCriterion() { | |||||
return AcceptAll.get(); | |||||
} | |||||
public void drop(DragAndDropEvent dropEvent) { | |||||
DataBoundTransferable transferable = (DataBoundTransferable) dropEvent | |||||
.getTransferable(); | |||||
TreeDropTargetDetails dropTargetData = (TreeDropTargetDetails) dropEvent | |||||
.getDropTargetDetails(); | |||||
tree1.setParent(transferable.getItemId(), dropTargetData | |||||
.getItemIdInto()); | |||||
} | |||||
}; | |||||
tree1.setDropHandler(dropHandler); | |||||
l.addComponent(tree1); | |||||
getLayout().setSizeFull(); | |||||
getLayout().addComponent(sp); | |||||
TestUtils | |||||
.injectCSS( | |||||
getLayout().getWindow(), | |||||
"" | |||||
+ ".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;}" | |||||
+ ".v-tree-node-caption-dragfolder { background-color: cyan;} "); | |||||
} | |||||
private final static ThemeResource FOLDER = new ThemeResource( | |||||
"../runo/icons/16/folder.png"); | |||||
private final static ThemeResource DOC = new ThemeResource( | |||||
"../runo/icons/16/document.png"); | |||||
public static class File { | |||||
private Resource icon = DOC; | |||||
private String name; | |||||
public File(String fileName) { | |||||
name = fileName; | |||||
} | |||||
public void setIcon(Resource icon) { | |||||
this.icon = icon; | |||||
} | |||||
public Resource getIcon() { | |||||
return icon; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
} | |||||
public static class Folder extends File { | |||||
public Folder(String fileName) { | |||||
super(fileName); | |||||
setIcon(FOLDER); | |||||
} | |||||
} | |||||
@Override | |||||
protected String getDescription() { | |||||
return "dd: tree and web desktop tests. TODO add traditional icon area on right side with DragAndDropWrapper and absolutelayouts + more files, auto-opening folders"; | |||||
} | |||||
@Override | |||||
protected Integer getTicketNumber() { | |||||
return 119; | |||||
} | |||||
} |
package com.vaadin.tests.util; | |||||
import com.vaadin.ui.Window; | |||||
public class TestUtils { | |||||
/** | |||||
* Crossbrowser hack to dynamically add css current window. Can be used to | |||||
* keep tests css in source files. | |||||
* | |||||
* @param cssString | |||||
*/ | |||||
public static void injectCSS(Window w, String cssString) { | |||||
String script = "if ('\\v'=='v') /* ie only */ {\n" | |||||
+ " document.createStyleSheet().cssText = '" | |||||
+ cssString | |||||
+ "';\n" | |||||
+ " } else {var tag = document.createElement('style'); tag.type = 'text/css';" | |||||
+ " document.getElementsByTagName('head')[0].appendChild(tag);tag[ (typeof " | |||||
+ "document.body.style.WebkitAppearance=='string') /* webkit only */ ? 'innerText' " | |||||
+ ": 'innerHTML'] = '" + cssString + "';}"; | |||||
w.executeJavaScript(script); | |||||
} | |||||
} |