Is it possible to connect a member function dynamically?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By wombatTurkey
:warning: Old Version Published before Godot 3 was released.

Hey everyone!

I am creating some inventory boxes which will allow the user to drag and drop items between them.

The problem is since set_drag_preview only works when you set it when it’s inside the get_drag_data function.

Thus, you cannot do something like this:

var TestButton = get_node('Button 2')
var cpb = ColorPickerButton.new()
cpb.set_size(Vector2(150, 150))
TestButton.set_drag_preview(cpb)

You have to actually add a gdscript inside the Button 2 node itself, and use this:

func get_drag_data(pos):
# Use another colorpicker as drag preview
var cpb = ColorPickerButton.new()
cpb.set_size(Vector2(150, 150))
set_drag_preview(cpb)

The problem is, I would need to create a seperate gdscript file for each inventory box I create. Which would be unintuitive I think.

Infact, when doing set_drag_preview dynamically by using get_node, it actually starts the dragging process without even starting the drag… It’s weird, but here is the example:

Create a simple button on your scene, then add this code inside _ready():

var TestButton = get_node('Button')
var cpb = ColorPickerButton.new()
cpb.set_size(Vector2(150, 150))
TestButton.set_drag_preview(cpb)

Now when the app starts, the drag preview starts automatically without even dragging, very weird. I’m obviously new to Godot so I’m probably screwing up somewhere, hope you guys can help thanks!

Can you explain a little more why you would need a different gdscript file for each inventory box? That sounds a little suspicious.

Warlaan | 2016-05-16 18:12

Hey Warlaan

Well, because if you do TestButton.set_drag_preview(cpb) it doesn’t work (well, it does, but it automatically starts showing the drag preview when your not even dragging, it’s weird) – You have to set this inside the func get_drag_data when extending the node ( a new gdscript ). I don’t want to add a new gdscript for each different node I want to try to add the set_drag_preview in code by using get_node. For example, take a look at the drag and drop example, they are using a separate gdscript for each individual node.

I’m kind of lost so it’s hard to explain

wombatTurkey | 2016-05-16 18:18

It seems like the name set_drag_preview is just not chosen very well. It looks like that method should be called show_drag_preview.
Looking at the drag-and-drop-example (the one with the nine boxes in different colors) I see nine nodes with attached scripts, but they all have the same file attached. Looking in the inspector at the very bottom it says “Script: drag_drop_script.gd” for each one of them.

Warlaan | 2016-05-16 18:36

Oh, so you can attach 1 gd script file to multiple nodes then? So technically it’s only 1 script, but multiple nodes taking advantage of it? Awww… I’m an idiot… I thought it was multiple scripts forEach node

wombatTurkey | 2016-05-16 18:39

:bust_in_silhouette: Reply From: Warlaan

I haven’t worked with the drag-and-drop system yet and I am not sure if I understand the problem correctly, but I think what you are looking for is this:

Using the call()-method or funcrefs you can store a method either by name or as a function reference. That way you can write a get_drag_data()-method that doesn’t do anything except call a method stored in a member variable. That way you can change the member variable in order to change the get_drag_data-behavior.