Merge pull request #110904 from YeldhamDev/tree_drag_unfolding

Unfold tree items on hover while drag-n-dropping
This commit is contained in:
Thaddeus Crews 2025-10-21 15:11:01 -05:00
commit ed4f4d275e
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
11 changed files with 82 additions and 4 deletions

View file

@ -140,7 +140,7 @@ void TreeItem::_change_tree(Tree *p_tree) {
}
if (tree->drop_mode_over == this) {
tree->drop_mode_over = nullptr;
tree->_reset_drop_mode_over();
}
if (tree->single_select_defer == this) {
@ -4266,6 +4266,9 @@ void Tree::_determine_hovered_item() {
if (drop_mode_flags) {
if (it != drop_mode_over) {
drop_mode_over = it;
if (enable_drag_unfolding) {
dropping_unfold_timer->start(theme_cache.dragging_unfold_wait_msec * 0.001);
}
queue_redraw();
}
if (it && section != drop_mode_section) {
@ -4309,6 +4312,19 @@ void Tree::_determine_hovered_item() {
}
}
void Tree::_on_dropping_unfold_timer_timeout() {
if (enable_drag_unfolding && drop_mode_over && drop_mode_section == 0) {
drop_mode_over->set_collapsed(false);
}
}
void Tree::_reset_drop_mode_over() {
drop_mode_over = nullptr;
if (!dropping_unfold_timer->is_stopped()) {
dropping_unfold_timer->stop();
}
}
void Tree::_queue_update_hovered_item() {
if (hovered_update_queued) {
return;
@ -6465,13 +6481,28 @@ bool Tree::is_recursive_folding_enabled() const {
return enable_recursive_folding;
}
void Tree::set_enable_drag_unfolding(bool p_enable) {
if (enable_drag_unfolding == p_enable) {
return;
}
enable_drag_unfolding = p_enable;
if (!enable_drag_unfolding && !dropping_unfold_timer->is_stopped()) {
dropping_unfold_timer->stop();
}
}
bool Tree::is_drag_unfolding_enabled() const {
return enable_drag_unfolding;
}
void Tree::set_drop_mode_flags(int p_flags) {
if (drop_mode_flags == p_flags) {
return;
}
drop_mode_flags = p_flags;
if (drop_mode_flags == 0) {
drop_mode_over = nullptr;
_reset_drop_mode_over();
}
queue_redraw();
@ -6595,6 +6626,9 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enable_recursive_folding", "enable"), &Tree::set_enable_recursive_folding);
ClassDB::bind_method(D_METHOD("is_recursive_folding_enabled"), &Tree::is_recursive_folding_enabled);
ClassDB::bind_method(D_METHOD("set_enable_drag_unfolding", "enable"), &Tree::set_enable_drag_unfolding);
ClassDB::bind_method(D_METHOD("is_drag_unfolding_enabled"), &Tree::is_drag_unfolding_enabled);
ClassDB::bind_method(D_METHOD("set_drop_mode_flags", "flags"), &Tree::set_drop_mode_flags);
ClassDB::bind_method(D_METHOD("get_drop_mode_flags"), &Tree::get_drop_mode_flags);
@ -6617,6 +6651,7 @@ void Tree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_recursive_folding"), "set_enable_recursive_folding", "is_recursive_folding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_drag_unfolding"), "set_enable_drag_unfolding", "is_drag_unfolding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden");
ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags");
ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode");
@ -6715,6 +6750,8 @@ void Tree::_bind_methods() {
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Tree, parent_hl_line_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Tree, children_hl_line_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Tree, dragging_unfold_wait_msec);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Tree, scroll_border);
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Tree, scroll_speed);
@ -6772,6 +6809,11 @@ Tree::Tree() {
range_click_timer->connect("timeout", callable_mp(this, &Tree::_range_click_timeout));
add_child(range_click_timer, false, INTERNAL_MODE_FRONT);
dropping_unfold_timer = memnew(Timer);
dropping_unfold_timer->set_one_shot(true);
dropping_unfold_timer->connect("timeout", callable_mp(this, &Tree::_on_dropping_unfold_timer_timeout));
add_child(dropping_unfold_timer);
h_scroll->connect(SceneStringName(value_changed), callable_mp(this, &Tree::_scroll_moved));
v_scroll->connect(SceneStringName(value_changed), callable_mp(this, &Tree::_scroll_moved));
line_editor->connect(SceneStringName(text_submitted), callable_mp(this, &Tree::_line_editor_submit));