|
@@ -151,6 +151,51 @@ EditorNode *EditorNode::singleton = nullptr;
|
|
// The metadata key used to store and retrieve the version text to copy to the clipboard.
|
|
// The metadata key used to store and retrieve the version text to copy to the clipboard.
|
|
static const String META_TEXT_TO_COPY = "text_to_copy";
|
|
static const String META_TEXT_TO_COPY = "text_to_copy";
|
|
|
|
|
|
|
|
+class AcceptDialogAutoReparent : public AcceptDialog {
|
|
|
|
+ GDCLASS(AcceptDialogAutoReparent, AcceptDialog);
|
|
|
|
+
|
|
|
|
+protected:
|
|
|
|
+ void _notification(int p_what) {
|
|
|
|
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
|
|
|
+ if (!is_visible()) {
|
|
|
|
+ Node *p = get_parent();
|
|
|
|
+ if (p) {
|
|
|
|
+ p->remove_child(this);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+public:
|
|
|
|
+ void attach_and_popup_centered() {
|
|
|
|
+ EditorNode *ed = EditorNode::get_singleton();
|
|
|
|
+ if (ed && !is_inside_tree()) {
|
|
|
|
+ Window *w = ed->get_window();
|
|
|
|
+ while (w && w->get_exclusive_child()) {
|
|
|
|
+ w = w->get_exclusive_child();
|
|
|
|
+ }
|
|
|
|
+ if (w && w != this) {
|
|
|
|
+ w->add_child(this);
|
|
|
|
+ popup_centered();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void attach_and_popup_centered_ratio(float p_ratio = 0.8) {
|
|
|
|
+ EditorNode *ed = EditorNode::get_singleton();
|
|
|
|
+ if (ed && !is_inside_tree()) {
|
|
|
|
+ Window *w = ed->get_window();
|
|
|
|
+ while (w && w->get_exclusive_child()) {
|
|
|
|
+ w = w->get_exclusive_child();
|
|
|
|
+ }
|
|
|
|
+ if (w && w != this) {
|
|
|
|
+ w->add_child(this);
|
|
|
|
+ popup_centered_ratio(p_ratio);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames) {
|
|
void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames) {
|
|
ERR_FAIL_COND_MSG(p_full_paths.size() != r_filenames.size(), vformat("disambiguate_filenames requires two string vectors of same length (%d != %d).", p_full_paths.size(), r_filenames.size()));
|
|
ERR_FAIL_COND_MSG(p_full_paths.size() != r_filenames.size(), vformat("disambiguate_filenames requires two string vectors of same length (%d != %d).", p_full_paths.size(), r_filenames.size()));
|
|
|
|
|
|
@@ -615,6 +660,21 @@ void EditorNode::_notification(int p_what) {
|
|
if (progress_dialog) {
|
|
if (progress_dialog) {
|
|
progress_dialog->queue_free();
|
|
progress_dialog->queue_free();
|
|
}
|
|
}
|
|
|
|
+ if (load_error_dialog) {
|
|
|
|
+ load_error_dialog->queue_free();
|
|
|
|
+ }
|
|
|
|
+ if (execute_output_dialog) {
|
|
|
|
+ execute_output_dialog->queue_free();
|
|
|
|
+ }
|
|
|
|
+ if (warning) {
|
|
|
|
+ warning->queue_free();
|
|
|
|
+ }
|
|
|
|
+ if (accept) {
|
|
|
|
+ accept->queue_free();
|
|
|
|
+ }
|
|
|
|
+ if (save_accept) {
|
|
|
|
+ save_accept->queue_free();
|
|
|
|
+ }
|
|
editor_data.save_editor_external_data();
|
|
editor_data.save_editor_external_data();
|
|
FileAccess::set_file_close_fail_notify_callback(nullptr);
|
|
FileAccess::set_file_close_fail_notify_callback(nullptr);
|
|
log->deinit(); // Do not get messages anymore.
|
|
log->deinit(); // Do not get messages anymore.
|
|
@@ -1233,6 +1293,12 @@ void EditorNode::edit_resource(const Ref<Resource> &p_resource) {
|
|
|
|
|
|
void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) {
|
|
void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) {
|
|
editor_data.apply_changes_in_editors();
|
|
editor_data.apply_changes_in_editors();
|
|
|
|
+
|
|
|
|
+ if (saving_resources_in_path.has(p_resource)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ saving_resources_in_path.insert(p_resource);
|
|
|
|
+
|
|
int flg = 0;
|
|
int flg = 0;
|
|
if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) {
|
|
if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) {
|
|
flg |= ResourceSaver::FLAG_COMPRESS;
|
|
flg |= ResourceSaver::FLAG_COMPRESS;
|
|
@@ -1247,10 +1313,16 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St
|
|
} else {
|
|
} else {
|
|
show_accept(TTR("Error saving resource!"), TTR("OK"));
|
|
show_accept(TTR("Error saving resource!"), TTR("OK"));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ saving_resources_in_path.erase(p_resource);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
((Resource *)p_resource.ptr())->set_path(path);
|
|
((Resource *)p_resource.ptr())->set_path(path);
|
|
|
|
+ saving_resources_in_path.erase(p_resource);
|
|
|
|
+
|
|
|
|
+ _resource_saved(p_resource, path);
|
|
|
|
+
|
|
emit_signal(SNAME("resource_saved"), p_resource);
|
|
emit_signal(SNAME("resource_saved"), p_resource);
|
|
editor_data.notify_resource_saved(p_resource);
|
|
editor_data.notify_resource_saved(p_resource);
|
|
}
|
|
}
|
|
@@ -4266,9 +4338,11 @@ void EditorNode::add_io_error(const String &p_error) {
|
|
|
|
|
|
void EditorNode::_load_error_notify(void *p_ud, const String &p_text) {
|
|
void EditorNode::_load_error_notify(void *p_ud, const String &p_text) {
|
|
EditorNode *en = static_cast<EditorNode *>(p_ud);
|
|
EditorNode *en = static_cast<EditorNode *>(p_ud);
|
|
- en->load_errors->add_image(en->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
|
|
|
|
- en->load_errors->add_text(p_text + "\n");
|
|
|
|
- en->load_error_dialog->popup_centered_ratio(0.5);
|
|
|
|
|
|
+ if (en && en->load_error_dialog) {
|
|
|
|
+ en->load_errors->add_image(en->gui_base->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")));
|
|
|
|
+ en->load_errors->add_text(p_text + "\n");
|
|
|
|
+ en->load_error_dialog->attach_and_popup_centered_ratio(0.5);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
|
|
bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
|
|
@@ -4639,23 +4713,27 @@ Error EditorNode::export_preset(const String &p_preset, const String &p_path, bo
|
|
|
|
|
|
void EditorNode::show_accept(const String &p_text, const String &p_title) {
|
|
void EditorNode::show_accept(const String &p_text, const String &p_title) {
|
|
current_menu_option = -1;
|
|
current_menu_option = -1;
|
|
- accept->set_ok_button_text(p_title);
|
|
|
|
- accept->set_text(p_text);
|
|
|
|
- accept->popup_centered();
|
|
|
|
|
|
+ if (accept) {
|
|
|
|
+ accept->set_ok_button_text(p_title);
|
|
|
|
+ accept->set_text(p_text);
|
|
|
|
+ accept->attach_and_popup_centered();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
|
|
void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
|
|
current_menu_option = -1;
|
|
current_menu_option = -1;
|
|
- save_accept->set_ok_button_text(p_title);
|
|
|
|
- save_accept->set_text(p_text);
|
|
|
|
- save_accept->popup_centered();
|
|
|
|
|
|
+ if (save_accept) {
|
|
|
|
+ save_accept->set_ok_button_text(p_title);
|
|
|
|
+ save_accept->set_text(p_text);
|
|
|
|
+ save_accept->attach_and_popup_centered();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void EditorNode::show_warning(const String &p_text, const String &p_title) {
|
|
void EditorNode::show_warning(const String &p_text, const String &p_title) {
|
|
- if (warning->is_inside_tree()) {
|
|
|
|
|
|
+ if (warning) {
|
|
warning->set_text(p_text);
|
|
warning->set_text(p_text);
|
|
warning->set_title(p_title);
|
|
warning->set_title(p_title);
|
|
- warning->popup_centered();
|
|
|
|
|
|
+ warning->attach_and_popup_centered();
|
|
} else {
|
|
} else {
|
|
WARN_PRINT(p_title + " " + p_text);
|
|
WARN_PRINT(p_title + " " + p_text);
|
|
}
|
|
}
|
|
@@ -4795,6 +4873,7 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
|
|
dock_slot[nrect]->add_child(dock);
|
|
dock_slot[nrect]->add_child(dock);
|
|
dock_popup_selected_idx = nrect;
|
|
dock_popup_selected_idx = nrect;
|
|
dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count() - 1);
|
|
dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count() - 1);
|
|
|
|
+ dock_slot[nrect]->set_tab_title(dock_slot[nrect]->get_tab_count() - 1, TTRGET(dock->get_name()));
|
|
dock_slot[nrect]->show();
|
|
dock_slot[nrect]->show();
|
|
dock_select->queue_redraw();
|
|
dock_select->queue_redraw();
|
|
|
|
|
|
@@ -5152,6 +5231,7 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String
|
|
}
|
|
}
|
|
dock_slot[i]->add_child(node);
|
|
dock_slot[i]->add_child(node);
|
|
dock_slot[i]->move_child(node, 0);
|
|
dock_slot[i]->move_child(node, 0);
|
|
|
|
+ dock_slot[i]->set_tab_title(0, TTRGET(node->get_name()));
|
|
dock_slot[i]->show();
|
|
dock_slot[i]->show();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -6441,6 +6521,11 @@ void EditorNode::_renderer_selected(int p_which) {
|
|
}
|
|
}
|
|
|
|
|
|
void EditorNode::_resource_saved(Ref<Resource> p_resource, const String &p_path) {
|
|
void EditorNode::_resource_saved(Ref<Resource> p_resource, const String &p_path) {
|
|
|
|
+ if (singleton->saving_resources_in_path.has(p_resource)) {
|
|
|
|
+ // This is going to be handled by save_resource_in_path when the time is right.
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (EditorFileSystem::get_singleton()) {
|
|
if (EditorFileSystem::get_singleton()) {
|
|
EditorFileSystem::get_singleton()->update_file(p_path);
|
|
EditorFileSystem::get_singleton()->update_file(p_path);
|
|
}
|
|
}
|
|
@@ -6492,7 +6577,6 @@ void EditorNode::_feature_profile_changed() {
|
|
}
|
|
}
|
|
|
|
|
|
void EditorNode::_bind_methods() {
|
|
void EditorNode::_bind_methods() {
|
|
- GLOBAL_DEF(PropertyInfo(Variant::INT, "editor/naming/scene_name_casing", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case"), SCENE_NAME_CASING_SNAKE_CASE);
|
|
|
|
ClassDB::bind_method("edit_current", &EditorNode::edit_current);
|
|
ClassDB::bind_method("edit_current", &EditorNode::edit_current);
|
|
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
|
|
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
|
|
|
|
|
|
@@ -6549,11 +6633,13 @@ static void _execute_thread(void *p_ud) {
|
|
}
|
|
}
|
|
|
|
|
|
int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok, bool p_close_on_errors) {
|
|
int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok, bool p_close_on_errors) {
|
|
- execute_output_dialog->set_title(p_title);
|
|
|
|
- execute_output_dialog->get_ok_button()->set_disabled(true);
|
|
|
|
- execute_outputs->clear();
|
|
|
|
- execute_outputs->set_scroll_follow(true);
|
|
|
|
- execute_output_dialog->popup_centered_ratio();
|
|
|
|
|
|
+ if (execute_output_dialog) {
|
|
|
|
+ execute_output_dialog->set_title(p_title);
|
|
|
|
+ execute_output_dialog->get_ok_button()->set_disabled(true);
|
|
|
|
+ execute_outputs->clear();
|
|
|
|
+ execute_outputs->set_scroll_follow(true);
|
|
|
|
+ execute_output_dialog->attach_and_popup_centered_ratio();
|
|
|
|
+ }
|
|
|
|
|
|
ExecuteThreadArgs eta;
|
|
ExecuteThreadArgs eta;
|
|
eta.path = p_path;
|
|
eta.path = p_path;
|
|
@@ -6571,6 +6657,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
|
|
String to_add = eta.output.substr(prev_len, eta.output.length());
|
|
String to_add = eta.output.substr(prev_len, eta.output.length());
|
|
prev_len = eta.output.length();
|
|
prev_len = eta.output.length();
|
|
execute_outputs->add_text(to_add);
|
|
execute_outputs->add_text(to_add);
|
|
|
|
+ DisplayServer::get_singleton()->process_events(); // Get rid of pending events.
|
|
Main::iteration();
|
|
Main::iteration();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -6580,14 +6667,16 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
|
|
eta.execute_output_thread.wait_to_finish();
|
|
eta.execute_output_thread.wait_to_finish();
|
|
execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode));
|
|
execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode));
|
|
|
|
|
|
- if (p_close_on_errors && eta.exitcode != 0) {
|
|
|
|
- execute_output_dialog->hide();
|
|
|
|
- }
|
|
|
|
- if (p_close_on_ok && eta.exitcode == 0) {
|
|
|
|
- execute_output_dialog->hide();
|
|
|
|
- }
|
|
|
|
|
|
+ if (execute_output_dialog) {
|
|
|
|
+ if (p_close_on_errors && eta.exitcode != 0) {
|
|
|
|
+ execute_output_dialog->hide();
|
|
|
|
+ }
|
|
|
|
+ if (p_close_on_ok && eta.exitcode == 0) {
|
|
|
|
+ execute_output_dialog->hide();
|
|
|
|
+ }
|
|
|
|
|
|
- execute_output_dialog->get_ok_button()->set_disabled(false);
|
|
|
|
|
|
+ execute_output_dialog->get_ok_button()->set_disabled(false);
|
|
|
|
+ }
|
|
|
|
|
|
return eta.exitcode;
|
|
return eta.exitcode;
|
|
}
|
|
}
|
|
@@ -7158,12 +7247,10 @@ EditorNode::EditorNode() {
|
|
prev_scene->set_position(Point2(3, 24));
|
|
prev_scene->set_position(Point2(3, 24));
|
|
prev_scene->hide();
|
|
prev_scene->hide();
|
|
|
|
|
|
- accept = memnew(AcceptDialog);
|
|
|
|
- gui_base->add_child(accept);
|
|
|
|
|
|
+ accept = memnew(AcceptDialogAutoReparent);
|
|
accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current));
|
|
accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_confirm_current));
|
|
|
|
|
|
- save_accept = memnew(AcceptDialog);
|
|
|
|
- gui_base->add_child(save_accept);
|
|
|
|
|
|
+ save_accept = memnew(AcceptDialogAutoReparent);
|
|
save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind((int)MenuOptions::FILE_SAVE_AS_SCENE));
|
|
save_accept->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind((int)MenuOptions::FILE_SAVE_AS_SCENE));
|
|
|
|
|
|
project_export = memnew(ProjectExportDialog);
|
|
project_export = memnew(ProjectExportDialog);
|
|
@@ -7208,9 +7295,8 @@ EditorNode::EditorNode() {
|
|
gui_base->add_child(fbx_importer_manager);
|
|
gui_base->add_child(fbx_importer_manager);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- warning = memnew(AcceptDialog);
|
|
|
|
|
|
+ warning = memnew(AcceptDialogAutoReparent);
|
|
warning->add_button(TTR("Copy Text"), true, "copy");
|
|
warning->add_button(TTR("Copy Text"), true, "copy");
|
|
- gui_base->add_child(warning);
|
|
|
|
warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning));
|
|
warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning));
|
|
|
|
|
|
ED_SHORTCUT("editor/next_tab", TTR("Next Scene Tab"), KeyModifierMask::CMD_OR_CTRL + Key::TAB);
|
|
ED_SHORTCUT("editor/next_tab", TTR("Next Scene Tab"), KeyModifierMask::CMD_OR_CTRL + Key::TAB);
|
|
@@ -7978,17 +8064,15 @@ EditorNode::EditorNode() {
|
|
set_process_shortcut_input(true);
|
|
set_process_shortcut_input(true);
|
|
|
|
|
|
load_errors = memnew(RichTextLabel);
|
|
load_errors = memnew(RichTextLabel);
|
|
- load_error_dialog = memnew(AcceptDialog);
|
|
|
|
|
|
+ load_error_dialog = memnew(AcceptDialogAutoReparent);
|
|
load_error_dialog->add_child(load_errors);
|
|
load_error_dialog->add_child(load_errors);
|
|
load_error_dialog->set_title(TTR("Load Errors"));
|
|
load_error_dialog->set_title(TTR("Load Errors"));
|
|
- gui_base->add_child(load_error_dialog);
|
|
|
|
|
|
|
|
execute_outputs = memnew(RichTextLabel);
|
|
execute_outputs = memnew(RichTextLabel);
|
|
execute_outputs->set_selection_enabled(true);
|
|
execute_outputs->set_selection_enabled(true);
|
|
- execute_output_dialog = memnew(AcceptDialog);
|
|
|
|
|
|
+ execute_output_dialog = memnew(AcceptDialogAutoReparent);
|
|
execute_output_dialog->add_child(execute_outputs);
|
|
execute_output_dialog->add_child(execute_outputs);
|
|
execute_output_dialog->set_title("");
|
|
execute_output_dialog->set_title("");
|
|
- gui_base->add_child(execute_output_dialog);
|
|
|
|
|
|
|
|
EditorFileSystem::get_singleton()->connect("sources_changed", callable_mp(this, &EditorNode::_sources_changed));
|
|
EditorFileSystem::get_singleton()->connect("sources_changed", callable_mp(this, &EditorNode::_sources_changed));
|
|
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorNode::_fs_changed));
|
|
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorNode::_fs_changed));
|