diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/debugger/script_editor_debugger.cpp | 19 | ||||
-rw-r--r-- | editor/dependency_editor.cpp | 4 | ||||
-rw-r--r-- | editor/editor_export.cpp | 3 | ||||
-rw-r--r-- | editor/editor_node.cpp | 59 | ||||
-rw-r--r-- | editor/editor_themes.cpp | 3 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 2 | ||||
-rw-r--r-- | editor/import/resource_importer_texture.cpp | 2 | ||||
-rw-r--r-- | editor/project_export.cpp | 53 | ||||
-rw-r--r-- | editor/project_export.h | 2 | ||||
-rw-r--r-- | editor/project_manager.cpp | 56 | ||||
-rw-r--r-- | editor/project_manager.h | 1 |
11 files changed, 150 insertions, 54 deletions
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 248073c5a2..fd33115cda 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -487,8 +487,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da error->set_text_align(0, TreeItem::ALIGN_LEFT); String error_title; - // Include method name, when given, in error title. - if (!oe.source_func.empty()) { + if (oe.callstack.size() > 0) { + // If available, use the script's stack in the error title. + error_title = oe.callstack[oe.callstack.size() - 1].func + ": "; + } else if (!oe.source_func.empty()) { + // Otherwise try to use the C++ source function. error_title += oe.source_func + ": "; } // If we have a (custom) error message, use it as title, and add a C++ Error @@ -529,9 +532,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da cpp_source->set_metadata(0, source_meta); } - error->set_tooltip(0, tooltip); - error->set_tooltip(1, tooltip); - // Format stack trace. // stack_items_count is the number of elements to parse, with 3 items per frame // of the stack trace (script, method, line). @@ -548,10 +548,17 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da stack_trace->set_text(0, "<" + TTR("Stack Trace") + ">"); stack_trace->set_text_align(0, TreeItem::ALIGN_LEFT); error->set_metadata(0, meta); + tooltip += TTR("Stack Trace:") + "\n"; } - stack_trace->set_text(1, infos[i].file.get_file() + ":" + itos(infos[i].line) + " @ " + infos[i].func + "()"); + + String frame_txt = infos[i].file.get_file() + ":" + itos(infos[i].line) + " @ " + infos[i].func + "()"; + tooltip += frame_txt + "\n"; + stack_trace->set_text(1, frame_txt); } + error->set_tooltip(0, tooltip); + error->set_tooltip(1, tooltip); + if (oe.warning) { warning_count++; } else { diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 5e87f866d8..527286583e 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -450,13 +450,13 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector< removed_deps.sort(); if (removed_deps.empty()) { owners->hide(); - text->set_text(TTR("Remove selected files from the project? (Can't be restored)")); + text->set_text(TTR("Remove selected files from the project? (no undo)\nYou can find the removed files in the system trash to restore them.")); set_size(Size2()); popup_centered(); } else { _build_removed_dependency_tree(removed_deps); owners->show(); - text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)")); + text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)\nYou can find the removed files in the system trash to restore them.")); popup_centered(Size2(500, 350)); } EditorFileSystem::get_singleton()->scan_changes(); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 97800fe961..3aeffede82 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -737,6 +737,9 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & _edit_filter_list(paths, p_preset->get_include_filter(), false); _edit_filter_list(paths, p_preset->get_exclude_filter(), true); + // Ignore import files, since these are automatically added to the jar later with the resources + _edit_filter_list(paths, String("*.import"), true); + // Get encryption filters. bool enc_pck = p_preset->get_enc_pck(); Vector<String> enc_in_filters; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index c6613cdf63..2e796b2dcd 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1679,7 +1679,7 @@ void EditorNode::_dialog_action(String p_file) { if (err == ERR_FILE_CANT_OPEN || err == ERR_FILE_NOT_FOUND) { config.instance(); // new config } else if (err != OK) { - show_warning(TTR("Error trying to save layout!")); + show_warning(TTR("An error occurred while trying to save the editor layout.\nMake sure the editor's user data path is writable.")); return; } @@ -1691,7 +1691,7 @@ void EditorNode::_dialog_action(String p_file) { _update_layouts_menu(); if (p_file == "Default") { - show_warning(TTR("Default editor layout overridden.")); + show_warning(TTR("Default editor layout overridden.\nTo restore the Default layout to its base settings, use the Delete Layout option and delete the Default layout.")); } } break; @@ -1722,7 +1722,7 @@ void EditorNode::_dialog_action(String p_file) { _update_layouts_menu(); if (p_file == "Default") { - show_warning(TTR("Restored default layout to base settings.")); + show_warning(TTR("Restored the Default layout to its base settings.")); } } break; @@ -5565,46 +5565,51 @@ EditorNode::EditorNode() { { int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale"); - float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale"); switch (display_scale) { case 0: { - // Try applying a suitable display scale automatically + // Try applying a suitable display scale automatically. #ifdef OSX_ENABLED editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale()); #else const int screen = DisplayServer::get_singleton()->window_get_current_screen(); - editor_set_scale(DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000 ? 2.0 : 1.0); + float scale; + if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) { + // hiDPI display. + scale = 2.0; + } else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) { + // Small loDPI display. Use a smaller display scale so that editor elements fit more easily. + // Icons won't look great, but this is better than having editor elements overflow from its window. + scale = 0.75; + } else { + scale = 1.0; + } + + editor_set_scale(scale); #endif } break; - case 1: { + case 1: editor_set_scale(0.75); - } break; - - case 2: { + break; + case 2: editor_set_scale(1.0); - } break; - - case 3: { + break; + case 3: editor_set_scale(1.25); - } break; - - case 4: { + break; + case 4: editor_set_scale(1.5); - } break; - - case 5: { + break; + case 5: editor_set_scale(1.75); - } break; - - case 6: { + break; + case 6: editor_set_scale(2.0); - } break; - - default: { - editor_set_scale(custom_display_scale); - } break; + break; + default: + editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale")); + break; } } diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 79525ced51..768e5bccbc 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -441,7 +441,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Highlighted tabs and border width Color tab_color = highlight_tabs ? base_color.lerp(font_color, contrast) : base_color; - const int border_width = CLAMP(border_size, 0, 3) * EDSCALE; + // Ensure borders are visible when using an editor scale below 100%. + const int border_width = CLAMP(border_size, 0, 3) * MAX(1, EDSCALE); const int default_margin_size = 4; const int margin_size_extra = default_margin_size + CLAMP(border_size, 0, 3); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index ee0ee91893..543546b152 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2363,7 +2363,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str if (p_paths.size() > 1 || p_paths[0] != "res://") { p_popup->add_icon_item(get_theme_icon("MoveUp", "EditorIcons"), TTR("Move To..."), FILE_MOVE); - p_popup->add_icon_item(get_theme_icon("Remove", "EditorIcons"), TTR("Delete"), FILE_REMOVE); + p_popup->add_icon_item(get_theme_icon("Remove", "EditorIcons"), TTR("Move to Trash"), FILE_REMOVE); } if (p_paths.size() == 1) { diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 3a0e624a8f..ac2485fe31 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -205,7 +205,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), (p_preset == PRESET_3D ? true : false))); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "roughness/mode", PROPERTY_HINT_ENUM, "Detect,Disabled,Red,Green,Blue,Alpha,Gray"), 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.png,*.jpg"), "")); + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.svgz,*.tga,*.webp"), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/invert_color"), false)); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index e8c2b1f954..75509c7544 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -721,14 +721,19 @@ void ProjectExportDialog::_fill_resource_tree() { } bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref<EditorExportPreset> ¤t, bool p_only_scenes) { + p_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); p_item->set_icon(0, presets->get_theme_icon("folder", "FileDialog")); p_item->set_text(0, p_dir->get_name() + "/"); + p_item->set_editable(0, true); + p_item->set_metadata(0, p_dir->get_path()); bool used = false; + bool checked = true; for (int i = 0; i < p_dir->get_subdir_count(); i++) { TreeItem *subdir = include_files->create_item(p_item); if (_fill_tree(p_dir->get_subdir(i), subdir, current, p_only_scenes)) { used = true; + checked = checked && subdir->is_checked(0); } else { memdelete(subdir); } @@ -750,10 +755,12 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem file->set_editable(0, true); file->set_checked(0, current->has_export_file(path)); file->set_metadata(0, path); + checked = checked && file->is_checked(0); used = true; } + p_item->set_checked(0, checked); return used; } @@ -775,13 +782,53 @@ void ProjectExportDialog::_tree_changed() { String path = item->get_metadata(0); bool added = item->is_checked(0); - if (added) { - current->add_export_file(path); + if (path.ends_with("/")) { + _check_dir_recursive(item, added); } else { - current->remove_export_file(path); + if (added) { + current->add_export_file(path); + } else { + current->remove_export_file(path); + } + } + _refresh_parent_checks(item); // Makes parent folder checked if all files/folders are checked. +} + +void ProjectExportDialog::_check_dir_recursive(TreeItem *p_dir, bool p_checked) { + for (TreeItem *child = p_dir->get_children(); child; child = child->get_next()) { + String path = child->get_metadata(0); + + child->set_checked(0, p_checked); + if (path.ends_with("/")) { + _check_dir_recursive(child, p_checked); + } else { + if (p_checked) { + get_current_preset()->add_export_file(path); + } else { + get_current_preset()->remove_export_file(path); + } + } } } +void ProjectExportDialog::_refresh_parent_checks(TreeItem *p_item) { + TreeItem *parent = p_item->get_parent(); + if (!parent) { + return; + } + + bool checked = true; + for (TreeItem *child = parent->get_children(); child; child = child->get_next()) { + checked = checked && child->is_checked(0); + if (!checked) { + break; + } + } + parent->set_checked(0, checked); + + _refresh_parent_checks(parent); +} + void ProjectExportDialog::_export_pck_zip() { export_pck_zip->popup_file_dialog(); } diff --git a/editor/project_export.h b/editor/project_export.h index 026daac2ad..b8ca0dd9f2 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -123,6 +123,8 @@ private: void _fill_resource_tree(); bool _fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref<EditorExportPreset> ¤t, bool p_only_scenes); void _tree_changed(); + void _check_dir_recursive(TreeItem *p_dir, bool p_checked); + void _refresh_parent_checks(TreeItem *p_item); Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index e3c2ba83f2..167cd3ac35 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -61,6 +61,7 @@ class ProjectDialog : public ConfirmationDialog { GDCLASS(ProjectDialog, ConfirmationDialog); public: + bool is_folder_empty = true; enum Mode { MODE_NEW, MODE_IMPORT, @@ -218,7 +219,7 @@ private: // check if the specified install folder is empty, even though this is not an error, it is good to check here d->list_dir_begin(); - bool is_empty = true; + is_folder_empty = true; String n = d->get_next(); while (n != String()) { if (!n.begins_with(".")) { @@ -226,14 +227,14 @@ private: // and hidden files/folders to be present. // For instance, this lets users initialize a Git repository // and still be able to create a project in the directory afterwards. - is_empty = false; + is_folder_empty = false; break; } n = d->get_next(); } d->list_dir_end(); - if (!is_empty) { + if (!is_folder_empty) { set_message(TTR("Please choose an empty folder."), MESSAGE_WARNING, INSTALL_PATH); memdelete(d); get_ok()->set_disabled(true); @@ -258,7 +259,7 @@ private: } else { // check if the specified folder is empty, even though this is not an error, it is good to check here d->list_dir_begin(); - bool is_empty = true; + is_folder_empty = true; String n = d->get_next(); while (n != String()) { if (!n.begins_with(".")) { @@ -266,18 +267,18 @@ private: // and hidden files/folders to be present. // For instance, this lets users initialize a Git repository // and still be able to create a project in the directory afterwards. - is_empty = false; + is_folder_empty = false; break; } n = d->get_next(); } d->list_dir_end(); - if (!is_empty) { - set_message(TTR("Please choose an empty folder."), MESSAGE_ERROR); + if (!is_folder_empty) { + set_message(TTR("The selected path is not empty. Choosing an empty folder is highly recommended."), MESSAGE_WARNING); memdelete(d); - get_ok()->set_disabled(true); - return ""; + get_ok()->set_disabled(false); + return valid_path; } } @@ -416,6 +417,11 @@ private: } } + void _nonempty_confirmation_ok_pressed() { + is_folder_empty = true; + ok_pressed(); + } + void ok_pressed() override { String dir = project_path->get_text(); @@ -454,6 +460,18 @@ private: } else { if (mode == MODE_NEW) { + // Before we create a project, check that the target folder is empty. + // If not, we need to ask the user if they're sure they want to do this. + if (!is_folder_empty) { + ConfirmationDialog *cd = memnew(ConfirmationDialog); + cd->set_title(TTR("Warning: This folder is not empty")); + cd->set_text(TTR("You are about to create a Godot project in a non-empty folder.\nThe entire contents of this folder will be imported as project resources!\n\nAre you sure you wish to continue?")); + cd->get_ok()->connect("pressed", callable_mp(this, &ProjectDialog::_nonempty_confirmation_ok_pressed)); + get_parent()->add_child(cd); + cd->popup_centered(); + cd->grab_focus(); + return; + } ProjectSettings::CustomMap initial_settings; if (rasterizer_button_group->get_pressed_button()->get_meta("driver_name") == "Vulkan") { initial_settings["rendering/quality/driver/driver_name"] = "Vulkan"; @@ -2348,12 +2366,24 @@ ProjectManager::ProjectManager() { switch (display_scale) { case 0: { - // Try applying a suitable display scale automatically + // Try applying a suitable display scale automatically. #ifdef OSX_ENABLED editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale()); #else const int screen = DisplayServer::get_singleton()->window_get_current_screen(); - editor_set_scale(DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).x > 2000 ? 2.0 : 1.0); + float scale; + if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) { + // hiDPI display. + scale = 2.0; + } else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) { + // Small loDPI display. Use a smaller display scale so that editor elements fit more easily. + // Icons won't look great, but this is better than having editor elements overflow from its window. + scale = 0.75; + } else { + scale = 1.0; + } + + editor_set_scale(scale); #endif } break; @@ -2375,9 +2405,9 @@ ProjectManager::ProjectManager() { case 6: editor_set_scale(2.0); break; - default: { + default: editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale")); - } break; + break; } // Define a minimum window size to prevent UI elements from overlapping or being cut off diff --git a/editor/project_manager.h b/editor/project_manager.h index 407dba0c94..212d693f1d 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -98,6 +98,7 @@ class ProjectManager : public Control { void _restart_confirm(); void _exit_dialog(); void _confirm_update_settings(); + void _nonempty_confirmation_ok_pressed(); void _load_recent_projects(); void _on_project_created(const String &dir); |