LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Tree Control Drag & Drop in LabVIEW 8

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?

0 Kudos
Message 1 of 20
(11,579 Views)

(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.

Message 2 of 20
(11,516 Views)

@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.


___________________
Try to take over the world!
Message 3 of 20
(11,487 Views)
jpeters: Thanks for the detailed response.  I guess that tst knows me well, because I do love a long and detailed explanation.  And certainly, I like to hear about LabVIEW features from the developers at NI -- the raw and unfiltered facts that you just don't find in the manuals Smiley Happy

> Using drag and drop events is harder than it used to be. I apolgize for that.

That's OK.  Are there any documents or white papers that describe how to use this feature (aside from the examples)?  There are several components of this feature -- (1) the control "Start Drag" method, (2) the multiple control Drag and Drop events (and related event data), and (3) the "Get Drag Drop Data" function -- and they are all very disconnected.  Is there any documentation that ties all of these pieces together?

> In 8.0, drag and drop is much more general [...snip...]. 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*.

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?

> To get the destination tag, use the "Point to Row Column" method on the tree control.

Ah... the "Point to Row Column" method was the missing link (if I had seen it, I might not have even posted this question).  This feature has been needed for quite some time and will make our lives so much easier.

> [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.

It appears to me that one doesn't have access to all of the necessary control properties to deterministically perform the calculation (in 7.x, at least):  You have to use "Master Rectangle" which is a private (scripting) method, and also you have to get the active cell height, to determine the pixel height of the tree elements.  Also, you have to check whether the column header is visible and conditionally add this as an offset to the start of the row positions.  And, you have to add a pixel border offset which can change depending on whether you are using 2D, 3D, or System (Dialog) controls.  This is all way too much effort for something so simple; but regardless, thanks for adding the "Point to Row Column" method -- problem solved Smiley Wink

> * 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.

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 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.

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.

Thanks and Regards,

Message Edited by Jim Kring on 01-03-2006 05:36 PM

0 Kudos
Message 4 of 20
(11,453 Views)

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

0 Kudos
Message 5 of 20
(11,435 Views)
> > 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.

Yes, I agree that 'source tag' doesn't make sense for a Tree Drop event, since the source might not be another node of a tree control (it could be any other control).  However, 'target tag' is still applicable for the Tree Drop event, as is 'source tag' for the Tree Drag event.  So, rather than forcing the programmer to call "Point to Row Column" to obtain this information, it could be made available via event data.  Actually, couldn't all of the "Point To Row Column" method outputs (In Bounds?, Tag, Column, In Symbol?) be added to the event data of Tree Drag and Tree Drop?
0 Kudos
Message 6 of 20
(11,429 Views)
Yes, I agree that 'source tag' doesn't make sense for a Tree Drop event, since the source might not be another node of a tree control (it could be any other control).  However, 'target tag' is still applicable for the Tree Drop event, as is 'source tag' for the Tree Drag event.  So, rather than forcing the programmer to call "Point to Row Column" to obtain this information, it could be made available via event data.  Actually, couldn't all of the "Point To Row Column" method outputs (In Bounds?, Tag, Column, In Symbol?) be added to the event data of Tree Drag and Tree Drop?
 
Ah, I see what you mean.  There are still reasons that we cannot do it for some of the drag source side events (like Drag Source Update and Drag Ended), specifically because we don't know necessarily what the user dragged.  They may have started the Drag with a click of a button, not on any tag at all using the Start Drag method.  That said, we could add it to Drag Starting? or Drag Starting with good success.
 
For the drop event there are also reasons why we can't do this currently too, mainly due to implementation; not that wecouldn't change it in the future. Basically, I don't think that we message the tree control in a way that we know what the destination is. 
 
I think that this kind of information makes a lot more sense if the "Drop" event was more like other filter events.  That is, if the user could "redirect" the drop by writing the destination tag on the right hand side of the event structure.  Of course, currently the Drop event is meant as a replacement to built in behavior currently, but if we added the Boolean parameter that you alluded to before (Update Control) then I think that this would be useful to people.  My guess is that reimplementing the insertion of nodes, is a non-trivial task, and this would help people big-time.
 
 
Jeff P
0 Kudos
Message 7 of 20
(11,424 Views)
Hey Jim,
 
If you're looking for functionality like the Point to Row-Column method in LabVIEW 7.x, this method was actually implemented as a VI that shipped with LabVIEW.  It's in one of the LLBs in vi.lib\tree...check it out.  I actually had to use this VI in the VI Analyzer 1.0 because of the glyph-clicking functionality I implemented...thankfully we were able to switch to the more robust method in LabVIEW 8.0, although I never had any problems with the VI-based Point to Row-Column in LabVIEW 7.x.
 
Darren N.
 
P.S. - The VI still exists in LabVIEW 8.0, although I think somebody replaced all of its guts with a simple call to the new method.  If you look at the VI in LabVIEW 7.x, you'll see all sorts of fun pixel math...that is, if it's not password-protected.  🙂
Message 8 of 20
(11,423 Views)
Darren: Thanks for the pointer to these vi.lib/tree VIs.  I took a look at "Point to Row-Col.vi" in 7.1 and it was password-protected -- but that's OK, I've already had a good share of fun pixel math in writing an equivalent VI Smiley Happy
0 Kudos
Message 9 of 20
(11,407 Views)
Jim wrote: Ah... the "Point to Row Column" method was the missing link (if I had seen it, I might not have even posted this question).
 
I, for one, am glad you posted Jim - thanks mate!




Copyright © 2004-2023 Christopher G. Relf. Some Rights Reserved. This posting is licensed under a Creative Commons Attribution 2.5 License.
Message 10 of 20
(11,342 Views)