From 9d4afdc37231146d0e36fe91d982d2edd9274b47 Mon Sep 17 00:00:00 2001 From: Blazej Floch Date: Tue, 9 Jan 2018 01:05:15 -0500 Subject: - Fixes #15470 "Crash on drag and drop scene file on empty scene" - New: Allows for multiple files to be dragged over - Added error when multiple nodes are dropped in scene **without** scene root - Removed TTR: "This operation requires a single selected node.", "I see.." - Introduces TTR: "Can not instaniate multiple nodes without root." - Fixes "Can't add_child, already got a parent" error - Reduced multiple resource loading by casting - Make sure to not _show_resource_type_selector if only PackedScenes are being dropped --- editor/plugins/canvas_item_editor_plugin.cpp | 110 +++++++++++++++++---------- editor/plugins/canvas_item_editor_plugin.h | 1 + 2 files changed, 71 insertions(+), 40 deletions(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 2a46aba207..bd5e5c7355 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4435,6 +4435,7 @@ void CanvasItemEditorViewport::_on_change_type_closed() { void CanvasItemEditorViewport::_create_preview(const Vector &files) const { label->set_position(get_global_position() + Point2(14, 14) * EDSCALE); label_desc->set_position(label->get_position() + Point2(0, label->get_size().height)); + bool add_preview = false; for (int i = 0; i < files.size(); i++) { String path = files[i]; RES res = ResourceLoader::load(path); @@ -4456,9 +4457,12 @@ void CanvasItemEditorViewport::_create_preview(const Vector &files) cons } } } - editor->get_scene_root()->add_child(preview_node); + add_preview = true; } } + + if (add_preview) + editor->get_scene_root()->add_child(preview_node); } void CanvasItemEditorViewport::_remove_preview() { @@ -4603,6 +4607,14 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons void CanvasItemEditorViewport::_perform_drop_data() { _remove_preview(); + // Without root dropping multiple files is not allowed + if (!target_node && selected_files.size() > 1) { + accept->get_ok()->set_text(TTR("Ok")); + accept->set_text(TTR("Cannot instantiate multiple nodes without root.")); + accept->popup_centered_minsize(); + return; + } + Vector error_files; editor_data->get_undo_redo().create_action(TTR("Create Node")); @@ -4613,30 +4625,40 @@ void CanvasItemEditorViewport::_perform_drop_data() { if (res.is_null()) { continue; } - Ref texture = Ref(Object::cast_to(*res)); Ref scene = Ref(Object::cast_to(*res)); - if (texture != NULL) { - Node *child; - if (default_type == "Light2D") - child = memnew(Light2D); - else if (default_type == "Particles2D") - child = memnew(Particles2D); - else if (default_type == "Polygon2D") - child = memnew(Polygon2D); - else if (default_type == "TouchScreenButton") - child = memnew(TouchScreenButton); - else if (default_type == "TextureRect") - child = memnew(TextureRect); - else if (default_type == "NinePatchRect") - child = memnew(NinePatchRect); - else - child = memnew(Sprite); // default - - _create_nodes(target_node, child, path, drop_pos); - } else if (scene != NULL) { - bool success = _create_instance(target_node, path, drop_pos); - if (!success) { - error_files.push_back(path); + if (scene != NULL && scene.is_valid()) { + if (!target_node) { + // Without root node act the same as "Load Inherited Scene" + Error err = EditorNode::get_singleton()->load_scene(path, false, true); + if (err != OK) { + error_files.push_back(path); + } + } else { + bool success = _create_instance(target_node, path, drop_pos); + if (!success) { + error_files.push_back(path); + } + } + } else { + Ref texture = Ref(Object::cast_to(*res)); + if (texture != NULL && texture.is_valid()) { + Node *child; + if (default_type == "Light2D") + child = memnew(Light2D); + else if (default_type == "Particles2D") + child = memnew(Particles2D); + else if (default_type == "Polygon2D") + child = memnew(Polygon2D); + else if (default_type == "TouchScreenButton") + child = memnew(TouchScreenButton); + else if (default_type == "TextureRect") + child = memnew(TextureRect); + else if (default_type == "NinePatchRect") + child = memnew(NinePatchRect); + else + child = memnew(Sprite); // default + + _create_nodes(target_node, child, path, drop_pos); } } } @@ -4661,14 +4683,14 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian if (String(d["type"]) == "files") { Vector files = d["files"]; bool can_instance = false; - for (int i = 0; i < files.size(); i++) { // check if dragged files contain resource or scene can be created at least one + for (int i = 0; i < files.size(); i++) { // check if dragged files contain resource or scene can be created at least once RES res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } String type = res->get_class(); if (type == "PackedScene") { - Ref sdata = ResourceLoader::load(files[i]); + Ref sdata = Ref(Object::cast_to(*res)); Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instanced_scene) { continue; @@ -4682,7 +4704,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian type == "StreamTexture" || type == "AtlasTexture" || type == "LargeTexture") { - Ref texture = ResourceLoader::load(files[i]); + Ref texture = Ref(Object::cast_to(*res)); if (texture.is_valid() == false) { continue; } @@ -4708,6 +4730,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian } void CanvasItemEditorViewport::_show_resource_type_selector() { + _remove_preview(); List btn_list; button_group->get_buttons(&btn_list); @@ -4719,6 +4742,17 @@ void CanvasItemEditorViewport::_show_resource_type_selector() { selector->popup_centered_minsize(); } +bool CanvasItemEditorViewport::_only_packed_scenes_selected() const { + + for (int i = 0; i < selected_files.size(); ++i) { + if (ResourceLoader::load(selected_files[i])->get_class() != "PackedScene") { + return false; + } + } + + return true; +} + void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p_data) { bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT); bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT); @@ -4728,6 +4762,8 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p if (d.has("type") && String(d["type"]) == "files") { selected_files = d["files"]; } + if (selected_files.size() == 0) + return; List list = editor->get_editor_selection()->get_selected_node_list(); if (list.size() == 0) { @@ -4737,25 +4773,19 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p } else { drop_pos = p_point; target_node = NULL; - _show_resource_type_selector(); - return; } } - if (list.size() != 1) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation requires a single selected node.")); - accept->popup_centered_minsize(); - _remove_preview(); - return; - } - target_node = list[0]; - if (is_shift && target_node != editor->get_edited_scene()) { - target_node = target_node->get_parent(); + if (list.size() > 0) { + target_node = list[0]; + if (is_shift && target_node != editor->get_edited_scene()) { + target_node = target_node->get_parent(); + } } + drop_pos = p_point; - if (is_alt) { + if (is_alt && !_only_packed_scenes_selected()) { _show_resource_type_selector(); } else { _perform_drop_data(); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 5be71bfc28..ace87f9fe2 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -576,6 +576,7 @@ class CanvasItemEditorViewport : public Control { void _remove_preview(); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); + bool _only_packed_scenes_selected() const; void _create_nodes(Node *parent, Node *child, String &path, const Point2 &p_point); bool _create_instance(Node *parent, String &path, const Point2 &p_point); void _perform_drop_data(); -- cgit v1.2.3