summaryrefslogtreecommitdiff
path: root/editor/scene_tree_dock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/scene_tree_dock.cpp')
-rw-r--r--editor/scene_tree_dock.cpp148
1 files changed, 128 insertions, 20 deletions
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 9f0f62592b..b13b238fd7 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -345,17 +345,30 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_CLEAR_SCRIPT: {
- Node *selected = scene_tree->get_selected();
- if (!selected)
- break;
- Ref<Script> existing = selected->get_script();
- if (existing.is_valid()) {
- const RefPtr empty;
- selected->set_script(empty);
- _update_script_button();
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ if (selection.empty())
+ return;
+
+ editor_data->get_undo_redo().create_action(TTR("Clear Script"));
+ editor_data->get_undo_redo().add_do_method(editor, "push_item", (Script *)NULL);
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Ref<Script> existing = E->get()->get_script();
+ if (existing.is_valid()) {
+ const RefPtr empty;
+ editor_data->get_undo_redo().add_do_method(E->get(), "set_script", empty);
+ editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
+ }
}
+ editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+ editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+
+ editor_data->get_undo_redo().commit_action();
+
} break;
case TOOL_MOVE_UP:
case TOOL_MOVE_DOWN: {
@@ -903,9 +916,6 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
if (!r_rem_anims)
r_rem_anims = &rem_anims;
- if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true)))
- return;
-
if (!p_base) {
p_base = edited_scene;
@@ -914,7 +924,54 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
if (!p_base)
return;
- if (Object::cast_to<AnimationPlayer>(p_base)) {
+ // Renaming node paths used in script instances
+ if (p_base->get_script_instance()) {
+
+ ScriptInstance *si = p_base->get_script_instance();
+
+ if (si) {
+
+ List<PropertyInfo> properties;
+ si->get_property_list(&properties);
+
+ for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+
+ String propertyname = E->get().name;
+ Variant p = p_base->get(propertyname);
+ if (p.get_type() == Variant::NODE_PATH) {
+
+ // Goes through all paths to check if its matching
+ for (List<Pair<NodePath, NodePath> >::Element *E = p_renames->front(); E; E = E->next()) {
+
+ NodePath root_path = p_base->get_path();
+
+ NodePath rel_path_old = root_path.rel_path_to(E->get().first);
+
+ NodePath rel_path_new = E->get().second;
+
+ // if not empty, get new relative path
+ if (E->get().second != NodePath()) {
+ rel_path_new = root_path.rel_path_to(E->get().second);
+ }
+
+ // if old path detected, then it needs to be replaced with the new one
+ if (p == rel_path_old) {
+
+ editor_data->get_undo_redo().add_do_property(p_base, propertyname, rel_path_new);
+ editor_data->get_undo_redo().add_undo_property(p_base, propertyname, rel_path_old);
+
+ p_base->set(propertyname, rel_path_new);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bool autorename_animation_tracks = bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true));
+
+ if (autorename_animation_tracks && Object::cast_to<AnimationPlayer>(p_base)) {
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_base);
List<StringName> anims;
@@ -1145,7 +1202,30 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
editor_data->get_undo_redo().add_do_method(new_parent, "move_child", node, p_position_in_parent + inc);
ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
+ String old_name = former_names[ni];
String new_name = new_parent->validate_child_name(node);
+
+ // name was modified, fix the path renames
+ if (old_name.casecmp_to(new_name) != 0) {
+
+ // Fix the to name to have the new name
+ NodePath old_new_name = path_renames[ni].second;
+ NodePath new_path;
+
+ Vector<StringName> unfixed_new_names = old_new_name.get_names();
+ Vector<StringName> fixed_new_names;
+
+ // Get last name and replace with fixed new name
+ for (int a = 0; a < (unfixed_new_names.size() - 1); a++) {
+ fixed_new_names.push_back(unfixed_new_names[a]);
+ }
+ fixed_new_names.push_back(new_name);
+
+ NodePath fixed_node_path = NodePath(fixed_new_names, true);
+
+ path_renames[ni].second = fixed_node_path;
+ }
+
editor_data->get_undo_redo().add_do_method(sed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, -1);
editor_data->get_undo_redo().add_undo_method(sed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)) + "/" + new_name), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index());
@@ -1208,12 +1288,26 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
void SceneTreeDock::_script_created(Ref<Script> p_script) {
- Node *selected = scene_tree->get_selected();
- if (!selected)
+ List<Node *> selected = editor_selection->get_selected_node_list();
+
+ if (selected.empty())
return;
- selected->set_script(p_script.get_ref_ptr());
- editor->push_item(p_script.operator->());
- _update_script_button();
+
+ editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+ for (List<Node *>::Element *E = selected.front(); E; E = E->next()) {
+
+ Ref<Script> existing = E->get()->get_script();
+ editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr());
+ editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
+ }
+
+ editor_data->get_undo_redo().add_do_method(editor, "push_item", p_script.operator->());
+ editor_data->get_undo_redo().add_undo_method(editor, "push_item", (Script *)NULL);
+
+ editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+ editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+
+ editor_data->get_undo_redo().commit_action();
}
void SceneTreeDock::_delete_confirm() {
@@ -1411,6 +1505,7 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) {
Node *n = p_node;
Node *newnode = p_by_node;
+ Node *default_oldnode = Object::cast_to<Node>(ClassDB::instance(n->get_class()));
List<PropertyInfo> pinfo;
n->get_property_list(&pinfo);
@@ -1419,8 +1514,11 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) {
continue;
if (E->get().name == "__meta__")
continue;
- newnode->set(E->get().name, n->get(E->get().name));
+ if (default_oldnode->get(E->get().name) != n->get(E->get().name)) {
+ newnode->set(E->get().name, n->get(E->get().name));
+ }
}
+ memdelete(default_oldnode);
editor->push_item(NULL);
@@ -1665,8 +1763,12 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
ERR_FAIL_COND(!scr.is_valid());
Node *n = get_node(p_to);
if (n) {
- n->set_script(scr.get_ref_ptr());
- _update_script_button();
+ editor_data->get_undo_redo().create_action(TTR("Attach Script"));
+ editor_data->get_undo_redo().add_do_method(n, "set_script", scr);
+ editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script());
+ editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
+ editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");
+ editor_data->get_undo_redo().commit_action();
}
}
@@ -1759,6 +1861,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
subresources.clear();
menu_subresources->clear();
+ menu_subresources->set_size(Size2(1, 1));
_add_children_to_popup(selection.front()->get(), 0);
if (menu->get_item_count() > 0)
menu->add_separator();
@@ -1803,6 +1906,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
}
}
+ } else {
+ menu->add_separator();
+ menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
+ menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
}
menu->add_separator();
menu->add_icon_shortcut(get_icon("Remove", "EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE);
@@ -1921,6 +2028,7 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_focus_node"), &SceneTreeDock::_focus_node);
ClassDB::bind_method(D_METHOD("_remote_tree_selected"), &SceneTreeDock::_remote_tree_selected);
ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected);
+ ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button);
ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance);