package scrum.client.dnd; import scrum.client.common.ABlockWidget; import scrum.client.common.BlockListWidget; import com.allen_sauer.gwt.dnd.client.DragContext; import com.allen_sauer.gwt.dnd.client.VetoDragException; import com.allen_sauer.gwt.dnd.client.drop.DropController; import com.allen_sauer.gwt.dnd.client.util.CoordinateLocation; import com.allen_sauer.gwt.dnd.client.util.WidgetArea; import com.google.gwt.user.client.ui.Widget; public class BlockDropController implements DropController { private BlockListWidget targetList; private ABlockWidget targetBlock; public BlockDropController(ABlockWidget targetBlock) { this.targetBlock = targetBlock; this.targetList = targetBlock.getList(); } public Widget getDropTarget() { return targetBlock; } public void onDrop(DragContext context) { Widget draggable = context.draggable; if (!isDropAllowed(draggable)) return; WidgetArea area = new WidgetArea(targetBlock, null); CoordinateLocation location = new CoordinateLocation(context.mouseX, context.mouseY); if (draggable instanceof ABlockWidget) { // move inside list ABlockWidget draggedBlock = (ABlockWidget) draggable; int fromIndex = targetList.indexOfBlock(draggedBlock); int toIndex = targetList.indexOfBlock(targetBlock); if (fromIndex > toIndex) toIndex++; if (isHigher(area, location)) toIndex--; targetList.drop(draggedBlock, toIndex); } } public void onEnter(DragContext context) {} public void onLeave(DragContext context) { targetList.deactivateDndMarkers(); } public void onMove(DragContext context) { if (!isDropAllowed(context.draggable)) return; WidgetArea area = new WidgetArea(targetBlock, null); CoordinateLocation location = new CoordinateLocation(context.mouseX, context.mouseY); boolean isHigher = isHigher(area, location); if (isHigher) { targetBlock.getList().activateDndMarkerBefore(targetBlock); } else { targetBlock.getList().activateDndMarkerAfter(targetBlock); } } public void onPreviewDrop(DragContext context) throws VetoDragException { if (!isDropAllowed(context.draggable)) { throw new VetoDragException(); } } private boolean isHigher(WidgetArea area, CoordinateLocation location) { int mid = area.getCenter().getTop(); return location.getTop() < mid; } private boolean isDropAllowed(Widget draggable) { if (draggable instanceof ABlockWidget) { ABlockWidget block = (ABlockWidget) draggable; return targetBlock.getList().acceptsDrop(block); } return false; } }