Unfold tree items on hover while drag-n-dropping

Co-authored-by: suddjian
This commit is contained in:
Michael Alexsander 2025-09-24 22:34:10 -03:00
parent 1f7630f1bf
commit 26745b4b87
No known key found for this signature in database
GPG key ID: A9C91EE110F4EABA
11 changed files with 82 additions and 4 deletions

View file

@ -139,7 +139,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) {
@ -4278,6 +4278,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) {
@ -4321,6 +4324,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;
@ -6440,13 +6456,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();
@ -6567,6 +6598,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);
@ -6589,6 +6623,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");
@ -6687,6 +6722,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);
@ -6744,6 +6781,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));