Skip to content

Commit ed4f4d2

Browse files
committed
Merge pull request godotengine#110904 from YeldhamDev/tree_drag_unfolding
Unfold tree items on hover while drag-n-dropping
2 parents e36dfb0 + 26745b4 commit ed4f4d2

File tree

11 files changed

+82
-4
lines changed

11 files changed

+82
-4
lines changed

doc/classes/EditorSettings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,9 @@
872872
<member name="interface/editor/dock_tab_style" type="int" setter="" getter="">
873873
Tab style of editor docks.
874874
</member>
875+
<member name="interface/editor/dragging_hover_wait_seconds" type="float" setter="" getter="">
876+
During a drag-and-drop, this is how long to wait over a UI element before it triggers a reaction (e.g. a section unfolds to show nested items).
877+
</member>
875878
<member name="interface/editor/editor_language" type="String" setter="" getter="">
876879
The language to use for the editor interface.
877880
Translations are provided by the community. If you spot a mistake, [url=https://contributing.godotengine.org/en/latest/documentation/translation/index.html]contribute to editor translations on Weblate![/url]

doc/classes/Tree.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@
370370
The drop mode as an OR combination of flags. See [enum DropModeFlags] constants. Once dropping is done, reverts to [constant DROP_MODE_DISABLED]. Setting this during [method Control._can_drop_data] is recommended.
371371
This controls the drop sections, i.e. the decision and drawing of possible drop locations based on the mouse position.
372372
</member>
373+
<member name="enable_drag_unfolding" type="bool" setter="set_enable_drag_unfolding" getter="is_drag_unfolding_enabled" default="true">
374+
If [code]true[/code], tree items will unfold when hovered over during a drag-and-drop. The delay for when this happens is dictated by [theme_item dragging_unfold_wait_msec].
375+
</member>
373376
<member name="enable_recursive_folding" type="bool" setter="set_enable_recursive_folding" getter="is_recursive_folding_enabled" default="true">
374377
If [code]true[/code], recursive folding is enabled for this [Tree]. Holding down [kbd]Shift[/kbd] while clicking the fold arrow or using [code]ui_right[/code]/[code]ui_left[/code] shortcuts collapses or uncollapses the [TreeItem] and all its descendants.
375378
</member>
@@ -561,6 +564,9 @@
561564
<theme_item name="children_hl_line_width" data_type="constant" type="int" default="1">
562565
The width of the relationship lines between the selected [TreeItem] and its children.
563566
</theme_item>
567+
<theme_item name="dragging_unfold_wait_msec" data_type="constant" type="int" default="500">
568+
During a drag-and-drop, this is how many milliseconds to wait over a section before the section unfolds.
569+
</theme_item>
564570
<theme_item name="draw_guides" data_type="constant" type="int" default="1">
565571
Draws the guidelines if not zero, this acts as a boolean. The guideline is a horizontal line drawn at the bottom of each item.
566572
</theme_item>

editor/docks/scene_tree_dock.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1713,6 +1713,9 @@ void SceneTreeDock::_notification(int p_what) {
17131713
scene_tree->set_hide_filtered_out_parents(EDITOR_GET("docks/scene_tree/hide_filtered_out_parents"), false);
17141714
scene_tree->set_accessibility_warnings(EDITOR_GET("docks/scene_tree/accessibility_warnings"), false);
17151715
}
1716+
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor")) {
1717+
inspect_hovered_node_delay->set_wait_time(EDITOR_GET("interface/editor/dragging_hover_wait_seconds"));
1718+
}
17161719
} break;
17171720

17181721
case NOTIFICATION_THEME_CHANGED: {
@@ -4861,7 +4864,6 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
48614864

48624865
inspect_hovered_node_delay = memnew(Timer);
48634866
inspect_hovered_node_delay->connect("timeout", callable_mp(this, &SceneTreeDock::_inspect_hovered_node));
4864-
inspect_hovered_node_delay->set_wait_time(.5);
48654867
inspect_hovered_node_delay->set_one_shot(true);
48664868
add_child(inspect_hovered_node_delay);
48674869

editor/editor_node.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,10 @@ void EditorNode::_notification(int p_what) {
10161016
recent_scenes->reset_size();
10171017
}
10181018

1019+
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor")) {
1020+
theme->set_constant("dragging_unfold_wait_msec", "Tree", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000);
1021+
}
1022+
10191023
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/dock_tab_style")) {
10201024
editor_dock_manager->update_tab_styles();
10211025
}

