X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java new file mode 100644 index 0000000..3840bc5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dnd/JdtViewerDropAdapter.java @@ -0,0 +1,282 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.dnd; + +//incastrix +//import org.eclipse.jface.text.Assert; +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.TreeItem; + +/** + * A drag and drop adapter to be used together with structured viewers. The + * adapater delegates the dragEnter, dragOperationChanged + * , + * dragOver and dropAccept method to the + * validateDrop method. Furthermore it adds location feedback. + */ +public class JdtViewerDropAdapter implements DropTargetListener { + + /** + * Constant describing the position of the mouse cursor relative to the + * target object. This means the mouse is positioned slightly before the + * target. + */ + protected static final int LOCATION_BEFORE = 1; + + /** + * Constant describing the position of the mouse cursor relative to the + * target object. This means the mouse is positioned slightly after the + * target. + */ + protected static final int LOCATION_AFTER = 2; + + /** + * Constant describing the position of the mouse cursor relative to the + * target object. This means the mouse is positioned directly on the target. + */ + protected static final int LOCATION_ON = 3; + + /** + * Constant describing the position of the mouse cursor relative to the + * target object. This means the mouse is not positioned over or near any + * valid target. + */ + protected static final int LOCATION_NONE = 4; + + /** + * The threshold used to determine if the mouse is before or after an item. + */ + private static final int LOCATION_EPSILON = 5; + + /** + * Style to enable location feedback. + */ + public static final int INSERTION_FEEDBACK = 1 << 1; + + private StructuredViewer fViewer; + + private int fFeedback; + + private boolean fShowInsertionFeedback; + + private int fRequestedOperation; + + private int fLastOperation; + + protected int fLocation; + + protected Object fTarget; + + public JdtViewerDropAdapter(StructuredViewer viewer, int feedback) { + fViewer = viewer; + Assert.isNotNull(fViewer); + fFeedback = feedback; + fLastOperation = -1; + } + + /** + * Controls whether the drop adapter shows insertion feedback or not. + * + * @param showInsertionFeedback + * true if the drop adapter is supposed to show + * insertion feedback. Otherwise false + */ +// public void showInsertionFeedback(boolean showInsertionFeedback) { +// fShowInsertionFeedback = showInsertionFeedback; +// } + + /** + * Returns the viewer this adapter is working on. + */ +// protected StructuredViewer getViewer() { +// return fViewer; +// } + + // ---- Hooks to override + // ----------------------------------------------------- + + /** + * The actual drop has occurred. Calls + * drop(Object target, DropTargetEvent event) + * . + * + * @see DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent) + */ + public void drop(DropTargetEvent event) { + drop(fTarget, event); + } + + /** + * The actual drop has occurred. + * + * @param target + * the drop target in form of a domain element. + * @param event + * the drop traget event + */ + public void drop(Object target, DropTargetEvent event) { + } + + /** + * Checks if the drop is valid. The method calls validateDrop + * (Object target, DropTargetEvent event). Implementors can alter the + * currentDataType field and the detail field + * to give feedback about drop acceptence. + */ + public void validateDrop(DropTargetEvent event) { + validateDrop(fTarget, event, fRequestedOperation); + } + + /** + * Checks if the drop on the current target is valid. The method can alter + * the currentDataType field and the + * detail + * field to give feedback about drop acceptence. + * + * @param target + * the drop target in form of a domain element. + * @param event + * the drop traget event + * @param operation + * the operation requested by the user. + */ + public void validateDrop(Object target, DropTargetEvent event, int operation) { + } + + public void dragEnter(DropTargetEvent event) { + dragOperationChanged(event); + } + + public void dragLeave(DropTargetEvent event) { + fTarget = null; + fLocation = LOCATION_NONE; + } + + public void dragOperationChanged(DropTargetEvent event) { + fRequestedOperation = event.detail; + fTarget = computeTarget(event); + fLocation = computeLocation(event); + validateDrop(event); + fLastOperation = event.detail; + computeFeedback(event); + } + + public void dragOver(DropTargetEvent event) { + Object oldTarget = fTarget; + fTarget = computeTarget(event); + + // set the location feedback + int oldLocation = fLocation; + fLocation = computeLocation(event); + if (oldLocation != fLocation || oldTarget != fTarget + || fLastOperation != event.detail) { + validateDrop(event); + fLastOperation = event.detail; + } else { + event.detail = fLastOperation; + } + computeFeedback(event); + } + + public void dropAccept(DropTargetEvent event) { + fTarget = computeTarget(event); + validateDrop(event); + fLastOperation = event.detail; + } + + /** + * Returns the data held by event.item. Inside a viewer this + * corresponds to the items data model element. + */ + protected Object computeTarget(DropTargetEvent event) { + return event.item == null ? null : event.item.getData(); + } + + /** + * Returns the position of the given coordinates relative to the given + * target. The position is determined to be before, after, or on the item, + * based on some threshold value. The return value is one of the LOCATION_* + * constants defined in this class. + */ + final protected int computeLocation(DropTargetEvent event) { + if (!(event.item instanceof Item)) + return LOCATION_NONE; + + Item item = (Item) event.item; + Point coordinates = fViewer.getControl().toControl( + new Point(event.x, event.y)); + Rectangle bounds = getBounds(item); + if (bounds == null) { + return LOCATION_NONE; + } + if ((coordinates.y - bounds.y) < LOCATION_EPSILON) { + return LOCATION_BEFORE; + } + if ((bounds.y + bounds.height - coordinates.y) < LOCATION_EPSILON) { + return LOCATION_AFTER; + } + return LOCATION_ON; + } + + /** + * Returns the bounds of the given item, or null if it is not + * a valid type of item. + */ + private Rectangle getBounds(Item item) { + if (item instanceof TreeItem) + return ((TreeItem) item).getBounds(); + + if (item instanceof TableItem) + return ((TableItem) item).getBounds(0); + + return null; + } + + /** + * Sets the drag under feedback corresponding to the value of + * fLocation and the INSERTION_FEEDBACK style + * bit. + */ + protected void computeFeedback(DropTargetEvent event) { + if (!fShowInsertionFeedback && fLocation != LOCATION_NONE) { + event.feedback = DND.FEEDBACK_SELECT; + } else { + if (fLocation == LOCATION_BEFORE) { + event.feedback = DND.FEEDBACK_INSERT_BEFORE; + } else if (fLocation == LOCATION_AFTER) { + event.feedback = DND.FEEDBACK_INSERT_AFTER; + } + } + event.feedback |= fFeedback; + } + + /** + * Sets the drop operation to DROP_NODE. + */ + protected void clearDropOperation(DropTargetEvent event) { + event.detail = DND.DROP_NONE; + } + + /** + * Returns the requested drop operation. + */ + protected int getRequestedOperation() { + return fRequestedOperation; + } +}