Search code examples
godotgdscript

Drag & Drop (swap) 3 texture buttons in a Margin Container->VBox


Following along a great tutorial, code is replicated yet does not function as shown. No new texture appears to be created when I try to drag the texture button. Only difference is the tutorial uses a TextureRect, while I'm using a TextureButton.

extends TextureButton


func get_drag_data(position: Vector2):
    var vControl = Control.new()
    var vData    = {}
    var vTexture = TextureRect.new()
    
    vTexture.expand    = true
    vTexture.texture   = texture_disabled
    vTexture.rect_size = Vector2(320, 400)
    
    vControl.add_child(vTexture)
    vTexture.rect_position = -0.5 * vTexture.rect_size
    
    set_drag_preview(vTexture)
    
    return vData

Hierarchy

Code above is attached to Party_1. texture_disabled does have a texture set.


Solution

  • It would work if you had the code in get_drag_data looking like this:

    func get_drag_data(_position: Vector2):
        var vTexture = TextureRect.new()
        vTexture.expand    = true
        vTexture.texture   = texture_disabled
        vTexture.rect_size = Vector2(320, 400)
        set_drag_preview(vTexture)
        return {}
    

    However, that would place the TextureRect top-left corner at the cursor position.

    You want to offset the position of the TextureRect so it is centered at the cursor position. To do that, you create another Control, add the TextureRect as a child to it… And pass the TextureRect anyway? No, that does not work, you need to pass the new Control:

    func get_drag_data(_position: Vector2):
        var vTexture = TextureRect.new()
        vTexture.expand    = true
        vTexture.texture   = texture_disabled
        vTexture.rect_size = Vector2(320, 400)
    
        var vControl = Control.new()
        vControl.add_child(vTexture)
        vTexture.rect_position = -0.5 * vTexture.rect_size
    
        set_drag_preview(vControl)
        return {}
    

    Please notice I'm giving vControl to set_drag_preview, not vTexture.


    You cannot give to set_drag_preview a Control that has a parent. In fact, if you tried you would get an error in the Output console saying:

    _gui_set_drag_preview: Condition "p_control->get_parent() != nullptr" is true.
    

    Or

    _gui_set_drag_preview: Condition "p_control->is_inside_tree()" is true.