/* * Ext GWT 2.2.4 - Ext for GWT * Copyright(c) 2007-2010, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.dnd; import java.util.List; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.dnd.DND.Feedback; import com.extjs.gxt.ui.client.event.DNDEvent; import com.extjs.gxt.ui.client.util.Rectangle; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.google.gwt.user.client.Element; /** * A <code>DropTarget</code> implementation for Grids. Supports both inserts and * appends, specified using * {@link #setOperation(com.extjs.gxt.ui.client.dnd.DND.Operation)}. * <p /> * Supported drag data: * <ul> * <li>A single ModelData instance.</li> * <li>A List of ModelData instances.</li> * <li>A List of TreeStoreModel instances (children are ignored). * </ul> */ public class GridDropTarget extends DropTarget { protected ModelData activeItem; protected Grid<ModelData> grid; protected int insertIndex; boolean before; private boolean autoScroll = true; private ScrollSupport scrollSupport; /** * Creates a new drop target instance. * * @param grid the target grid */ @SuppressWarnings({"unchecked", "rawtypes"}) public GridDropTarget(Grid grid) { super(grid); this.grid = grid; } /** * Returns the target grid component. * * @return the grid */ public Grid<ModelData> getGrid() { return grid; } /** * Returns true if auto scroll is enabled (defaults to true). * * @return true if auto scroll enabled */ public boolean isAutoScroll() { return autoScroll; } /** * True to automatically scroll the tree when the user hovers over the top and * bottom of the tree grid (defaults to true). * * @see ScrollSupport * * @param autoScroll true to enable auto scroll */ public void setAutoScroll(boolean autoScroll) { this.autoScroll = autoScroll; } @Override protected void onDragCancelled(DNDEvent event) { super.onDragCancelled(event); if (autoScroll) { scrollSupport.stop(); } } @Override protected void onDragDrop(DNDEvent e) { super.onDragDrop(e); Object data = e.getData(); List<ModelData> models = prepareDropData(data, true); if (models.size() > 0) { if (feedback == Feedback.APPEND) { grid.getStore().add(models); } else { grid.getStore().insert(models, insertIndex); } } insertIndex = -1; activeItem = null; if (autoScroll) { scrollSupport.stop(); } } @Override protected void onDragEnter(DNDEvent e) { super.onDragEnter(e); e.setCancelled(false); e.getStatus().setStatus(true); if (autoScroll) { if (scrollSupport == null) { scrollSupport = new ScrollSupport(grid.getView().getScroller()); } else if (scrollSupport.getScrollElement() == null) { scrollSupport.setScrollElement(grid.getView().getScroller()); } scrollSupport.start(); } } @Override protected void onDragFail(DNDEvent event) { super.onDragFail(event); if (autoScroll) { scrollSupport.stop(); } } @Override protected void onDragLeave(DNDEvent e) { super.onDragLeave(e); if (autoScroll) { scrollSupport.stop(); } } @Override protected void onDragMove(DNDEvent event) { if (!event.within(grid.getView().getBody().dom)) { event.setCancelled(true); event.getStatus().setStatus(false); return; } event.setCancelled(false); event.getStatus().setStatus(true); } @Override protected void showFeedback(DNDEvent event) { event.getStatus().setStatus(true); if (feedback == Feedback.INSERT) { Element row = grid.getView().findRow(event.getTarget()).cast(); if (row == null && grid.getStore().getCount() > 0) { row = grid.getView().getRow(grid.getStore().getCount() - 1).cast(); } if (row != null) { int height = row.getOffsetHeight(); int mid = height / 2; mid += row.getAbsoluteTop(); int y = event.getClientY(); before = y < mid; int idx = grid.getView().findRowIndex(row); activeItem = grid.getStore().getAt(idx); insertIndex = adjustIndex(event, idx); showInsert(event, row); } else { insertIndex = 0; } } } private int adjustIndex(DNDEvent event, int index) { Object data = event.getData(); int i = index; List<ModelData> models = prepareDropData(data, true); for (ModelData m : models) { int idx = grid.getStore().indexOf(m); if (idx > -1 && (before ? idx < index : idx <= index)) { i--; } } return before ? i : i + 1; } protected void showInsert(DNDEvent event, Element row) { Insert insert = Insert.get(); insert.show(row); Rectangle rect = El.fly(row).getBounds(); int y = !before ? (rect.y + rect.height - 4) : rect.y - 2; insert.el().setBounds(rect.x, y, rect.width, 6); } }