Bug 10146 - [DND] Consider adopting JDT support classes for Drag and Drop
Summary: [DND] Consider adopting JDT support classes for Drag and Drop
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows 2000
: P2 enhancement (vote)
Target Milestone: 3.0   Edit
Assignee: Stefan Xenos CLA
QA Contact:
URL:
Whiteboard:
Keywords: investigate
Depends on:
Blocks: 101993
  Show dependency tree
 
Reported: 2002-02-24 18:32 EST by Erich Gamma CLA
Modified: 2005-06-28 05:35 EDT (History)
7 users (show)

See Also:


Attachments
Delegating drag/drop (27.04 KB, application/octet-stream)
2003-09-02 16:52 EDT, Knut Radloff CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Erich Gamma CLA 2002-02-24 18:32:37 EST
The following classes are copied or used by several clients (e.g. GEF).
They therefore are generally useful and should be considered to be promoted as 
API at the workbench level.

org.eclipse.jdt.internal.ui.dnd.DelegatingDragAdapter
org.eclipse.jdt.internal.ui.dnd.LocalSelectionTransfer
org.eclipse.jdt.internal.ui.dnd.TransferDragSourceListener
org.eclipse.jdt.internal.ui.dnd.TransferDropTargetListener
Comment 1 Kevin Haaland CLA 2002-05-01 17:33:07 EDT
Nick, do you want these classes? 
Comment 2 Nick Edgar CLA 2002-05-02 09:46:01 EDT
Deferred to v3.
Comment 3 Randy Giffen CLA 2002-08-09 12:54:45 EDT
Reopen to investigate
Comment 4 Randy Hudson CLA 2002-11-14 18:10:04 EST
Several clients within IBM are using the GEF implementation, or have duplicated 
the efforts of creating their own implementations.

This should be moved up to JFace (I guess SWT wouldn't distrubute 
such "utility" classes).
Comment 5 Knut Radloff CLA 2003-04-03 11:58:48 EST
Should integrate the code for 2.2. Investigate adopting the delegates for the 
Navigator.
Comment 6 Randy Hudson CLA 2003-04-03 16:28:34 EST
The GEF implementation is not identical to the JDT implemention.  Important 
differences include:

1) The active drop-target listener may be a function of the mouse location, 
therefore we update the active drop target more frequently.  On every dragOver 
callback we update the active listener.
2) Whenever the current listener is changed, the old listener will be sent 
dragLeave(), the new listener is sent dragEnter().  This is necessary for the 
old listener to clean up any feedback it was showing, and to be consistent with 
the DropListener interface, which guarantees that either dragLeave or 
dragFinished will be called.
3) DelegatingDragAdapter should not be updating the set of Transfers[] inside 
the dragStart method.  See bug 34983.  If the set of transfers go to none, then 
drag will no longer function at all.  So, DelegatingDragAdapter must make all 
Tranfers available via a getTransfers[] method, and calling 
dragSource.setTranfer([]) must be done externally by the client.

You can check out our implementations from CVS, or download them from our 
downloads page.
Comment 7 Knut Radloff CLA 2003-04-17 10:27:02 EDT
Nick suggested asking the SWT team for input regarding enhanced drag and drop 
listener support.
I released an experimental version of the delegating drag and drop support to 
org.eclipse.jface. 
The files are:
org.eclipse.jface.util.DelegatingDragAdapter
org.eclipse.jface.util.DelegatingDropAdapter
org.eclipse.jface.util.TransferDragSourceListener
org.eclipse.jface.util.TransferDropTargetListener

The two concepts/benefits of the delegating drag and drop are:
1) Allowing a 1:1 mapping between transfer type and listener.
  The listener implementation depends on the transfer type. This is certainly 
true for dragSetData and drop. In the Resource Navigator use case the 
dragEnter, dragFinished and dragStart implementations vary depending on the 
transfer type. The listener code will be greatly simplified if it can be 
separated by transfer type.
The current SWT listener in DragSource/DropTarget does not allow for a clean 
separation by transfer type.

2) Controlling enablement of listeners.
  Drag listener enablement often depends on selection state. Based on the 
selection some or all transfer types may not be valid. In the GEF use case 
finer control over drop enablement is needed as well. Drop enablement may 
change based in the drag operation and location.

The question is if SWT can provide more fine grained drag and drop listener 
support. 
Scenario 1) could be supported by adding API that allows setting a listener for 
a specific transfer type. The code I released adds a method #getTransfer() to 
the drag/drop listener interface for this purpose. There are other options.
Scenario 2) could be supported by adding a doit field to the dropTargetEvent. 
The current code uses the dragStart doit field of the DragSourceEvent and adds 
a method #isEnabled to the drop listener interface to determine enablement of a 
particular listener.

Interested parties are encouraged to provide further input they may have, 
including corrections and additions to the two scenarios I provide and the 
changes to SWT that I suggest. Please verify that the SWT changes I suugest and 
the preliminary code I released would be sufficient for your use cases.
Comment 8 Veronika Irvine CLA 2003-04-22 12:33:15 EDT
I am currently implementing DND on the Mac and looking at what additional 
capability could be provided on all platforms.  I am also making a concerted 
effort to make all platforms perform DND in a more consistent manner.  I will 
keep this bug report in mind as I do this.  I expect there will be a number of 
changes for 3.0.
Comment 9 Veronika Irvine CLA 2003-04-22 12:46:23 EDT
Regarding scenario 1 in comment #7.  One possible extension of DND is to allow 
the transfer of more than one type of data in the drop.  I am currently 
looking into this.  Also, a target may support the download of multiple types 
but have a preferred type.  I am not clear on how adding listeners based on 
transfer type will work well in either of these situations.

