Mercurial > projects > dwt-addons
changeset 30:913f0fd3b347
util dnd
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 03 Apr 2008 19:20:11 +0200 |
parents | f12d40e7da8f |
children | 51d06982c550 |
files | dwtx/jface/util/DelegatingDragAdapter.d dwtx/jface/util/DelegatingDropAdapter.d dwtx/jface/util/TransferDragSourceListener.d dwtx/jface/util/TransferDropTargetListener.d |
diffstat | 4 files changed, 807 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/DelegatingDragAdapter.d Thu Apr 03 19:20:11 2008 +0200 @@ -0,0 +1,290 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.util.DelegatingDragAdapter; + +import dwtx.jface.util.TransferDragSourceListener; +import dwtx.jface.util.SafeRunnable; + +import tango.util.collection.ArraySeq; + +import dwt.dnd.DragSource; +import dwt.dnd.DragSourceEvent; +import dwt.dnd.DragSourceListener; +import dwt.dnd.Transfer; +import dwt.dnd.TransferData; + +import dwt.dwthelper.utils; + +/** + * A <code>DelegatingDragAdapter</code> is a <code>DragSourceListener</code> that + * maintains and delegates to a set of {@link TransferDragSourceListener}s. Each + * TransferDragSourceListener can then be implemented as if it were the + * <code>DragSource's</code> only DragSourceListener. + * <p> + * When a drag is started, a subset of all <code>TransferDragSourceListeners</code> + * is generated and stored in a list of <i>active</i> listeners. This subset is + * calculated by forwarding {@link DragSourceListener#dragStart(DragSourceEvent)} to + * every listener, and checking if the {@link DragSourceEvent#doit doit} field is left + * set to <code>true</code>. + * </p> + * The <code>DragSource</code>'s set of supported Transfer types ({@link + * DragSource#setTransfer(Transfer[])}) is updated to reflect the Transfer types + * corresponding to the active listener subset. + * <p> + * If and when {@link #dragSetData(DragSourceEvent)} is called, a single + * <code>TransferDragSourceListener</code> is chosen, and only it is allowed to set the + * drag data. The chosen listener is the first listener in the subset of active listeners + * whose Transfer supports ({@link Transfer#isSupportedType(TransferData)}) the + * <code>dataType</code> in the <code>DragSourceEvent</code>. + * </p> + * <p> + * The following example snippet shows a <code>DelegatingDragAdapter</code> with two + * <code>TransferDragSourceListeners</code>. One implements drag of text strings, + * the other supports file transfer and demonstrates how a listener can be disabled using + * the dragStart method. + * </p> + * <code><pre> + * final TreeViewer viewer = new TreeViewer(shell, DWT.NONE); + * + * DelegatingDragAdapter dragAdapter = new DelegatingDragAdapter(); + * dragAdapter.addDragSourceListener(new TransferDragSourceListener() { + * public Transfer getTransfer() { + * return TextTransfer.getInstance(); + * } + * public void dragStart(DragSourceEvent event) { + * // always enabled, can control enablement based on selection etc. + * } + * public void dragSetData(DragSourceEvent event) { + * event.data = "Transfer data"; + * } + * public void dragFinished(DragSourceEvent event) { + * // no clean-up required + * } + * }); + * dragAdapter.addDragSourceListener(new TransferDragSourceListener() { + * public Transfer getTransfer() { + * return FileTransfer.getInstance(); + * } + * public void dragStart(DragSourceEvent event) { + * // enable drag listener if there is a viewer selection + * event.doit = !viewer.getSelection().isEmpty(); + * } + * public void dragSetData(DragSourceEvent event) { + * File file1 = new File("C:/temp/file1"); + * File file2 = new File("C:/temp/file2"); + * event.data = new String[] {file1.getAbsolutePath(), file2.getAbsolutePath()}; + * } + * public void dragFinished(DragSourceEvent event) { + * // no clean-up required + * } + * }); + * viewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, dragAdapter.getTransfers(), dragAdapter); + * </pre></code> + * @since 3.0 + */ +public class DelegatingDragAdapter : DragSourceListener { + private ArraySeq!(Object) listeners; + + private ArraySeq!(Object) activeListeners; + + private TransferDragSourceListener currentListener; + + this(){ + listeners = new ArraySeq!(Object); + activeListeners = new ArraySeq!(Object); + } + + /** + * Adds the given <code>TransferDragSourceListener</code>. + * + * @param listener the new listener + */ + public void addDragSourceListener(TransferDragSourceListener listener) { + listeners.append(cast(Object)listener); + } + + /** + * The drop has successfully completed. This event is forwarded to the current + * drag listener. + * Doesn't update the current listener, since the current listener is already the one + * that completed the drag operation. + * + * @param event the drag source event + * @see DragSourceListener#dragFinished(DragSourceEvent) + */ + public void dragFinished(DragSourceEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drag Finished: " + toString()); //$NON-NLS-1$ + SafeRunnable.run(new class SafeRunnable { + DragSourceEvent event_; + this(){ + event_=event; + } + public void run() { + if (currentListener !is null) { + // there is a listener that can handle the drop, delegate the event + currentListener.dragFinished(event_); + } else { + // The drag was canceled and currentListener was never set, so send the + // dragFinished event to all the active listeners. + foreach( e; activeListeners ){ + (cast(TransferDragSourceListener) e) + .dragFinished(event); + } + } + } + }); + currentListener = null; + activeListeners.clear(); + } + + /** + * The drop data is requested. + * Updates the current listener and then forwards the event to it. + * + * @param event the drag source event + * @see DragSourceListener#dragSetData(DragSourceEvent) + */ + public void dragSetData(DragSourceEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drag Set Data: " + toString()); //$NON-NLS-1$ + + updateCurrentListener(event); // find a listener that can provide the given data type + if (currentListener !is null) { + SafeRunnable.run(new class SafeRunnable { + DragSourceEvent event_; + this(){ + event_=event; + } + public void run() { + currentListener.dragSetData(event_); + } + }); + } + } + + /** + * A drag operation has started. + * Forwards this event to each listener. A listener must set <code>event.doit</code> + * to <code>false</code> if it cannot handle the drag operation. If a listener can + * handle the drag, it is added to the list of active listeners. + * The drag is aborted if there are no listeners that can handle it. + * + * @param event the drag source event + * @see DragSourceListener#dragStart(DragSourceEvent) + */ + public void dragStart(DragSourceEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drag Start: " + toString()); //$NON-NLS-1$ + bool doit = false; // true if any one of the listeners can handle the drag + auto transfers = new ArraySeq!(Object); + transfers.capacity(listeners.size()); + + activeListeners.clear(); + for (int i = 0; i < listeners.size(); i++) { + TransferDragSourceListener listener = cast(TransferDragSourceListener) listeners + .get(i); + event.doit = true; // restore event.doit + SafeRunnable.run(new class SafeRunnable { + TransferDragSourceListener listener_; + DragSourceEvent event_; + this(){ + event_=event; + listener_=listener; + } + public void run() { + listener_.dragStart(event_); + } + }); + if (event.doit) { // the listener can handle this drag + transfers.append(listener.getTransfer()); + activeListeners.append(cast(Object)listener); + } + doit |= event.doit; + } + + if (doit) { + (cast(DragSource) event.widget).setTransfer(arraycast!(Transfer)( transfers + .toArray())); + } + + event.doit = doit; + } + + /** + * Returns the <code>Transfer<code>s from every <code>TransferDragSourceListener</code>. + * + * @return the combined <code>Transfer</code>s + */ + public Transfer[] getTransfers() { + Transfer[] types = new Transfer[listeners.size()]; + for (int i = 0; i < listeners.size(); i++) { + TransferDragSourceListener listener = cast(TransferDragSourceListener) listeners + .get(i); + types[i] = listener.getTransfer(); + } + return types; + } + + /** + * Returns <code>true</code> if there are no listeners to delegate drag events to. + * + * @return <code>true</code> if there are no <code>TransferDragSourceListeners</code> + * <code>false</code> otherwise. + */ + public bool isEmpty() { + return listeners.drained(); + } + + /** + * Removes the given <code>TransferDragSourceListener</code>. + * Listeners should not be removed while a drag and drop operation is in progress. + * + * @param listener the <code>TransferDragSourceListener</code> to remove + */ + public void removeDragSourceListener(TransferDragSourceListener listener) { + listeners.remove(cast(Object)listener); + if (currentListener is listener) { + currentListener = null; + } + if (activeListeners.contains(cast(Object)listener)) { + activeListeners.remove(cast(Object)listener); + } + } + + /** + * Updates the current listener to one that can handle the drag. There can + * be many listeners and each listener may be able to handle many <code>TransferData</code> + * types. The first listener found that supports one of the <code>TransferData</ode> + * types specified in the <code>DragSourceEvent</code> will be selected. + * + * @param event the drag source event + */ + private void updateCurrentListener(DragSourceEvent event) { + currentListener = null; + if (event.dataType is null) { + return; + } + foreach( e; activeListeners ){ + TransferDragSourceListener listener = cast(TransferDragSourceListener)e; + + if (listener.getTransfer().isSupportedType(event.dataType)) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Current drag listener: " + listener); //$NON-NLS-1$ + currentListener = listener; + return; + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/DelegatingDropAdapter.d Thu Apr 03 19:20:11 2008 +0200 @@ -0,0 +1,411 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.util.DelegatingDropAdapter; + +import dwtx.jface.util.TransferDropTargetListener; +import dwtx.jface.util.SafeRunnable; + +import tango.util.collection.ArraySeq; + +import dwt.dnd.DND; +import dwt.dnd.DropTargetEvent; +import dwt.dnd.DropTargetListener; +import dwt.dnd.Transfer; +import dwt.dnd.TransferData; + +import dwt.dwthelper.utils; + +/** + * A <code>DelegatingDropAdapter</code> is a <code>DropTargetListener</code> that + * maintains and delegates to a set of {@link TransferDropTargetListener}s. Each + * <code>TransferDropTargetListener</code> can then be implemented as if it were + * the DropTarget's only <code>DropTargetListener</code>. + * <p> + * On <code>dragEnter</code>, <code>dragOperationChanged</code>, <code>dragOver</code> + * and <code>drop</code>, a <i>current</i> listener is obtained from the set of all + * <code>TransferDropTargetListeners</code>. The current listener is the first listener + * to return <code>true</code> for + * {@link TransferDropTargetListener#isEnabled(DropTargetEvent)}. + * The current listener is forwarded all <code>DropTargetEvents</code> until some other + * listener becomes the current listener, or the drop terminates. + * </p> + * <p> + * After adding all <code>TransferDropTargetListeners</code> to the + * <code>DelegatingDropAdapter</code> the combined set of <code>Transfers</code> should + * be set in the DWT <code>DropTarget</code>. <code>#getTransfers()</code> provides the + * set of <code>Transfer</code> types of all <code>TransferDropTargetListeners</code>. + * </p> + * <p> + * The following example snippet shows a <code>DelegatingDropAdapter</code> with two + * <code>TransferDropTargetListeners</code>. One supports dropping resources and + * demonstrates how a listener can be disabled in the isEnabled method. + * The other listener supports text transfer. + * </p> + * <code><pre> + * final TreeViewer viewer = new TreeViewer(shell, DWT.NONE); + * DelegatingDropAdapter dropAdapter = new DelegatingDropAdapter(); + * dropAdapter.addDropTargetListener(new TransferDropTargetListener() { + * public Transfer getTransfer() { + * return ResourceTransfer.getInstance(); + * } + * public bool isEnabled(DropTargetEvent event) { + * // disable drop listener if there is no viewer selection + * if (viewer.getSelection().isEmpty()) + * return false; + * return true; + * } + * public void dragEnter(DropTargetEvent event) {} + * public void dragLeave(DropTargetEvent event) {} + * public void dragOperationChanged(DropTargetEvent event) {} + * public void dragOver(DropTargetEvent event) {} + * public void drop(DropTargetEvent event) { + * if (event.data is null) + * return; + * IResource[] resources = (IResource[]) event.data; + * if (event.detail is DND.DROP_COPY) { + * // copy resources + * } else { + * // move resources + * } + * + * } + * public void dropAccept(DropTargetEvent event) {} + * }); + * dropAdapter.addDropTargetListener(new TransferDropTargetListener() { + * public Transfer getTransfer() { + * return TextTransfer.getInstance(); + * } + * public bool isEnabled(DropTargetEvent event) { + * return true; + * } + * public void dragEnter(DropTargetEvent event) {} + * public void dragLeave(DropTargetEvent event) {} + * public void dragOperationChanged(DropTargetEvent event) {} + * public void dragOver(DropTargetEvent event) {} + * public void drop(DropTargetEvent event) { + * if (event.data is null) + * return; + * System.out.println(event.data); + * } + * public void dropAccept(DropTargetEvent event) {} + * }); + * viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, dropAdapter.getTransfers(), dropAdapter); + * </pre></code> + * @since 3.0 + */ +public class DelegatingDropAdapter : DropTargetListener { + private ArraySeq!(Object) listeners; + + private TransferDropTargetListener currentListener; + + private int originalDropType; + + this(){ + listeners = new ArraySeq!(Object); + } + + /** + * Adds the given <code>TransferDropTargetListener</code>. + * + * @param listener the new listener + */ + public void addDropTargetListener(TransferDropTargetListener listener) { + listeners.append(cast(Object)listener); + } + + /** + * The cursor has entered the drop target boundaries. The current listener is + * updated, and <code>#dragEnter()</code> is forwarded to the current listener. + * + * @param event the drop target event + * @see DropTargetListener#dragEnter(DropTargetEvent) + */ + public void dragEnter(DropTargetEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drag Enter: " + toString()); //$NON-NLS-1$ + originalDropType = event.detail; + updateCurrentListener(event); + } + + /** + * The cursor has left the drop target boundaries. The event is forwarded to the + * current listener. + * + * @param event the drop target event + * @see DropTargetListener#dragLeave(DropTargetEvent) + */ + public void dragLeave(DropTargetEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drag Leave: " + toString()); //$NON-NLS-1$ + setCurrentListener(null, event); + } + + /** + * The operation being performed has changed (usually due to the user changing + * a drag modifier key while dragging). Updates the current listener and forwards + * this event to that listener. + * + * @param event the drop target event + * @see DropTargetListener#dragOperationChanged(DropTargetEvent) + */ + public void dragOperationChanged(DropTargetEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drag Operation Changed to: " + event.detail); //$NON-NLS-1$ + originalDropType = event.detail; + TransferDropTargetListener oldListener = getCurrentListener(); + updateCurrentListener(event); + TransferDropTargetListener newListener = getCurrentListener(); + // only notify the current listener if it hasn't changed based on the + // operation change. otherwise the new listener would get a dragEnter + // followed by a dragOperationChanged with the exact same event. + if (newListener !is null && newListener is oldListener) { + SafeRunnable.run(new class SafeRunnable { + DropTargetEvent event_; + TransferDropTargetListener newListener_; + this(){ + event_=event; + newListener_=newListener; + } + public void run() { + newListener_.dragOperationChanged(event_); + } + }); + } + } + + /** + * The cursor is moving over the drop target. Updates the current listener and + * forwards this event to that listener. If no listener can handle the drag + * operation the <code>event.detail</code> field is set to <code>DND.DROP_NONE</code> + * to indicate an invalid drop. + * + * @param event the drop target event + * @see DropTargetListener#dragOver(DropTargetEvent) + */ + public void dragOver(DropTargetEvent event) { + TransferDropTargetListener oldListener = getCurrentListener(); + updateCurrentListener(event); + TransferDropTargetListener newListener = getCurrentListener(); + + // only notify the current listener if it hasn't changed based on the + // drag over. otherwise the new listener would get a dragEnter + // followed by a dragOver with the exact same event. + if (newListener !is null && newListener is oldListener) { + SafeRunnable.run(new class SafeRunnable { + DropTargetEvent event_; + TransferDropTargetListener newListener_; + this(){ + event_=event; + newListener_=newListener; + } + public void run() { + newListener_.dragOver(event_); + } + }); + } + } + + /** + * Forwards this event to the current listener, if there is one. Sets the + * current listener to <code>null</code> afterwards. + * + * @param event the drop target event + * @see DropTargetListener#drop(DropTargetEvent) + */ + public void drop(DropTargetEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drop: " + toString()); //$NON-NLS-1$ + updateCurrentListener(event); + if (getCurrentListener() !is null) { + SafeRunnable.run(new class SafeRunnable { + DropTargetEvent event_; + this(){ event_=event;} + public void run() { + getCurrentListener().drop(event_); + } + }); + } + setCurrentListener(null, event); + } + + /** + * Forwards this event to the current listener if there is one. + * + * @param event the drop target event + * @see DropTargetListener#dropAccept(DropTargetEvent) + */ + public void dropAccept(DropTargetEvent event) { + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Drop Accept: " + toString()); //$NON-NLS-1$ + if (getCurrentListener() !is null) { + SafeRunnable.run(new class SafeRunnable { + DropTargetEvent event_; + this(){ event_=event;} + public void run() { + getCurrentListener().dropAccept(event_); + } + }); + } + } + + /** + * Returns the listener which currently handles drop events. + * + * @return the <code>TransferDropTargetListener</code> which currently + * handles drop events. + */ + private TransferDropTargetListener getCurrentListener() { + return currentListener; + } + + /** + * Returns the transfer data type supported by the given listener. + * Returns <code>null</code> if the listener does not support any of the + * specified data types. + * + * @param dataTypes available data types + * @param listener <code>TransferDropTargetListener</code> to use for testing + * supported data types. + * @return the transfer data type supported by the given listener or + * <code>null</code>. + */ + private TransferData getSupportedTransferType(TransferData[] dataTypes, + TransferDropTargetListener listener) { + for (int i = 0; i < dataTypes.length; i++) { + if (listener.getTransfer().isSupportedType(dataTypes[i])) { + return dataTypes[i]; + } + } + return null; + } + + /** + * Returns the combined set of <code>Transfer</code> types of all + * <code>TransferDropTargetListeners</code>. + * + * @return the combined set of <code>Transfer</code> types + */ + public Transfer[] getTransfers() { + Transfer[] types = new Transfer[listeners.size()]; + for (int i = 0; i < listeners.size(); i++) { + TransferDropTargetListener listener = cast(TransferDropTargetListener) listeners + .get(i); + types[i] = listener.getTransfer(); + } + return types; + } + + /** + * Returns <code>true</code> if there are no listeners to delegate events to. + * + * @return <code>true</code> if there are no <code>TransferDropTargetListeners</code> + * <code>false</code> otherwise + */ + public bool isEmpty() { + return listeners.drained(); + } + + /** + * Removes the given <code>TransferDropTargetListener</code>. + * Listeners should not be removed while a drag and drop operation is in progress. + * + * @param listener the listener to remove + */ + public void removeDropTargetListener(TransferDropTargetListener listener) { + if (currentListener is listener) { + currentListener = null; + } + listeners.remove(cast(Object)listener); + } + + /** + * Sets the current listener to <code>listener</code>. Sends the given + * <code>DropTargetEvent</code> if the current listener changes. + * + * @return <code>true</code> if the new listener is different than the previous + * <code>false</code> otherwise + */ + private bool setCurrentListener(TransferDropTargetListener listener, + DropTargetEvent event) { + if (currentListener is listener) { + return false; + } + if (currentListener !is null) { + SafeRunnable.run(new class SafeRunnable { + DropTargetEvent event_; + this(){ event_=event;} + public void run() { + currentListener.dragLeave(event_); + } + }); + } + currentListener = listener; + // if (Policy.DEBUG_DRAG_DROP) + // System.out.println("Current drop listener: " + listener); //$NON-NLS-1$ + if (currentListener !is null) { + SafeRunnable.run(new class SafeRunnable { + DropTargetEvent event_; + this(){ event_=event;} + public void run() { + currentListener.dragEnter(event_); + } + }); + } + return true; + } + + /** + * Updates the current listener to one that can handle the drop. There can be many + * listeners and each listener may be able to handle many <code>TransferData</code> + * types. The first listener found that can handle a drop of one of the given + * <code>TransferData</code> types will be selected. + * If no listener can handle the drag operation the <code>event.detail</code> field + * is set to <code>DND.DROP_NONE</code> to indicate an invalid drop. + * + * @param event the drop target event + */ + private void updateCurrentListener(DropTargetEvent event) { + int originalDetail = event.detail; + // revert the detail to the "original" drop type that the User indicated. + // this is necessary because the previous listener may have changed the detail + // to something other than what the user indicated. + event.detail = originalDropType; + + foreach( e; listeners ){ + TransferDropTargetListener listener = cast(TransferDropTargetListener)e; + TransferData dataType = getSupportedTransferType(event.dataTypes, + listener); + if (dataType !is null) { + TransferData originalDataType = event.currentDataType; + // set the data type supported by the drop listener + event.currentDataType = dataType; + if (listener.isEnabled(event)) { + // if the listener stays the same, set its previously determined + // event detail + if (!setCurrentListener(listener, event)) { + event.detail = originalDetail; + } + return; + } + event.currentDataType = originalDataType; + } + } + setCurrentListener(null, event); + event.detail = DND.DROP_NONE; + + // -always- ensure that expand/scroll are on...otherwise + // if a valid drop target is a child of an invalid one + // you can't get there... + event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/TransferDragSourceListener.d Thu Apr 03 19:20:11 2008 +0200 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.util.TransferDragSourceListener; + +import dwt.dnd.DragSourceListener; +import dwt.dnd.Transfer; + +import dwt.dwthelper.utils; + +/** + * A <code>TransferDragSourceListener</code> is a <code>DragSourceListener</code> + * that can handle one type of DWT {@link Transfer}. + * The purpose of a <code>TransferDragSourceListener</code> is to: + * <ul> + * <li>Determine enablement for a drag operation. A <code>TransferDragSourceListener</code> + * will not be used in a drag operation if the <code>DragSourceEvent#doit</code> field + * is set to false in <code>DragSourceListener#dragStart(DragSourceEvent)</code>. + * <li>Set data for a single type of drag and <code>Transfer</code> type. + * </ul> + * <p> + * A <code>DelegatingDragAdapter</code> allows these functions to be implemented + * separately for unrelated types of drags. <code>DelegatingDragAdapter</code> then + * combines the function of each <code>TransferDragSourceListener</code>, while + * allowing them to be implemented as if they were the only <code>DragSourceListener</code>. + * </p> + * @since 3.0 + */ +public interface TransferDragSourceListener : DragSourceListener { + /** + * Returns the <code>Transfer</code> type that this listener can provide data for. + * + * @return the <code>Transfer</code> associated with this listener + */ + Transfer getTransfer(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/TransferDropTargetListener.d Thu Apr 03 19:20:11 2008 +0200 @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.util.TransferDropTargetListener; + +import dwt.dnd.DropTargetEvent; +import dwt.dnd.DropTargetListener; +import dwt.dnd.Transfer; + +import dwt.dwthelper.utils; + +/** + * A <code>TransferDropTargetListener</code> is a <code>DropTragetListener</code> + * that handles one type of DWT {@link Transfer}. + * The purpose of a <code>TransferDropTargetListener</code> is to: + * <ul> + * <li>Determine enablement for a drop operation. A <code>TransferDropTargetListener</code> + * will not be used if <code>isEnabled</code> returns false. + * <li>When enabled, optionally show feedback on the <code>DropTarget</code>. + * <li>Perform the actual drop + * </ul> + * A <code>DelegatingDropAdapter</code> allows these functions to be implemented + * separately for unrelated types of drags. <code>DelegatingDropAdapter</code> then + * combines the function of each <code>TransferDropTargetListener</code>, while + * allowing them to be implemented as if they were the only <code>DragSourceListener</code>. + * @since 3.0 + */ +public interface TransferDropTargetListener : DropTargetListener { + /** + * Returns the <code>Transfer</code> type that this listener can + * accept a drop operation for. + * + * @return the <code>Transfer</code> for this listener + */ + Transfer getTransfer(); + + /** + * Returns <code>true</code> if this listener can handle the drop + * based on the given <code>DropTargetEvent</code>. + * <p> + * This method is called by the <code>DelegatingDropAdapter</code> only + * if the <code>DropTargetEvent</code> contains a transfer data type + * supported by this listener. The <code>Transfer</code> returned by the + * <code>#getTransfer()</code> method is used for this purpose. + * </p> + * + * @param event the drop target event + * @return <code>true</code> if the listener is enabled for the given + * drop target event. + */ + bool isEnabled(DropTargetEvent event); +}