Skip to content

Commit b400633

Browse files
committed
Show detach script button when added via inspector
Fixes #107059. The SceneTreeDock was not tracking script changes in selected nodes in any capacity as far as I could assess. To do that, my solution essentially connects the "script_changed" signal from selected nodes to "SceneTreeDock::_update_script_button()" whenever the selection changes. It actually queues the update to make sure it happens only once no matter how many nodes are selected. However, only connecting that signal would leave previously selected nodes with a signal connection that should no longer exist. To properly disconnect previously selected nodes, we have to store the list of currently selected nodes so we can disconnect them when the selection changes. The commit also includes some improvements to the SceneTreeDock class: 1. Remove unnecessary initialization in SceneTreeDock This field is already initialized in the line that declares it. As such, initializing it on the constructor as well as is redundant. 2. Queue script button updates in scene tree dock Since we now have the option to defer the script button update and make sure it only runs once per frame, it's always best to use the queued version of the update from a performance perspective. I'm not entirely sure if there could be any unexpected side effects but it is a minor self-contained UI update, so it's likely a relatively safe change. The replacement includes the bindings since it is a requirement for the other replacements in the class to work (UndoRedo needs their method names registered in the class DB). It should be OK to remove the old non-queued bindings too even though they are accessible in the public API because it is a "unofficial" method starting with an underscore.
1 parent f92f1ce commit b400633

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

editor/docks/scene_tree_dock.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
789789
}
790790
}
791791

792-
undo_redo->add_do_method(this, "_update_script_button");
793-
undo_redo->add_undo_method(this, "_update_script_button");
792+
undo_redo->add_do_method(this, "_queue_update_script_button");
793+
undo_redo->add_undo_method(this, "_queue_update_script_button");
794794

795795
undo_redo->commit_action();
796796
} break;
@@ -2578,16 +2578,16 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
25782578
undo_redo->add_undo_method(E, "set_script", existing);
25792579
undo_redo->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", E);
25802580
undo_redo->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", E);
2581-
undo_redo->add_do_method(this, "_update_script_button");
2582-
undo_redo->add_undo_method(this, "_update_script_button");
2581+
undo_redo->add_do_method(this, "_queue_update_script_button");
2582+
undo_redo->add_undo_method(this, "_queue_update_script_button");
25832583
}
25842584
undo_redo->commit_action();
25852585

25862586
// Avoid changing the currently edited object.
25872587
Object *edited_object = InspectorDock::get_inspector_singleton()->get_edited_object();
25882588

25892589
_push_item(p_script.ptr());
2590-
_update_script_button();
2590+
_queue_update_script_button();
25912591

25922592
InspectorDock::get_inspector_singleton()->edit(edited_object);
25932593
}
@@ -2901,6 +2901,16 @@ void SceneTreeDock::_update_script_button() {
29012901
button_create_script->set_visible(can_create_script);
29022902
button_detach_script->set_visible(can_detach_script);
29032903
button_extend_script->set_visible(can_extend_script);
2904+
2905+
update_script_button_queued = false;
2906+
}
2907+
2908+
void SceneTreeDock::_queue_update_script_button() {
2909+
if (update_script_button_queued) {
2910+
return;
2911+
}
2912+
update_script_button_queued = true;
2913+
callable_mp(this, &SceneTreeDock::_update_script_button).call_deferred();
29042914
}
29052915

29062916
void SceneTreeDock::_selection_changed() {
@@ -2914,7 +2924,20 @@ void SceneTreeDock::_selection_changed() {
29142924
_push_item(nullptr);
29152925
}
29162926

2917-
_update_script_button();
2927+
// Untrack script changes in previously selected nodes.
2928+
for (Node *node : node_previous_selection) {
2929+
node->disconnect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button));
2930+
}
2931+
2932+
// Track script changes in newly selected nodes.
2933+
node_previous_selection.clear();
2934+
node_previous_selection.reserve(editor_selection->get_selection().size());
2935+
for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) {
2936+
Node *node = E.key;
2937+
node_previous_selection.push_back(node);
2938+
node->connect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button));
2939+
}
2940+
_queue_update_script_button();
29182941
}
29192942

29202943
Node *SceneTreeDock::_do_create(Node *p_parent) {
@@ -3682,8 +3705,8 @@ void SceneTreeDock::_script_dropped(const String &p_file, NodePath p_to) {
36823705
undo_redo->add_undo_method(n, "set_script", n->get_script());
36833706
undo_redo->add_do_method(InspectorDock::get_singleton(), "apply_script_properties", n);
36843707
undo_redo->add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", n);
3685-
undo_redo->add_do_method(this, "_update_script_button");
3686-
undo_redo->add_undo_method(this, "_update_script_button");
3708+
undo_redo->add_do_method(this, "_queue_update_script_button");
3709+
undo_redo->add_undo_method(this, "_queue_update_script_button");
36873710
undo_redo->commit_action();
36883711
}
36893712
}
@@ -4456,7 +4479,7 @@ void SceneTreeDock::_feature_profile_changed() {
44564479
profile_allow_script_editing = true;
44574480
}
44584481

4459-
_update_script_button();
4482+
_queue_update_script_button();
44604483
}
44614484

44624485
void SceneTreeDock::_clear_clipboard() {
@@ -4631,7 +4654,7 @@ void SceneTreeDock::_bind_methods() {
46314654
ClassDB::bind_method(D_METHOD("_reparent_nodes_to_root"), &SceneTreeDock::_reparent_nodes_to_root);
46324655
ClassDB::bind_method(D_METHOD("_reparent_nodes_to_paths_with_transform_and_name"), &SceneTreeDock::_reparent_nodes_to_paths_with_transform_and_name);
46334656

4634-
ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button);
4657+
ClassDB::bind_method(D_METHOD("_queue_update_script_button"), &SceneTreeDock::_queue_update_script_button);
46354658

46364659
ClassDB::bind_method(D_METHOD("instantiate"), &SceneTreeDock::instantiate);
46374660
ClassDB::bind_method(D_METHOD("get_tree_editor"), &SceneTreeDock::get_tree_editor);
@@ -4653,7 +4676,6 @@ void SceneTreeDock::_update_configuration_warning() {
46534676
SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) {
46544677
singleton = this;
46554678
set_name("Scene");
4656-
edited_scene = nullptr;
46574679
editor_data = &p_editor_data;
46584680
editor_selection = p_editor_selection;
46594681
scene_root = p_scene_root;

editor/docks/scene_tree_dock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class SceneTreeDock : public VBoxContainer {
135135

136136
EditorData *editor_data = nullptr;
137137
EditorSelection *editor_selection = nullptr;
138+
LocalVector<Node *> node_previous_selection;
139+
bool update_script_button_queued = false;
138140

139141
List<Node *> node_clipboard;
140142
HashSet<Node *> node_clipboard_edited_scene_owned;
@@ -248,6 +250,7 @@ class SceneTreeDock : public VBoxContainer {
248250
bool _validate_no_instance();
249251
void _selection_changed();
250252
void _update_script_button();
253+
void _queue_update_script_button();
251254

252255
void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, HashMap<Node *, NodePath> *p_renames);
253256
bool _has_tracks_to_delete(Node *p_node, List<Node *> &p_to_delete) const;

0 commit comments

Comments
 (0)