12-29-2005 11:54 PM
I've got some concerns with drag and drop events and how
they relate to the tree control. Here is a simple use case: drag and drop
nodes in a tree control. In order to do anything useful beyond the
degenerate case of allowing all nodes to be dragged and dropped on any other
node, I need to know the Source Tag and the Target Tag (to both validate and
process these events, I need to know which item was dragged and dropped onto
which other item). In LabVIEW 7.1 Source Tag and Target Tag are available
as event data. However, in LabVIEW 8.0 the new control drag and drop
events supersede the tree control drag and drop events (the tree drag and drop
events have been depreciated and a warning dialog will be displayed when
opening 7.1 code that calls these events). OK, here is the problem...
there are no longer Source Tag and Target Tag event data in any of the LabVIEW
8.0 tree control drag and drop events. I have found a work-around by writing
a routine that calculates which element the mouse is hovering over, but this is
very non-direct and a bit of a kludge.
Another issue is that the source item disappears from the tree control after
the drop event is processed. This is not the end of the world (I can
recreate the deleted node and child nodes), but it is still a bit of a pain and
I believe that this is a bug.
So, am I off-track? Any thoughts?
01-03-2006 08:52 AM
(Sorry for the length of this post.)
First of all, as the developer of drag and drop in LabVIEW 8.0, thank you for using my feature. Implementing this was a big challenge, especially since drag and drop was so limited in 7.1.
Using drag and drop events is harder than it used to be. I apolgize for that. However, I think that you will see that the change was justified, and that we have ways to do virtually everything you could do in 7.1.
First, let me explain why we changed the drag and drop events.
In 7.1, drag and drop was very limited, and we only had events for drag and drop in a tree control. This meant that we could expose more information in the event structure. For example, 'source tag' and 'destination tag' both make sense if your drag source and target are both tree controls (or, technically, the same tree control).
In 8.0, drag and drop is much more general: you can drag from one tree to another; you can drag from any control to any other control; you can drag from one VI to another; a drag target can accept or decline all kinds of data; and you can register for events for all of these behaviors.
This reduced what we could expose in the event structure. Suddenly in 8.0, 'source tag' and 'destination tag' *don't* make sense, because your drag source and drag target could be *anything*.
I understand that this makes your use case harder -- but it makes many, many more uses possible.
Now, let's talk about your use case: filtering tree drag and drop like you did in 7.1.
In the tree's popup menu, there's an option called "Allow Drag/Drop Outside Control". Turn this off, and the tree won't be able to drag tree items to other controls, or accept drags from other controls (in other words, it'll behave like it did in 7.1).
To get the destination tag, use the "Point to Row Column" method on the tree control. Just pass it the point that you get from the drag/drop event. [1]
To get the source tag, use the LV_TREE_TAG data from the "Get Drag Drop Data" primitive. This is the source tag. (Alternately, you could cache the source tag in the "Drag Starting" event.)
Finally let's address your last comment:
Another issue is that the source item disappears from the tree control after the drop event is processed. This is not the end of the world (I can recreate the deleted node and child nodes), but it is still a bit of a pain and I believe that this is a bug.
I uploaded a test VI with a tree and a couple of the new drag/drop events: << link >>
If you run it and drop item 'c' on item 'a', item 'c' does indeed go bye-bye.
Why?
First, let's examine the built-in LV behavior for tree drag.
When you drop 'c' onto 'a' at edit time, LV does its normal built-in behavior for the tree's drag and drop.
That built-in behavior actually involves two steps:
Step 1: We update the drag source by deleting 'c'.
Step 2: We update the drag target by adding 'c' under 'a'.
And yes, 'source' and 'target' are the same thing: the tree control.
Certain drag/drop user events override built-in LabVIEW drag/drop behaviors.
More specifically:
* If you register for "Drag Source Update" on a drag source, LV will no longer do its built-in behavior for updating the drag source. Instead, LV leaves that entirely up to you.
* If you register for "Drop" on a drag target, LV will no longer do its built-in behavior for updating the target. Instead, LV leaves that entirely up to you.
This sample VI has registered for "Drop", and so at run time step 2 doesn't happen. If you register for the "Drop" event, you have to implement that Drop behavior yourself, in G.
I hope this clarifies things a little bit, and I hope that you will continue working with drag and drop. I know that it's not the easiest feature in the world to use, so any suggestions are appreciated.
[1] A quick note about what you said:
I have found a work-around by writing a routine that calculates which element the mouse is hovering over, but this is very non-direct and a bit of a kludge.
I don't think this is a kludge at all. In fact this is exactly what LabVIEW was doing internally before to determine if you were in droppable spot.
01-03-2006 10:23 AM
@jpeters wrote:
(Sorry for the length of this post.)
Don't be. Those of us who are interested in such things (and I'm positive Jim qualifies) like the long and detailed responeses and we always appreciate getting information from the development team. Keep it up.
01-03-2006 07:32 PM - edited 01-03-2006 07:32 PM
Message Edited by Jim Kring on 01-03-2006 05:36 PM
01-03-2006 07:56 PM
That's OK. Are there any documents or white papers that describe how to use this feature (aside from the examples)? …Is there any documentation that ties all of these pieces together?
Not that I am aware of. I think it is an excellent idea that I will try to produce in the coming weeks.
But the event structure knows that the control is a tree control. Couldn't the tree control inherit the drag/drop event data from the Control class (which is a parent class of Tree), and customize it by adding additional 'source tag' and 'target tag' data?
I don’t think that it can. You can get drags from anywhere. There are a number of cases where it doesn’t make any sense. For example, let’s say that you drag from anywhere else besides the destination tree control – the source tag is meaningless in this case. I don’t think that it would be good practice to expose something in the API that makes sense in only a handful of cases.
Hmmm, but if the tree control could customize the inherited Control.Drop event, then it could add a Boolean output data parameter called "update target?", which would cause it to do its built-in behavior of copying the entire node hierarchy to the target.
I think that this is a good suggestion and one that I seriously considered during development of the feature. I definitely will write this down as a potential addition in the next rev of drag and drop events.
Definitely, this is a great discussion and I know that the tree control is going to become a very powerful tool. It's just going to take us all a while to learn how to use it effectively -- distil the patterns of use and come up with some utilities and best practices to make it easier.
I agree and I hope that everyone continues to try to use it. In time and with your suggestions I hope to make the feature a bit more approachable to everyone. Please continue to post here and file suggestions for utilities and features you would like to see for drag and drop. This includes anything from new utilities or properties to changes in the API that would make programming drag and drop easier.
Jeff Peters
01-03-2006 08:39 PM
01-03-2006 09:03 PM
01-03-2006 10:04 PM
01-03-2006 10:48 PM
01-06-2006 08:25 AM