Package com.sencha.gxt.dnd.core.client

Source Code of com.sencha.gxt.dnd.core.client.ListViewDropTarget

/**
* Sencha GXT 3.1.0-beta - Sencha for GWT
* Copyright(c) 2007-2014, Sencha, Inc.
* licensing@sencha.com
*
* http://www.sencha.com/products/gxt/license/
*/
package com.sencha.gxt.dnd.core.client;

import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.sencha.gxt.core.client.GXTLogConfiguration;
import com.sencha.gxt.core.client.dom.XElement;
import com.sencha.gxt.core.client.util.Rectangle;
import com.sencha.gxt.dnd.core.client.DND.Feedback;
import com.sencha.gxt.dnd.core.client.DND.Operation;
import com.sencha.gxt.widget.core.client.ListView;

/**
* Enables a {@link ListView} to act as the target of a drag and drop operation.
* <p/>
* Use {@link #setFeedback(com.sencha.gxt.dnd.core.client.DND.Feedback)} to specify whether to allow inserting items
* between rows, appending items to the end, or both (defaults to {@link Feedback#BOTH}).
* <p/>
* Use {@link #setOperation(com.sencha.gxt.dnd.core.client.DND.Operation)} to specify whether to move items or copy
* them (defaults to {@link Operation#MOVE}).
*
* @param <M> the model type
*/
public class ListViewDropTarget<M> extends DropTarget {

  private static final Logger logger = Logger.getLogger(ListViewDropTarget.class.getName());

  protected ListView<M, ?> listView;
  protected M activeItem;
  protected int insertIndex;
  protected boolean before;

  private boolean autoSelect;

  /**
   * Creates a drop target for the specified list view.
   *
   * @param listView the list view to enable as a drop target
   */
  public ListViewDropTarget(ListView<M, ?> listView) {
    super(listView);
    this.listView = listView;
  }

  /**
   * Returns the list view associated with this drop target.
   *
   * @return the list view associated with this drop target
   */
  public ListView<M, ?> getListView() {
    return listView;
  }

  /**
   * Returns true if auto select is enabled.
   *
   * @return the auto select state
   */
  public boolean isAutoSelect() {
    return autoSelect;
  }

  /**
   * True to automatically select any new items created after a drop (defaults to false).
   *
   * @param autoSelect true to auto select
   */
  public void setAutoSelect(boolean autoSelect) {
    this.autoSelect = autoSelect;
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  @Override
  protected void onDragDrop(DndDropEvent event) {
    super.onDragDrop(event);

    Object data = event.getData();
    List<M> models = (List) prepareDropData(data, true);
    if (models.size() > 0) {
      if (feedback == Feedback.APPEND) {
        listView.getStore().addAll(models);
      } else {
        listView.getStore().addAll(insertIndex, models);
      }
    }
    insertIndex = -1;
    activeItem = null;
  }

  @Override
  protected void onDragEnter(DndDragEnterEvent event) {
    super.onDragEnter(event);
    event.setCancelled(true);
    event.getStatusProxy().setStatus(true);
  }

  @Override
  protected void onDragLeave(DndDragLeaveEvent event) {
    super.onDragLeave(event);
    Insert insert = Insert.get();
    insert.setVisible(false);
  }

  @Override
  protected void onDragMove(DndDragMoveEvent event) {
    XElement target = event.getDragMoveEvent().getNativeEvent().getEventTarget().cast();
    if (!listView.getElement().isOrHasChild(target)) {
      event.setCancelled(true);
      event.getStatusProxy().setStatus(false);
    } else {
      event.setCancelled(false);
      event.getStatusProxy().setStatus(true);
    }
  }

  @Override
  protected void showFeedback(DndDragMoveEvent event) {
    event.getStatusProxy().setStatus(true);

    NativeEvent e = event.getDragMoveEvent().getNativeEvent().cast();

    if (feedback == Feedback.INSERT) {
      Element row = listView.findElement((Element) e.getEventTarget().cast());

      if (row == null && listView.getStore().size() > 0) {
        row = listView.getElement(listView.getStore().size() - 1).cast();
      }

      if (row != null) {
        int height = row.getOffsetHeight();
        int mid = height / 2;
        mid += row.getAbsoluteTop();
        int y = e.getClientY();
        before = y < mid;
        int idx = listView.findElementIndex(row);

        activeItem = listView.getStore().get(idx);
        insertIndex = adjustIndex(event, idx);

        showInsert(event, row);
      } else {
        insertIndex = 0;
      }
    }
  }

  private int adjustIndex(DndDragMoveEvent event, int index) {
    Object data = event.getData();
    int i = index;
    @SuppressWarnings("unchecked")
    List<M> models = (List<M>) prepareDropData(data, true);
    for (M m : models) {
      int idx = listView.getStore().indexOf(m);
      if (idx > -1 && (before ? idx < index : idx <= index)) {
        i--;
      }
    }
    return before ? i : i + 1;
  }

  private void showInsert(DndDragMoveEvent event, Element row) {
    Insert insert = Insert.get();
    insert.show(row.getParentElement());

    Rectangle rect = row.<XElement> cast().getBounds();

    int y = rect.getY() - 2;
    if (!before) {
      y = rect.getY() + rect.getHeight() - 4;
    }

    insert.getElement().makePositionable(true);
    insert.getElement().setBounds(rect.getX(), y, rect.getWidth(), 6);

    if (GXTLogConfiguration.loggingIsEnabled()) {
      logger.finest("showInsert: y=" + y + " before=" + before + " rect=" + rect);
    }
  }

}
TOP

Related Classes of com.sencha.gxt.dnd.core.client.ListViewDropTarget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.