Hello, today I have two questions:
1. How can I determine that the dragged tree view item has to be moved before the dropped item (as a sibling item) and NOT below the dropped item (as a child item)? I want to move an item between two items within the same parent using the standard drag&drop move operation.
2. In the old ObjectDCL the DragDropFromControl event returned -1 as uDropPoint argument in the case the user has dropped the dragged item into empty space below the last item. I used this for the case a dragged child item shall be moved to the top level (root; shall become a parent item). How can I move a child item to the root?
It is very important for me.
Fred
Hi, I've attached a video for better understanding. In this form the user can add favorite LISP Tools and commands for fast implementation. He can also group them into folders. In this case you cannote see folder because the user hasn't created folders yet. Macros and LISP Tools cannot be child of other Macros and LISP Tools. But the dragndrop peration can be used for re-arranging them.
Fred
From looking at the code, it looks like the DragDropFromControl event should pass an item key of zero when dropping in an empty space. I could easily change that to -1 if you prefer. As for building in logic to decide whether to add as a child or a sibling, I'm not sure how that could be done programmatically, but I'm open to ideas.
Owen, zero would be ok, too. But now it is not possible to get any value in this case. As you can see in the video a stop sign is shown when moving the mouse over empty space - that's why nothing will be returned in uDropItem.
For the other thing I don't have any idea, too - maybe it can controlled by a returning key of DragBegin event or DragOver event... But it's only a thought....
Fred
The return value from your OnDragOverFromControl handler function would determine whether a drop is allowed in the blank area. I did a quick test and was able to drop into empty space in the tree sample.
The problem with returning a key for DragBegin or DragOver is that it would need to be designed to still allow the current return values somehow. It would be possible to change the insertion type depending on where on the tree item the drop occurs. For example, it could insert a sibling key if the drop occurs to the left of the icon, or a child otherwise. Unfortunately that would not solve your problem because it would not allow programmatic control. I think the only solution is for you to handle he DragOver and Drop events in your own code.
Quote from: owenwengerd on March 14, 2010, 04:00:31 PM
The return value from your OnDragOverFromControl handler function would determine whether a drop is allowed in the blank area. I did a quick test and was able to drop into empty space in the tree sample.
I'm wondering, how did you do that. I've changed my code and the OnDragOver event passes an entity for uDropItem argument:
OnDragOverFromControl: <Objektname: 0>
Fred
Quote from: owenwengerd on March 14, 2010, 04:00:31 PM
I think the only solution is for you to handle he DragOver and Drop events in your own code.
Owen, I'd like to do that. But unfortunately, the dragged item will be deleted after DragDropFromControl event was left.
OnDragBegin = active; returns 2
OnDragOver = active; returns 2
OnDragDrop = active, does nothing
After OnDragDrop was finished, the dragged item will get removed. I thing it should not get deleted when OnDragDrop is active and defined. But maybe I'm wrong...
Fred
I will see if I can change the "null" entity name to NIL, otherwise it isn't very easy to test for that value.
Regarding copy vs. move, I don't understand the problem. To copy instead of move, just return 1 from OnDragOver.
Quote from: owenwengerd on March 15, 2010, 08:29:30 AM
To copy instead of move, just return 1 from OnDragOver.
I don't want to
copy, I want to
move the item. I thought when OnDragDropFromControl is active the item will be moved and not deleted.
I've attached a small sample. The items and subitems shall be re-arranged by the move method. You've told me to do it within OnDragDropFromControl event. I want to do that but although the event is active and defined the dragged item will be removed.
If I deactivate DragDropFromControl event then the dragged item will be moved but I don't have any chance to avoid that an item will get a child of an item (I want to insert it between two items if the dropitem is not a folder).
Fred
Quote from: Fred Tomke on March 15, 2010, 09:08:23 AM
I thought when OnDragDropFromControl is active the item will be moved and not deleted.
I don't think it would work to change what happens in the source item based on whether or not an event handler exists for the destination. In theory the only communication between destination and source is the returned integer that determines whether it was a move or a copy. Given that limitation, and the fact that a drag operation can originate from the same control or from a different control, it seems like a risky attempt to guess at what should happen in the source control.
I will have a look at your sample later today to see if I can understand the problem.
I just looked at your sample. I expected your OnDragnDropFromControl to insert the source item as a sibling of the target item. What exactly did not work as you expected?
I only wanted to show you that the dragged item will be removed after dropping it. And that's what I don't want. Of course I could move the item by myself but it would deleted by OpenDCL after finishing OnDragDropFromControl event.
Fred
Sorry, I am still confused. Let's consider the two possible operations here: a move or a copy. A move operation causes the source item to be deleted, a copy operation causes the source item to remain undisturbed. So which of these two possible operations do you want?
Do I understand it right that automatic "moving" (when all DragnDrop events are turned off) does not mean that an item will be actually moved, but deleted from the old parent and inserted at the drop point anew?
Depending on my problem let me ask it this way: does it make sense that OpenDCL removes the dragged item after finishing OnDragDropFromControl although the active OnDragDropFromControl event wants to control it by itself (and not by OpenDCL)?
Please, have a look at the project I attached in this post or look at the new video. Maybe it explains my problem a bit better.
Fred
It is correct to say that drag and drop does not literally move anything. "Move" is just a way of signalling to the caller that the source should be deleted after the operatio is completed. Perhaps it will help if you see the logic of a drag and drop operation from the perspective of the source object:
1) In the LeftButtonDown handler of e.g. the tree control, call DoDragDrop(<source item>). This function does not return until the operation is completed or cancelled.
2) If the return value is <MOVE>, delete the source item.
Note that the source does not know or care where the drop occurred. In fact, there is some special code that keeps track of any items that are inserted in the same control during the drop so that the correct source item is deleted in the event the drop was a <MOVE>. The important point is that by the time the source object reacts to the operation, the drop is already complete.
I tested your latest sample and it works as expected even though you are deleting the source item from within the drop handler. I'm not sure why you get different results.
Quote from: owenwengerd on March 15, 2010, 12:47:27 PM
I tested your latest sample and it works as expected even though you are deleting the source item from within the drop handler. I'm not sure why you get different results.
Yes, you are right: I've justed this sample on AutoCAD Map 2010 x64 on Win7 x64. There is a significant difference to AutoCAD Civil 3D 2009 on WinXP x86 and Map 2010 x64 on Vista x64: Only on Windows 7 x64 the dragged item will be kept. I would backtrack this topic if the way it works on Win7 x64 it also works on Windows XP and Windows Vista. ;)
Other question towards this: you wrote
Quote from: owenwengerd on March 15, 2010, 12:12:22 PM
2) If the return value is <MOVE>, delete the source item.
Would it be possible to extend the if condition for the case the event handler DragDropFromControl ist active?
= 2) If the return value is <MOVE> and the eventhandler name <> "", then delete the source item.
Just a thought.
Fred
The AddSibling function should fail when it is called after the target key has already been deleted, but for some reason it works anyway in AutoCAD 2010. I tested in AutoCAD 2004, and the AddSibling function fails there as I would expect. I was going to suggest simply removing the calls to DeleteItem, but this presents a different problem: AddSibling fails in that case because the item key would be a duplicate.
To address the problem, I have made some changes for the next build so that DeleteItem within the drop handler works as you expected, and the source item correctly recognizes that it has already been deleted. I think this will resolve the problem and allow your latest sample to work the way you want.
Quote from: Fred Tomke on March 15, 2010, 04:41:49 PM
Would it be possible to extend the if condition for the case the event handler DragDropFromControl ist active?
= 2) If the return value is <MOVE> and the eventhandler name <> "", then delete the source item.
In addition to the problem that I explained in the previous post, the source object would have no way of knowing where it was dropped, and so it would have no independent way of determining whether the event handler existed at the drop point. In any case, I thinkthe problem is now resolved.
Quote from: owenwengerd on March 15, 2010, 07:08:02 PM
The AddSibling function should fail when it is called after the target key has already been deleted.
Hm, I cannot see where I should have deleted the target item. I my code I have deleted the dragged item. Of course, AddSibling must fail if the target item was deleted before.
However, thanks Owen for your patience. I am looking forward to test the new release.
Fred
I should have said "source item" instead of "target key".
Hi Owen, Hi Fred,
I've followed your dialog here and have gone through the code that has been posted because I am also trying to build a tree where I can re-order, or, 'move' items around without nesting them. Seeing as this thread is quite old, I'm wondering if there is some 'new' way to achieve this behaviour in release 7?
Otherwise, the problem that I am facing right now is that I have a tree of items where the parents have keys but the children do not. The DropPoint variable of OnDragnDropFromControl is useful when the item has a key, but, when it doesn't, instead of getting the item's handle DropPoint becomes an entity name and I'm not sure how to use that information to do anything useful like add a sibling. Is this a bug? I was expecting a handle if the tree item doesn't have a key.
Thanks for taking a look at this entry.
The "entity name" is not an entity name -- it is the item handle.