How to drag windows?

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

Hello Godoters,

As the name of the post itself says, i created a windows in my game and made this code:

Here is my project tree too:
Imgur

This code was in the Windows node, but I removed it, because I needed to put other things, so … I wanted the code to work on the TitleBar node, if not ask for more. :slight_smile:

Then could someone fix my code, please? The only problem is that the archor point is at (0, 0) from the window instead of the position I clicked.

:bust_in_silhouette: Reply From: Pieter-Jan Briers

Having an inside boolean for when the cursor is over the title bar is not the right way to do this. You want to use a proper input event so you can track where the mouse was when the user pressed their mouse.

You want to hook _gui_input on the title bar, and track when the user presses down the mouse on the title bar and when they release it. Store the position of the mouse when they pressed down in a variable, and unset it when the user releases. Then you can determine how the window was moved by the difference between the current mouse position and the position when the window was grabbed.

Example:

extends Control

var dragPoint = null

func _on_Titlebar_gui_input(ev):
    if ev is InputEventMouseButton:
        if ev.button_index == BUTTON_LEFT:
            if ev.pressed:
                # Grab it.
                dragPoint = get_global_mouse_position() - get_position()
            else:
                # Release it.
                dragPoint = null
    
    if ev is InputEventMouseMotion and dragPoint != null:
        set_position(get_global_mouse_position() - dragPoint)

For reference, this is pretty much a reimplementation of the built-in WindowDialog dragging code

Might be a dumb question, but I’ve achieved partial-functionality with this. I’m working in Godot 3.1 and am attempting to be able to click-and-drag the window from the title bar. My tree looks like

Node2D
-|Control
—|Title Bar
-----|Panel
—|[App contents]

I’ve implemented your code almost exactly as-is (providing a different name for the title bar and using [event] instead of [ev]), but functionality should be the same.

Problem is, [Node2D] doesn’t offer a gui_input(), placing gui_input() on [Control] or [Title Bar] does nothing, and placing gui_input() on [Panel] allows me to move the contents of the window, uh… inside the window. Without the window moving. Placing a Panel as a direct child of [Node2D] before [Control] in the heirarchy and hooking a gui_input() on that up to the script provided does nothing.

I suspect it’s a hierarchy problem. That’d explain why the current [Panel], being the object “closest” to the user does it while nothing else does. However, that doesn’t explain for me how that moves everything within the window (including the entirety of [App contents]), but not the window itself.

I don’t know if anybody’s still tracking this question and it’s probably a dunderheaded overlook on my part, but any assistance would be appreciated.

occultnix | 2020-01-26 21:59