Mouse Drag Control

Description

As simple as attaching this script to a node and update the settings :

Usage

Once attached to a node, connect the signals in order to be notified when a drag motion is done on a specific Control.

Signals

  • on_drag_press : Triggered when a drag is initiated. Provides the initial position of the mouse.
  • on_drag_release : Triggered when a drag is finished. Provides the final position.
  • on_drag : Triggered each time the mouse is dragged. Provides the starting and ending position of the mouse.

Variables

  • drag_button : Specifies which button it capable of dragging
  • inspected : The control on which the dragging motion has to be detected

Note

The script must be attached to a Node . If needed, adapt the extends statement.

Warning

The inspected control node must be ready/initialized before the one hosting this script.

    Main code

    extends Node
    
    # Triggered when dragging is initiated
    signal on_drag_press(position : Vector2)
    # Triggered when dragging is finished
    signal on_drag_release(position : Vector2)
    # Triggered while dragging
    signal on_drag(previous : Vector2, next : Vector2)
    
    # Which button is used to drag
    @export var drag_button : MouseButton
    
    # Inspected control
    @export var inspected : Control
    
    @onready var is_dragging : bool = false
    @onready var previous_position : Vector2
    
    func _ready() -> void:
    	inspected.gui_input.connect(_drag_callback)
    
    func _drag_callback(event : InputEvent) -> void:
    	if event is InputEventMouseMotion:
    		if is_dragging:
    			var e : InputEventMouse = event as InputEventMouse
    			on_drag.emit(previous_position, e.position)
    			previous_position = e.position
    	elif event is InputEventMouseButton:
    		var e : InputEventMouseButton = event as InputEventMouseButton
    		if e.button_index == drag_button:
    			if e.pressed and not is_dragging:
    				previous_position = e.position
    				on_drag_press.emit(previous_position)
    			elif is_dragging and not e.pressed:
    				on_drag_release.emit(e.position)
    		is_dragging = e.pressed
    

    Comments