Only trigger a button event on tap, not after drag

Here’s the problem:

I have digital info panel where I have a bunch of interactable elements such as videos (like here) and image galleries. Because I have to rely on the gui_input signal, I can’t seem to find a way to stop button-pressed and button-released events after the user performed a dragging gesture, like in the video. Ideally I’d only like to start/stop the video, or open up a bigger carousel, if the user did a tap (press-release within a very small radius) and not do it if the user dragged the page up or down initiating the action inside the TextureRect or VideoStreamPlayer or whatever is there.

The cancelled property on the button-released event is false, which makes sense because this isn’t an explicit click/tap event, but I can’t find any other sensible way of dealing with this. Any pointers?

You need to implement a gating check around stop/start of your video, and only stop/start playback if it passes your gating check. You have described your gating check here.

  1. “press-release within a very small radius” - you need to store the press location and the release location. This should be very simple to implement within the gui_input for whatever is controlling the stop/start.
  2. “and not do it if the user dragged the page up or down initiating the action…” - you would need to track whether or not a drag action occurred. This should be simple to implement as a signal in whatever is responsible for scrolling up or down.

In pseudo-code, this is what I envision may work:

var press_position: Vector2 = Vector2.ZERO
var dragged: bool = false

func _gui_input(event):
    if event.is_input_action("pressed"):
        press_position = event.position
        dragged = false # reset
        # connect on_drag to the drag signal so you can see if a drag occurred between press/release.
    else if event.is_input_action("released"):
        if should_toggle_playback(event.position):
            toggle_playback()
        # disconnect on_drag from the drag signal, because you don't care while not in between press/release.


func on_drag() -> void:
    dragged = true


func should_toggle_playback(release_position: Vector2) -> bool:
    var difference = release_position - press_position
    var is_within_radius: bool = difference <= THRESHOLD # you can implement this check however you want.
    return not dragged and is_within_radius

I had already thought of that and I was hoping for something easier I hadn’t spotted but if that’s the only solution, that’ll do.

Now I’m stuck trying to figure out what control I’m on. I may have more than one interactable element, of course.