editor/inspector/editor_inspector.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,12 @@ void EditorInspectorSection::_notification(int p_what) {
21382138
queue_redraw();
21392139
}
21402140
} break;
2141+
2142+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
2143+
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor")) {
2144+
dropping_unfold_timer->set_wait_time(EDITOR_GET("interface/editor/dragging_hover_wait_seconds"));
2145+
}
2146+
} break;
21412147
}
21422148
}
21432149

@@ -2466,7 +2472,7 @@ EditorInspectorSection::EditorInspectorSection() {
24662472
vbox = memnew(VBoxContainer);
24672473

24682474
dropping_unfold_timer = memnew(Timer);
2469-
dropping_unfold_timer->set_wait_time(0.6);
2475+
dropping_unfold_timer->set_wait_time(EDITOR_GET("interface/editor/dragging_hover_wait_seconds"));
24702476
dropping_unfold_timer->set_one_shot(true);
24712477
add_child(dropping_unfold_timer);
24722478
dropping_unfold_timer->connect("timeout", callable_mp(this, &EditorInspectorSection::unfold));

editor/scene/scene_tree_editor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,8 @@ void SceneTreeEditor::_notification(int p_what) {
13621362
} break;
13631363

13641364
case NOTIFICATION_THEME_CHANGED: {
1365+
// Wait for the node to be inspected before triggering the unfolding.
1366+
tree->add_theme_constant_override("dragging_unfold_wait_msec", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000 * 2);
13651367
tree->add_theme_constant_override("icon_max_width", get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
13661368
[[fallthrough]];
13671369
}

editor/settings/editor_settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
505505
EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/editor/main_font", "", "*.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm")
506506
EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/editor/main_font_bold", "", "*.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm")
507507
EDITOR_SETTING(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/editor/code_font", "", "*.ttf,*.otf,*.woff,*.woff2,*.pfb,*.pfm")
508+
EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/editor/dragging_hover_wait_seconds", 0.5, "0.01,10,0.01,or_greater,suffix:s");
508509
_initial_set("interface/editor/separate_distraction_mode", false, true);
509510
_initial_set("interface/editor/automatically_open_screenshots", true, true);
510511
EDITOR_SETTING_USAGE(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/single_window_mode", false, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED | PROPERTY_USAGE_EDITOR_BASIC_SETTING)

editor/themes/editor_theme_manager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
980980
p_theme->set_constant("inner_item_margin_left", "Tree", p_config.increased_margin * EDSCALE);
981981
p_theme->set_constant("inner_item_margin_right", "Tree", p_config.increased_margin * EDSCALE);
982982
p_theme->set_constant("button_margin", "Tree", p_config.base_margin * EDSCALE);
983+
p_theme->set_constant("dragging_unfold_wait_msec", "Tree", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000);
983984
p_theme->set_constant("scroll_border", "Tree", 40 * EDSCALE);
984985
p_theme->set_constant("scroll_speed", "Tree", 12);
985986
p_theme->set_constant("outline_size", "Tree", 0);

scene/gui/tree.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ void TreeItem::_change_tree(Tree *p_tree) {
140140
}
141141

142142
if (tree->drop_mode_over == this) {
143-
tree->drop_mode_over = nullptr;
143+
tree->_reset_drop_mode_over();
144144
}
145145

146146
if (tree->single_select_defer == this) {
@@ -4266,6 +4266,9 @@ void Tree::_determine_hovered_item() {
42664266
if (drop_mode_flags) {
42674267
if (it != drop_mode_over) {
42684268
drop_mode_over = it;
4269+
if (enable_drag_unfolding) {
4270+
dropping_unfold_timer->start(theme_cache.dragging_unfold_wait_msec * 0.001);
4271+
}
42694272
queue_redraw();
42704273
}
42714274
if (it && section != drop_mode_section) {
@@ -4309,6 +4312,19 @@ void Tree::_determine_hovered_item() {
43094312
}
43104313
}
43114314

4315+
void Tree::_on_dropping_unfold_timer_timeout() {
4316+
if (enable_drag_unfolding && drop_mode_over && drop_mode_section == 0) {
4317+
drop_mode_over->set_collapsed(false);
4318+
}
4319+
}
4320+
4321+
void Tree::_reset_drop_mode_over() {
4322+
drop_mode_over = nullptr;
4323+
if (!dropping_unfold_timer->is_stopped()) {
4324+
dropping_unfold_timer->stop();
4325+
}
4326+
}
4327+
43124328
void Tree::_queue_update_hovered_item() {
43134329
if (hovered_update_queued) {
43144330
return;
@@ -6465,13 +6481,28 @@ bool Tree::is_recursive_folding_enabled() const {
64656481
return enable_recursive_folding;
64666482
}
64676483

6484+
void Tree::set_enable_drag_unfolding(bool p_enable) {
6485+
if (enable_drag_unfolding == p_enable) {
6486+
return;
6487+
}
6488+
6489+
enable_drag_unfolding = p_enable;
6490+
if (!enable_drag_unfolding && !dropping_unfold_timer->is_stopped()) {
6491+
dropping_unfold_timer->stop();
6492+
}
6493+
}
6494+
6495+
bool Tree::is_drag_unfolding_enabled() const {
6496+
return enable_drag_unfolding;
6497+
}
6498+
64686499
void Tree::set_drop_mode_flags(int p_flags) {
64696500
if (drop_mode_flags == p_flags) {
64706501
return;
64716502
}
64726503
drop_mode_flags = p_flags;
64736504
if (drop_mode_flags == 0) {
6474-
drop_mode_over = nullptr;
6505+
_reset_drop_mode_over();
64756506
}
64766507

64776508
queue_redraw();
@@ -6595,6 +6626,9 @@ void Tree::_bind_methods() {
65956626
ClassDB::bind_method(D_METHOD("set_enable_recursive_folding", "enable"), &Tree::set_enable_recursive_folding);
65966627
ClassDB::bind_method(D_METHOD("is_recursive_folding_enabled"), &Tree::is_recursive_folding_enabled);
65976628

6629+
ClassDB::bind_method(D_METHOD("set_enable_drag_unfolding", "enable"), &Tree::set_enable_drag_unfolding);
6630+
ClassDB::bind_method(D_METHOD("is_drag_unfolding_enabled"), &Tree::is_drag_unfolding_enabled);
6631+
65986632
ClassDB::bind_method(D_METHOD("set_drop_mode_flags", "flags"), &Tree::set_drop_mode_flags);
65996633
ClassDB::bind_method(D_METHOD("get_drop_mode_flags"), &Tree::get_drop_mode_flags);
66006634

@@ -6617,6 +6651,7 @@ void Tree::_bind_methods() {
66176651
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search");
66186652
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden");
66196653
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_recursive_folding"), "set_enable_recursive_folding", "is_recursive_folding_enabled");
6654+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_drag_unfolding"), "set_enable_drag_unfolding", "is_drag_unfolding_enabled");
66206655
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden");
66216656
ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags");
66226657
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() {
67156750
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Tree, parent_hl_line_color);
67166751
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, Tree, children_hl_line_color);
67176752

6753+
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Tree, dragging_unfold_wait_msec);
6754+
67186755
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Tree, scroll_border);
67196756
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, Tree, scroll_speed);
67206757

@@ -6772,6 +6809,11 @@ Tree::Tree() {
67726809
range_click_timer->connect("timeout", callable_mp(this, &Tree::_range_click_timeout));
67736810
add_child(range_click_timer, false, INTERNAL_MODE_FRONT);
67746811

6812+
dropping_unfold_timer = memnew(Timer);
6813+
dropping_unfold_timer->set_one_shot(true);
6814+
dropping_unfold_timer->connect("timeout", callable_mp(this, &Tree::_on_dropping_unfold_timer_timeout));
6815+
add_child(dropping_unfold_timer);
6816+
67756817
h_scroll->connect(SceneStringName(value_changed), callable_mp(this, &Tree::_scroll_moved));
67766818
v_scroll->connect(SceneStringName(value_changed), callable_mp(this, &Tree::_scroll_moved));
67776819
line_editor->connect(SceneStringName(text_submitted), callable_mp(this, &Tree::_line_editor_submit));

scene/gui/tree.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ class Tree : public Control {
654654
int parent_hl_line_margin = 0;
655655
int draw_guides = 0;
656656

657+
int dragging_unfold_wait_msec = 500;
658+
657659
int scroll_border = 0;
658660
int scroll_speed = 0;
659661

@@ -741,6 +743,11 @@ class Tree : public Control {
741743

742744
bool enable_recursive_folding = true;
743745

746+
bool enable_drag_unfolding = true;
747+
Timer *dropping_unfold_timer = nullptr;
748+
void _on_dropping_unfold_timer_timeout();
749+
void _reset_drop_mode_over();
750+
744751
bool enable_auto_tooltip = true;
745752

746753
bool hovered_update_queued = false;
@@ -892,6 +899,9 @@ class Tree : public Control {
892899
void set_enable_recursive_folding(bool p_enable);
893900
bool is_recursive_folding_enabled() const;
894901

902+
void set_enable_drag_unfolding(bool p_enable);
903+
bool is_drag_unfolding_enabled() const;
904+
895905
void set_drop_mode_flags(int p_flags);
896906
int get_drop_mode_flags() const;
897907

0 commit comments

Comments
 (0)