Drag & Drop issue

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Seli

Hello Godot community,

I started working with the Drag&Drop built in functionality in Godot.
I got familiarized with

get_drag_data()
can_drop_data()
drop_data()

My question is, is there an event for dropping data elsewhere (I mean by elsewhere, in a zone where the drop_data is not expected), once it’s dragged ?

Here is my issue:
I have objects which can exist in 2 containers, these objects implement the drag code:

func get_drag_data(pos):
   ## Preview code here ##
   self.hide()
   return self

I hide the object to give this impression that we picked it up and it’s being dragged

The containers (receivers) implement the drop code:

func can_drop_data(pos, data):
    return true

func drop_data(pos, data):
	data.get_parent().remove_child(data)
	data.show()
	add_child(data)

Once dropped, I remove it from the parent, I render it and I add it to the target.

This works perfectly, the only problem is when I drop it elsewhere, I lose the drop event and my object stays in a hidden status in the source.
I would like to show() it back if the drop happens in a zone where it’s not expected.

Thank you for your help.

I didn’t find anything in Godot documentation, any ideas ?

Seli | 2019-05-24 01:26

Were you able to solve this as per the answer below? Could do with an example in that case. Thanks!

utopiansocialist | 2020-07-03 20:28

:bust_in_silhouette: Reply From: JustinSJ

I solved this issue in C# by having a static CurrentDrag object and calling Show() if it not null and set it as null whenever a mouse release is triggered. A similar method should work for you on GDScript!

:bust_in_silhouette: Reply From: Pavel 1

I had the exact same problem: when I dropped the object outside my two containers it would stay hidden because the drop event was missing. My solution was the following:

Create a 3rd control container as a root node, set both of your containers as child nodes. In the end you should have 3 containers. Inside the root node container use the following script:

#Set this to true otherwise drop_data(pos,data) below will not process data:
func can_drop_data(position, data):
	return true

# Your root control node can now detect your dropped data and 
# it will provide the drop_data functionality
# that was missing. It will show your object again.
# The position will also be reset automatically to the position before the
# drag event. 
func drop_data(position, data):
	data.show()
	

My two child nodes are still able to capture items I place inside them, once I drop the items outside the child nodes, the position will reset and the object will still be visible.

In Godot 4 is
_get_drag_data(at_position)

luislodosm | 2022-09-25 19:09