summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2018-01-10 07:57:35 +0100
committerGitHub <noreply@github.com>2018-01-10 07:57:35 +0100
commit4a25a4e53f4c3b457ac2003bab7cf0001dd5aab1 (patch)
tree68230c2bd88e6ffa9b009b236b44957a29e2eacd /editor/plugins
parent2ac27608a6892d8d7e28d8afbbcc98505eb3e4b3 (diff)
parent9d4afdc37231146d0e36fe91d982d2edd9274b47 (diff)
Merge pull request #15516 from StateOff/fixes_crash_on_drop_scene_file
Fixes #15470 "Crash on drag and drop scene file on empty scene"
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp110
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h1
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<String> &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<String> &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<String> 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> texture = Ref<Texture>(Object::cast_to<Texture>(*res));
Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*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> texture = Ref<Texture>(Object::cast_to<Texture>(*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<String> 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<PackedScene> sdata = ResourceLoader::load(files[i]);
+ Ref<PackedScene> sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(*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> texture = ResourceLoader::load(files[i]);
+ Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(*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<BaseButton *> 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<Node *> 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();