0
\$\begingroup\$

Is there a way to collapse/uncollapse a Tree (Control) in Godot 4 by clicking on the TreeItem instead of the folding arrow?

I mean, I click on an item, gets selected and the subitems get uncollapsed. Click again the same item and the subitems get collapsed.

I've managed to achieve a similar behaviour by connecting the item_selected() signal from the Tree, but it just doesn't work flawlessly:

  • Some mouse clicks are missed if you click quick (less quick than a double-click though).
  • The selected item must be deselected because the signal won't trigger again if the item is already selected, and I'd like the item to be shown as selected.

Here's the code:

@onready var characters_tree: Tree = $MarginContainer/Tree

func _on_tree_item_selected() -> void:
    var item := characters_tree.get_selected()
    item.collapsed = not item.collapsed
    item.deselect(0)
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Connect to the Tree's item_mouse_selected signal, which is emitted when an item is selected with a mouse button. It is even emitted again if the item is already selected, so you don't have to deselect it in your code.

func _on_tree_item_mouse_selected(position, mouse_button_index):
    var item = characters_tree.get_selected()
    item.collapsed = not item.collapsed

However, if you click twice fast enough to be considered a double-click, this signal is not emitted for the second click. Instead the item_activated signal is emitted. You mentioned that your quick clicks were less quick than a double-click, but double-clicks can be deceptively long and still register as one. To account for this, you should also connect to the item_activated signal.

func _on_tree_item_activated():
    var item = characters_tree.get_selected()
    item.collapsed = not item.collapsed
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .