org.eclipse.swt.dnd.DropTarget Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.dnd;
import java.util.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cocoa.*;
import org.eclipse.swt.widgets.*;
/**
*
* Class DropTarget
defines the target object for a drag and drop transfer.
*
* IMPORTANT: This class is not intended to be subclassed.
*
* This class identifies the Control
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 Control
and a DropTarget
.
* The DropTarget can receive data from within the same application or from other applications
* (such as text dragged from a text editor like Word).
*
*
* 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);
*
*
* The application is notified of data being dragged over this control and of when a drop occurs by
* implementing the interface DropTargetListener
which uses the class
* DropTargetEvent
. The application can modify the type of drag being performed
* on this Control at any stage of the drag by modifying the event.detail
field or the
* event.currentDataType
field. When the data is dropped, it is the responsibility of
* the application to copy this data for its own purposes.
*
*
*
*
* 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
* }
* });
*
-
*
- Styles
- DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK *
- Events
- DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged, * DND.DropAccept, DND.Drop *
DropTargetListener
* interface.
*
* -
*
dragEnter
is called when the cursor has entered the drop target boundaries *dragLeave
is called when the cursor has left the drop target boundaries and just before * the drop occurs or is cancelled. *dragOperationChanged
is called when the operation being performed has changed * (usually due to the user changing the selected modifier key(s) while dragging) *dragOver
is called when the cursor is moving over the drop target *dropAccept
is called just before the drop is performed. The drop target is given * the chance to change the nature of the drop or veto the drop by setting theevent.detail
field *drop
is called when the data is being dropped *
-
*
- ERROR_NULL_ARGUMENT - if the listener is null *
-
*
- ERROR_WIDGET_DISPOSED - if the receiver has been disposed *
- ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver *
DropTarget
to allow data to be dropped on the specified
* Control
.
* Creating an instance of a DropTarget may cause system resources to be allocated
* depending on the platform. It is therefore mandatory that the DropTarget instance
* be disposed when no longer required.
*
* @param control the Control
over which the user positions the cursor to drop the data
* @param style the bitwise OR'ing of allowed operations; this may be a combination of any of
* DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
*
* @exception SWTException -
*
- ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent *
- ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass *
-
*
- ERROR_CANNOT_INIT_DROP - unable to initiate drop target; this will occur if more than one * drop target is created for a control or if the operating system will not allow the creation * of the drop target *
NOTE: ERROR_CANNOT_INIT_DROP should be an SWTException, since it is a * recoverable error, but can not be changed due to backward compatibility.
* * @see Widget#dispose * @see DropTarget#checkSubclass * @see DND#DROP_NONE * @see DND#DROP_COPY * @see DND#DROP_MOVE * @see DND#DROP_LINK */ public DropTarget(Control control, int style) { super(control, checkStyle(style)); this.control = control; if (control.getData(DND.DROP_TARGET_KEY) != null) { DND.error(DND.ERROR_CANNOT_INIT_DROP); } control.setData(DND.DROP_TARGET_KEY, this); controlListener = event -> { if (!DropTarget.this.isDisposed()) { DropTarget.this.dispose(); } }; control.addListener (SWT.Dispose, controlListener); this.addListener(SWT.Dispose, event -> onDispose()); Object effect = control.getData(DEFAULT_DROP_TARGET_EFFECT); if (effect instanceof DropTargetEffect) { dropEffect = (DropTargetEffect) effect; } else if (control instanceof Table) { dropEffect = new TableDropTargetEffect((Table) control); } else if (control instanceof Tree) { dropEffect = new TreeDropTargetEffect((Tree) control); } addDragHandlers(); } static long /*int*/ dropTargetProc(long /*int*/ id, long /*int*/ sel) { Display display = Display.findDisplay(Thread.currentThread()); if (display == null || display.isDisposed()) return 0; Widget widget = display.findWidget(id); if (widget == null) return 0; DropTarget dt = (DropTarget)widget.getData(DND.DROP_TARGET_KEY); if (dt == null) return 0; if (sel == OS.sel_wantsPeriodicDraggingUpdates) { return dt.wantsPeriodicDraggingUpdates(id, sel) ? 1 : 0; } return 0; } static long /*int*/ dropTargetProc(long /*int*/ id, long /*int*/ sel, long /*int*/ arg0) { Display display = Display.findDisplay(Thread.currentThread()); if (display == null || display.isDisposed()) return 0; Widget widget = display.findWidget(id); if (widget == null) return 0; DropTarget dt = (DropTarget)widget.getData(DND.DROP_TARGET_KEY); if (dt == null) return 0; // arg0 is _always_ the sender, and implements NSDraggingInfo. // Looks like an NSObject for our purposes, though. NSObject sender = new NSObject(arg0); if (sel == OS.sel_draggingEntered_) { return dt.draggingEntered(id, sel, sender); } else if (sel == OS.sel_draggingUpdated_) { return dt.draggingUpdated(id, sel, sender); } else if (sel == OS.sel_draggingExited_) { dt.draggingExited(id, sel, sender); } else if (sel == OS.sel_performDragOperation_) { return dt.performDragOperation(id, sel, sender) ? 1 : 0; } return 0; } static long /*int*/ dropTargetProc(long /*int*/ id, long /*int*/ sel, long /*int*/ arg0, long /*int*/ arg1, long /*int*/ arg2, long /*int*/ arg3) { Display display = Display.findDisplay(Thread.currentThread()); if (display == null || display.isDisposed()) return 0; Widget widget = display.findWidget(id); if (widget == null) return 0; DropTarget dt = (DropTarget)widget.getData(DND.DROP_TARGET_KEY); if (dt == null) return 0; if (sel == OS.sel_outlineView_acceptDrop_item_childIndex_) { return dt.outlineView_acceptDrop_item_childIndex(id, sel, arg0, arg1, arg2, arg3) ? 1 : 0; } else if (sel == OS.sel_outlineView_validateDrop_proposedItem_proposedChildIndex_) { return dt.outlineView_validateDrop_proposedItem_proposedChildIndex(id, sel, arg0, arg1, arg2, arg3); } else if (sel == OS.sel_tableView_acceptDrop_row_dropOperation_) { return dt.tableView_acceptDrop_row_dropOperation(id, sel, arg0, arg1, arg2, arg3) ? 1 : 0; } else if (sel == OS.sel_tableView_validateDrop_proposedRow_proposedDropOperation_) { return dt.tableView_validateDrop_proposedRow_proposedDropOperation(id, sel, arg0, arg1, arg2, arg3); } return 0; } /** * 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; } /** * Returns an array of listeners who will be notified when a drag and drop * operation is in progress, by sending it one of the messages defined in * theDropTargetListener
interface.
*
* @return the listeners who will be notified when a drag and drop
* operation is in progress
*
* @exception SWTException -
*
- ERROR_WIDGET_DISPOSED - if the receiver has been disposed *
- ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver *
-
*
- ERROR_NULL_ARGUMENT - if the listener is null *
-
*
- ERROR_WIDGET_DISPOSED - if the receiver has been disposed *
- ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver *
-
*
- ERROR_NULL_ARGUMENT - if transferAgents is null *