package org.eclipse.swt.dnd; | |
import org.eclipse.swt.*; | |
import org.eclipse.swt.graphics.*; | |
import org.eclipse.swt.widgets.*; | |
import org.eclipse.swt.internal.*; | |
import org.eclipse.swt.internal.photon.*; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved | |
*/ | |
/** | |
* | |
* Class <code>DropTarget</code> defines the target object for a drag and drop transfer. | |
* | |
* IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
* | |
* <p>This class identifies the <code>Control</code> over which the user must position the cursor | |
* in order to drop the data being transferred. It also specifies what data types can be dropped on | |
* this control and what operations can be performed. You may have several DropTragets in an | |
* application but there can only be a one to one mapping between a <code>Control</code> and a <code>DropTarget</code>. | |
* The DropTarget can receive data from within the same application or from other applications | |
* (such as text dragged from a text editor like Word).</p> | |
* | |
* <code><pre> | |
* int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK; | |
* Transfer[] types = new Transfer[] {TextTransfer.getInstance()}; | |
* DropTarget target = new DropTarget(label, operations); | |
* target.setTransfer(types); | |
* </code></pre> | |
* | |
* <p>The application is notified of data being dragged over this control and of when a drop occurs by | |
* implementing the interface <code>DropTargetListener</code> which uses the class | |
* <code>DropTargetEvent</code>. The application can modify the type of drag being performed | |
* on this Control at any stage of the drag by modifying the <code>event.detail</code> field or the | |
* <code>event.currentDataType</code> field. When the data is dropped, it is the responsibility of | |
* the application to copy this data for its own purposes. | |
* | |
* <code><pre> | |
* target.addDropListener (new DropTargetListener() { | |
* public void dragEnter(DropTargetEvent event) {}; | |
* public void dragOver(DropTargetEvent event) {}; | |
* public void dragLeave(DropTargetEvent event) {}; | |
* public void dragOperationChanged(DropTargetEvent event) {}; | |
* public void dropAccept(DropTargetEvent event) {} | |
* public void drop(DropTargetEvent event) { | |
* // A drop has occurred, copy over the data | |
* if (event.data == null) { // no data to copy, indicate failure in event.detail | |
* event.detail = DND.DROP_NONE; | |
* return; | |
* } | |
* label.setText ((String) event.data); // data copied to label text | |
* } | |
* }); | |
* </pre></code> | |
* | |
* <dl> | |
* <dt><b>Styles</b> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK | |
* <dt><b>Events</b> <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged, | |
* DND.Drop, DND.DropAccept | |
* </dl> | |
*/ | |
public class DropTarget extends Widget { | |
private Callback dropProc; | |
private Callback transferProc; | |
private Callback dragProc; | |
// info for registering as a droptarget | |
private Control control; | |
private Listener controlListener; | |
private Transfer[] transferAgents = new Transfer[0]; | |
// info about data being dragged over site | |
private TransferData selectedDataType; | |
private TransferData[] dataTypes; | |
private int dropTransferObject; | |
private DragUnderEffect effect; | |
public DropTarget(Control control, int style) { | |
super (control, checkStyle(style)); | |
this.control = control; | |
controlListener = new Listener () { | |
public void handleEvent (Event event) { | |
if (!DropTarget.this.isDisposed()){ | |
DropTarget.this.dispose(); | |
} | |
} | |
}; | |
control.addListener (SWT.Dispose, controlListener); | |
this.addListener (SWT.Dispose, new Listener () { | |
public void handleEvent (Event event) { | |
//onDispose(); | |
} | |
}); | |
if (control instanceof Tree) { | |
effect = new TreeDragUnderEffect((Tree)control); | |
} else if (control instanceof Table) { | |
effect = new TableDragUnderEffect((Table)control); | |
} else { | |
effect = new NoDragUnderEffect(control); | |
} | |
} | |
/** | |
* Adds the listener to receive events. | |
* <p> | |
* | |
* @param listener the listener | |
* | |
* @exception SWTError(ERROR_THREAD_INVALID_ACCESS) | |
* when called from the wrong thread | |
* @exception SWTError(ERROR_WIDGET_DISPOSED) | |
* when the widget has been disposed | |
* @exception SWTError(ERROR_NULL_ARGUMENT) | |
* when listener is null | |
*/ | |
public void addDropListener(DropTargetListener listener) { | |
if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT); | |
DNDListener typedListener = new DNDListener (listener); | |
addListener (DND.DragEnter, typedListener); | |
addListener (DND.DragLeave, typedListener); | |
addListener (DND.DragOver, typedListener); | |
addListener (DND.DragOperationChanged, typedListener); | |
addListener (DND.Drop, typedListener); | |
addListener (DND.DropAccept, typedListener); | |
} | |
static int checkStyle (int style) { | |
if (style == SWT.NONE) return DND.DROP_MOVE; | |
return style; | |
} | |
/** | |
* Returns the Control which is registered for this DropTarget. This is the control over which the | |
* user positions the cursor to drop the data. | |
* | |
* @return the Control which is registered for this DropTarget | |
* | |
*/ | |
public Control getControl () { | |
return control; | |
} | |
public Display getDisplay () { | |
if (control == null) DND.error(SWT.ERROR_WIDGET_DISPOSED); | |
return control.getDisplay (); | |
} | |
/** | |
* Returns the list of data types that can be transferred to this DropTarget. | |
* | |
* @return the list of data types that can be transferred to this DropTarget | |
* | |
*/ | |
public Transfer[] getTransfer(){ | |
return transferAgents; | |
} | |
public void notifyListeners (int eventType, Event event) { | |
Point coordinates = new Point(event.x, event.y); | |
coordinates = control.toControl(coordinates); | |
if (this.control instanceof Tree) { | |
event.item = ((Tree)control).getItem(coordinates); | |
} | |
if (this.control instanceof Table) { | |
event.item = ((Table)control).getItem(coordinates); | |
} | |
super.notifyListeners(eventType, event); | |
} | |
/** | |
* Adds the listener to receive events. | |
* <p> | |
* | |
* @param listener the listener | |
* | |
* @exception SWTError(ERROR_THREAD_INVALID_ACCESS) | |
* when called from the wrong thread | |
* @exception SWTError(ERROR_WIDGET_DISPOSED) | |
* when the widget has been disposed | |
* @exception SWTError(ERROR_NULL_ARGUMENT) | |
* when listener is null | |
*/ | |
public void removeDropListener(DropTargetListener listener) { | |
if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT); | |
removeListener (DND.DragEnter, listener); | |
removeListener (DND.DragLeave, listener); | |
removeListener (DND.DragOver, listener); | |
removeListener (DND.DragOperationChanged, listener); | |
removeListener (DND.Drop, listener); | |
removeListener (DND.DropAccept, listener); | |
} | |
public void setTransfer(Transfer[] transferAgents){ | |
} | |
protected void checkSubclass () { | |
String name = getClass().getName (); | |
String validName = DropTarget.class.getName(); | |
if (!validName.equals(name)) { | |
DND.error (SWT.ERROR_INVALID_SUBCLASS); | |
} | |
} | |
} |