Android - How to prevent Tree item selection when screen dragging?

Godot Version



I am working on an Android app that includes a Tree that is being used as a selection menu. The default folding arrows for a Tree are inconvenient to use on mobile, so I opted instead to collapse/uncollapse the items by clicking the items themselves.

func _on_tree_item_mouse_selected(_position: Vector2, _mouse_button_index: int):
    var item = $Tree.get_selected()
    item.collapsed = not item.collapsed

Unfortunately, this function is called even when the item selection is due to the user touching the screen to screen drag through the menu. Here is an example of the issue, run in an Android emulator.

Is there an easy way to address this? My current thought is to keep track of InputEventScreeenTouch and InputEventScreenDrag events after item selection to determine if there was any dragging between touch and release, but that all is a bit manual. If there is a built-in solution to this problem, I would prefer to use that.

You’ll need to manually take care of that. Example:

extends Tree

var scroll_start = -INF
var scrolled = false

func _ready() -> void:
	var root = create_item()
	root.set_text(0, "root")

var d = 0

func generate_branch(root):
	for i in randi_range(3, 10):
		var c = create_item(root)
		c.set_text(0, "child %s" % i)
		if d < 3 and randf() > 0.75:
			d += 1

func _gui_input(event: InputEvent) -> void:
	if event is InputEventScreenTouch or event is InputEventMouseButton:
		if event.is_pressed():
			scrolled = false
			scroll_start = get_scroll().y
			if not scrolled:
				var selected = get_selected()
				if selected:
					selected.set_deferred("collapsed", not selected.collapsed)

	if not scrolled and (event is InputEventMouseMotion or event is InputEventScreenDrag):
		var current_scroll = get_scroll().y
		if abs(scroll_start - current_scroll) > SCROLL_TRIGGER_DIFF:
			scrolled = true