Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically add root node when drag-and-dropping in 3D editor #55626

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 36 additions & 17 deletions editor/plugins/spatial_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3828,7 +3828,23 @@ bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const P
if (mesh != nullptr) {
MeshInstance *mesh_instance = memnew(MeshInstance);
mesh_instance->set_mesh(mesh);
mesh_instance->set_name(path.get_file().get_basename());

// Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
String name = path.get_file().get_basename();
switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) {
case NAME_CASING_PASCAL_CASE:
name = name.capitalize().replace(" ", "");
break;
case NAME_CASING_CAMEL_CASE:
name = name.capitalize().replace(" ", "");
name[0] = name.to_lower()[0];
break;
case NAME_CASING_SNAKE_CASE:
name = name.capitalize().replace(" ", "_").to_lower();
break;
}
mesh_instance->set_name(name);

instanced_scene = mesh_instance;
} else {
if (!scene.is_valid()) { // invalid scene
Expand Down Expand Up @@ -3979,36 +3995,39 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
}

bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);

selected_files.clear();
Dictionary d = p_data;
if (d.has("type") && String(d["type"]) == "files") {
selected_files = d["files"];
}

List<Node *> list = editor->get_editor_selection()->get_selected_node_list();
if (list.size() == 0) {
Node *root_node = editor->get_edited_scene();
List<Node *> selected_nodes = editor->get_editor_selection()->get_selected_node_list();
Node *root_node = editor->get_edited_scene();
if (selected_nodes.size() == 1) {
Node *selected_node = selected_nodes[0];
target_node = root_node;
if (is_ctrl) {
target_node = selected_node;
} else if (is_shift && selected_node != root_node) {
target_node = selected_node->get_parent();
}
} else if (selected_nodes.size() == 0) {
if (root_node) {
list.push_back(root_node);
target_node = root_node;
} else {
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered_minsize();
_remove_preview();
return;
// Create a root node so we can add child nodes to it.
EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Spatial));
target_node = get_tree()->get_edited_scene_root();
}
}
if (list.size() != 1) {
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
} else {
accept->set_text(TTR("Cannot drag and drop into multiple selected nodes."));
accept->popup_centered();
_remove_preview();
return;
}

target_node = list[0];
if (is_shift && target_node != editor->get_edited_scene()) {
target_node = target_node->get_parent();
}
drop_pos = p_point;

_perform_drop_data();
Expand Down
17 changes: 11 additions & 6 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1190,12 +1190,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}

editor_data->get_undo_redo().create_action(TTR("New Scene Root"));
editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", new_node);
editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
editor_data->get_undo_redo().add_do_reference(new_node);
editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)nullptr);
editor_data->get_undo_redo().commit_action();
add_root_node(new_node);

editor->edit_node(new_node);
editor_selection->clear();
Expand Down Expand Up @@ -1233,6 +1228,16 @@ void SceneTreeDock::_perform_property_drop(Node *p_node, String p_property, RES
editor_data->get_undo_redo().add_undo_method(p_node, "property_list_changed_notify");
editor_data->get_undo_redo().commit_action();
}

void SceneTreeDock::add_root_node(Node *p_node) {
editor_data->get_undo_redo().create_action(TTR("New Scene Root"));
editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", p_node);
editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
editor_data->get_undo_redo().add_do_reference(p_node);
editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)nullptr);
editor_data->get_undo_redo().commit_action();
}

void SceneTreeDock::_node_collapsed(Object *p_obj) {
TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
if (!ti) {
Expand Down
1 change: 1 addition & 0 deletions editor/scene_tree_dock.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ class SceneTreeDock : public VBoxContainer {
void show_tab_buttons();
void hide_tab_buttons();

void add_root_node(Node *p_node);
void replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties = true, bool p_remove_old = true);

void attach_script_to_selected(bool p_extend);
Expand Down