Regarding scenario 2 in comment #7.  At any time the event.detail field can be 
set to DND.DROP_NONE.  This is the equivalent of setting doit to false for the 
drop target.  I do not see why an additional field is required.
Comment 10 Randy Hudson CLA 2003-04-22 13:25:50 EDT
"At any time the event.detail field can be set to DND.DROP_NONE.  This is the 
equivalent of setting doit to false for the drop target.  I do not see why an 
additional field is required"

Additional field?  Did you mean the additional isEnabled(...) method?  I 
suppose that instead of the isEnabled(..) method, we could call one of the 
existing Drop callbacks and check the detail field.  But, this has a drawback:

It is possible that a delegate would really like to be the active listener, but 
it wants to display the NOT cursor (detail = DROP_NONE) in addition to some 
other feedback (such as scrolling the view or a tooltip).  This case can only 
be handled with the additional isEnabled method.
Comment 11 Veronika Irvine CLA 2003-04-22 13:59:47 EDT
Scenario 2 in comment 7 talks about adding a doit field to the 
DropTargetEvent - that is what I am referring to when I said "additional 
field".

The only purpose I could see of a doit field in the DropTargetEvent is for the 
drop target at any time to say "bug off and stop telling me about any more of 
these DND events - I am not interested".  Since this does not actually 
terminate the DND operation in the OS (some other target may still be 
interested in it), I do not see why the current capability provided by SWT is 
not sufficient.  The delegate can set the feedback and detail fields to none 
if that is what it wants.  If the delegate wants to have an "enabled" field to 
track its state, that is fine but why should the event be changed or the 
reporting of events?
Comment 12 Knut Radloff CLA 2003-04-22 14:51:58 EDT
The idea of delegates is to make life easier when handling many transfer types.
Are you saying that each delegate should track whether it is interested in drop 
events using a flag? That is exactly the kind of duplication the delegation 
mechanism wants to avoid.
Comment 13 Randy Hudson CLA 2003-04-22 17:13:32 EDT
Sorry, I misread comment 7, seeing the "2)" instead of "scenario 2)".

I agree with Veronika, a doit field would not be useful because there would be 
no obvious time when the listener's notification would resume, which is 
required.  Even if a delegate sets doit=false, you must continue to poll it to 
see if it still isn't interested (if doit == false still), in which case what's 
the point.

I think Knut was also proposing:
DragSource#addDragSourceListener(DragSourceListener, Transfer[]);
DropTarget#addDropTargetListener(DropTargetListener, Transfer[]);

But I'm not sure how such API would be used.  What would it mean if two 
droptargetlisteners were added with a common Transfer type?
Comment 14 Knut Radloff CLA 2003-04-23 15:56:18 EDT
The doit field in the DropTargetEvent would work like and could replace the 
isEnabled method in the (transfer) drop target listener. Now, isEnabled is 
called to update the currently active listener in dragEnter, 
dragOperationChanged, dragOver and drop. Instead, the appropriate event would 
be sent to the listeners until one returns doit == true. That listener would 
then be made active listener. Again, the purpose is the same as with the 
isEnabled method.

The API I envisioned to address scenario 1 would support exactly a 1:1 mapping. 
E.g., addDragSourceListener(DragSourceListener, Transfer)
The semantics when there is more than one listener for the same transfer type 
currently (in the experimental code) is to select the first one, just like in 
GEF. The 1:1 relationship should probably be enforced by the API and exceptions 
thrown.

It seems that multiple transfer types and delegating drag/drop listeners are 
conflicting features. Delegation aims to separate DnD by transfer type whereas 
multiple transfer types requires knowledge about more than one and probably all 
of them.
Comment 15 Knut Radloff CLA 2003-04-29 13:33:52 EDT
Another use case:
WSAD is using a form of delegating DnD in the "Data Definition" and "DB 
Servers" views in the Data Perspective. It is similar to scenario 2, selection 
dependent transfer type enablement. 
The difference is that more than one delegation listener is defined for one 
transfer type. Different listeners handle different selections in the view. 
They all use the same transfer type. This suggests that we would need more than 
just an addDragSourceListener(DragSourceListener, Transfer) API. E.g., this is 
a 1:n relationship of transfer type and listener.
Comment 16 Knut Radloff CLA 2003-09-02 16:52:59 EDT
Created attachment 5948 [details]
Delegating drag/drop

Changes to Resource Navigator for using delegating DND.
The Delegating DND framework itself is released in org.eclipse.jface. It is
marked as experimental and should be removed if it is decided that this should
not be included in 3.0.
Should consider this when working on drag and drop design for General Purpose
Navigator.
Comment 17 Knut Radloff CLA 2003-09-02 17:13:21 EDT
Reassigning to Nick since he is taking ownership of DND.
Comment 18 Nick Edgar CLA 2005-04-28 16:02:41 EDT
Stefan now owns the DND support in the workbench.
Nothing planned here for 3.1, but should revisit post-3.1.
Comment 19 Nick Edgar CLA 2005-04-28 16:10:36 EDT
The following utility classes were added to JFace as "experimental" in 3.0:
DelegatingDragAdapter
DelegatingDropAdapter
TransferDragSourceListener
TransferDropTargetListener

I have removed the "experimental" tags in 3.1.
Comment 20 Randy Hudson CLA 2005-04-28 16:51:08 EDT
So this is fixed then, milestone = 3.0
Comment 21 Nick Edgar CLA 2005-04-28 17:20:26 EDT
I guess we did satisfy the original request.
Closing then.