From 77fb65debff5df719709a7f0f5b1047ab13e46af Mon Sep 17 00:00:00 2001 From: Hendrik Brucker Date: Thu, 3 Feb 2022 01:21:52 +0100 Subject: [PATCH] Use EditorFileDialog instead of FileDialog in the project manager --- core/config/engine.h | 7 ++ core/string/translation.cpp | 2 +- editor/editor_file_dialog.cpp | 154 ++++++++++++++++++++----------- editor/editor_file_dialog.h | 24 +++-- editor/editor_paths.cpp | 2 +- editor/editor_settings.cpp | 33 +++++-- editor/editor_settings.h | 2 +- editor/project_manager.cpp | 52 ++++++++--- editor/project_manager.h | 7 +- main/main.cpp | 9 +- main/main.h | 1 - modules/mono/mono_gd/gd_mono.cpp | 14 +-- 12 files changed, 206 insertions(+), 101 deletions(-) diff --git a/core/config/engine.h b/core/config/engine.h index 65ca58ba1a8..1adab9b96f3 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -72,6 +72,7 @@ private: Map singleton_ptrs; bool editor_hint = false; + bool project_manager_hint = false; static Engine *singleton; @@ -119,9 +120,15 @@ public: #ifdef TOOLS_ENABLED _FORCE_INLINE_ void set_editor_hint(bool p_enabled) { editor_hint = p_enabled; } _FORCE_INLINE_ bool is_editor_hint() const { return editor_hint; } + + _FORCE_INLINE_ void set_project_manager_hint(bool p_enabled) { project_manager_hint = p_enabled; } + _FORCE_INLINE_ bool is_project_manager_hint() const { return project_manager_hint; } #else _FORCE_INLINE_ void set_editor_hint(bool p_enabled) {} _FORCE_INLINE_ bool is_editor_hint() const { return false; } + + _FORCE_INLINE_ void set_project_manager_hint(bool p_enabled) {} + _FORCE_INLINE_ bool is_project_manager_hint() const { return false; } #endif Dictionary get_version_info() const; diff --git a/core/string/translation.cpp b/core/string/translation.cpp index eeac8b0acf6..811ae95e9fc 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -685,7 +685,7 @@ Ref TranslationServer::get_tool_translation() const { String TranslationServer::get_tool_locale() { #ifdef TOOLS_ENABLED - if (TranslationServer::get_singleton()->get_tool_translation().is_valid() && (Engine::get_singleton()->is_editor_hint() || Main::is_project_manager())) { + if (TranslationServer::get_singleton()->get_tool_translation().is_valid() && (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint())) { return tool_translation->get_locale(); } else { #else diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 74e02609f9f..bda026e16c8 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -70,24 +70,7 @@ VBoxContainer *EditorFileDialog::get_vbox() { void EditorFileDialog::_notification(int p_what) { if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED || p_what == Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { - // Update icons. - mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); - mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); - if (is_layout_rtl()) { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - } else { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - } - dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); - show_hidden->set_icon(item_list->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); - - fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); - fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); - + _update_icons(); } else if (p_what == NOTIFICATION_PROCESS) { if (preview_waiting) { preview_wheel_timeout -= get_process_delta_time(); @@ -109,22 +92,7 @@ void EditorFileDialog::_notification(int p_what) { } set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); - // Update icons. - mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); - mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); - if (is_layout_rtl()) { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - } else { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - } - dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); - - fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); - fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); + _update_icons(); // DO NOT CALL UPDATE FILE LIST HERE, ALL HUNDREDS OF HIDDEN DIALOGS WILL RESPOND, CALL INVALIDATE INSTEAD invalidate(); } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { @@ -312,7 +280,7 @@ void EditorFileDialog::_post_popup() { const Color folder_color = item_list->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); recent->clear(); - bool res = access == ACCESS_RESOURCES; + bool res = (access == ACCESS_RESOURCES); Vector recentd = EditorSettings::get_singleton()->get_recent_dirs(); for (int i = 0; i < recentd.size(); i++) { bool cres = recentd[i].begins_with("res://"); @@ -384,7 +352,7 @@ void EditorFileDialog::_thumbnail_done(const String &p_path, const Refset_item_metadata(item_list->get_item_count() - 1, d); - if (display_mode == DISPLAY_THUMBNAILS) { + if (display_mode == DISPLAY_THUMBNAILS && previews_enabled) { EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath, this, "_thumbnail_result", fullpath); } @@ -1118,9 +1086,12 @@ void EditorFileDialog::_make_dir_confirm() { update_filters(); update_dir(); _push_history(); - EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes + if (access != ACCESS_FILESYSTEM) { + EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes + } } else { - mkdirerr->popup_centered(Size2(250, 50) * EDSCALE); + error_dialog->set_text(TTR("Could not create folder.")); + error_dialog->popup_centered(Size2(250, 50) * EDSCALE); } makedirname->set_text(""); // reset label } @@ -1146,11 +1117,28 @@ void EditorFileDialog::_delete_items() { } } if (folders.size() + files.size() > 0) { - remove_dialog->reset_size(); - remove_dialog->show(folders, files); + if (access == ACCESS_FILESYSTEM) { + global_remove_dialog->popup_centered(); + } else { + dep_remove_dialog->reset_size(); + dep_remove_dialog->show(folders, files); + } } } +void EditorFileDialog::_delete_files_global() { + // Delete files outside of the project directory without dependency checks. + for (int i = 0; i < item_list->get_item_count(); i++) { + if (!item_list->is_selected(i)) { + continue; + } + Dictionary item_meta = item_list->get_item_metadata(i); + // Only delete empty directories for safety. + dir_access->remove(item_meta["path"]); + } + update_file_list(); +} + void EditorFileDialog::_select_drive(int p_idx) { String d = drives->get_item_text(p_idx); dir_access->change_dir(d); @@ -1184,11 +1172,60 @@ void EditorFileDialog::_update_drives(bool p_select) { } } +void EditorFileDialog::_update_icons() { + // Update icons. + mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); + mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); + if (is_layout_rtl()) { + dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + } else { + dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + } + dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); + refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); + favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); + show_hidden->set_icon(item_list->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); + + fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); + fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); +} + void EditorFileDialog::_favorite_selected(int p_idx) { - dir_access->change_dir(favorites->get_item_metadata(p_idx)); - update_dir(); - invalidate(); - _push_history(); + Error change_dir_result = dir_access->change_dir(favorites->get_item_metadata(p_idx)); + if (change_dir_result != OK) { + error_dialog->set_text(TTR("Favorited folder does not exist anymore and will be removed.")); + error_dialog->popup_centered(Size2(250, 50) * EDSCALE); + + bool res = (access == ACCESS_RESOURCES); + + Vector favorited = EditorSettings::get_singleton()->get_favorites(); + String dir_to_remove = favorites->get_item_metadata(p_idx); + + bool found = false; + for (int i = 0; i < favorited.size(); i++) { + bool cres = favorited[i].begins_with("res://"); + if (cres != res) { + continue; + } + + if (favorited[i] == dir_to_remove) { + found = true; + break; + } + } + + if (found) { + favorited.erase(favorites->get_item_metadata(p_idx)); + favorites->remove_item(p_idx); + EditorSettings::get_singleton()->set_favorites(favorited); + } + } else { + update_dir(); + invalidate(); + _push_history(); + } } void EditorFileDialog::_favorite_move_up() { @@ -1234,7 +1271,7 @@ void EditorFileDialog::_favorite_move_down() { } void EditorFileDialog::_update_favorites() { - bool res = access == ACCESS_RESOURCES; + bool res = (access == ACCESS_RESOURCES); String current = get_current_dir(); Ref folder_icon = item_list->get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")); @@ -1283,7 +1320,7 @@ void EditorFileDialog::_update_favorites() { } void EditorFileDialog::_favorite_pressed() { - bool res = access == ACCESS_RESOURCES; + bool res = (access == ACCESS_RESOURCES); String cd = get_current_dir(); if (!cd.ends_with("/")) { @@ -1495,6 +1532,14 @@ bool EditorFileDialog::is_overwrite_warning_disabled() const { return disable_overwrite_warning; } +void EditorFileDialog::set_previews_enabled(bool p_enabled) { + previews_enabled = p_enabled; +} + +bool EditorFileDialog::are_previews_enabled() { + return previews_enabled; +} + EditorFileDialog::EditorFileDialog() { show_hidden_files = default_show_hidden_files; display_mode = default_display_mode; @@ -1728,8 +1773,13 @@ EditorFileDialog::EditorFileDialog() { add_child(confirm_save); confirm_save->connect("confirmed", callable_mp(this, &EditorFileDialog::_save_confirm_pressed)); - remove_dialog = memnew(DependencyRemoveDialog); - add_child(remove_dialog); + dep_remove_dialog = memnew(DependencyRemoveDialog); + add_child(dep_remove_dialog); + + global_remove_dialog = memnew(ConfirmationDialog); + global_remove_dialog->set_text(TTR("Remove the selected files? For safety only files and empty directories can be deleted from here. (Cannot be undone.)\nDepending on your filesystem configuration, the files will either be moved to the system trash or deleted permanently.")); + global_remove_dialog->connect("confirmed", callable_mp(this, &EditorFileDialog::_delete_files_global)); + add_child(global_remove_dialog); makedialog = memnew(ConfirmationDialog); makedialog->set_title(TTR("Create Folder")); @@ -1742,9 +1792,8 @@ EditorFileDialog::EditorFileDialog() { add_child(makedialog); makedialog->register_text_enter(makedirname); makedialog->connect("confirmed", callable_mp(this, &EditorFileDialog::_make_dir_confirm)); - mkdirerr = memnew(AcceptDialog); - mkdirerr->set_text(TTR("Could not create folder.")); - add_child(mkdirerr); + error_dialog = memnew(AcceptDialog); + add_child(error_dialog); update_filters(); update_dir(); @@ -1757,6 +1806,7 @@ EditorFileDialog::EditorFileDialog() { register_func(this); } + previews_enabled = true; preview_wheel_timeout = 0; preview_wheel_index = 0; preview_waiting = false; diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index 6cfdf537804..65a4c9e5440 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -32,6 +32,7 @@ #define EDITORFILEDIALOG_H #include "core/io/dir_access.h" +#include "editor/plugins/editor_preview_plugins.h" #include "scene/gui/box_container.h" #include "scene/gui/dialogs.h" #include "scene/gui/item_list.h" @@ -88,7 +89,7 @@ private: Button *makedir; Access access; - //Button *action; + VBoxContainer *vbox; FileMode mode; bool can_create_dir; @@ -109,10 +110,11 @@ private: HBoxContainer *file_box; LineEdit *file; OptionButton *filter; - AcceptDialog *mkdirerr; + AcceptDialog *error_dialog; DirAccess *dir_access; ConfirmationDialog *confirm_save; - DependencyRemoveDialog *remove_dialog; + DependencyRemoveDialog *dep_remove_dialog; + ConfirmationDialog *global_remove_dialog; Button *mode_thumbnails; Button *mode_list; @@ -133,9 +135,11 @@ private: Vector filters; + bool previews_enabled; bool preview_waiting; int preview_wheel_index; float preview_wheel_timeout; + static bool default_show_hidden_files; static DisplayMode default_display_mode; bool show_hidden_files; @@ -179,8 +183,10 @@ private: void _make_dir_confirm(); void _delete_items(); + void _delete_files_global(); void _update_drives(bool p_select = true); + void _update_icons(); void _go_up(); void _go_back(); @@ -189,7 +195,7 @@ private: virtual void _post_popup() override; void _save_to_recent(); - //callback function is callback(String p_path,Ref preview,Variant udata) preview null if could not load + // Callback function is callback(String p_path,Ref preview,Variant udata) preview null if could not load. void _thumbnail_result(const String &p_path, const Ref &p_preview, const Ref &p_small_preview, const Variant &p_udata); void _thumbnail_done(const String &p_path, const Ref &p_preview, const Ref &p_small_preview, const Variant &p_udata); @@ -202,7 +208,7 @@ private: protected: void _notification(int p_what); static void _bind_methods(); - //bind helpers + public: void popup_file_dialog(); void clear_filters(); @@ -230,17 +236,19 @@ public: void set_access(Access p_access); Access get_access() const; - void set_show_hidden_files(bool p_show); - bool is_showing_hidden_files() const; - static void set_default_show_hidden_files(bool p_show); static void set_default_display_mode(DisplayMode p_mode); + void set_show_hidden_files(bool p_show); + bool is_showing_hidden_files() const; void invalidate(); void set_disable_overwrite_warning(bool p_disable); bool is_overwrite_warning_disabled() const; + void set_previews_enabled(bool p_enabled); + bool are_previews_enabled(); + EditorFileDialog(); ~EditorFileDialog(); }; diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index d4e40db406d..c2092384472 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -193,7 +193,7 @@ EditorPaths::EditorPaths() { // Validate or create project-specific editor data dir, // including shader cache subdir. - if (Main::is_project_manager() || Main::is_cmdline_tool()) { + if (Engine::get_singleton()->is_project_manager_hint() || Main::is_cmdline_tool()) { // Nothing to create, use shared editor data dir for shader cache. Engine::get_singleton()->set_shader_cache_path(data_dir); } else { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index f230a9b4353..0c3f7287a50 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -845,7 +845,7 @@ void EditorSettings::create() { singleton->setup_language(); singleton->setup_network(); - singleton->load_favorites(); + singleton->load_favorites_and_recent_dirs(); singleton->list_text_editor_themes(); return; @@ -1103,7 +1103,13 @@ Variant EditorSettings::get_project_metadata(const String &p_section, const Stri void EditorSettings::set_favorites(const Vector &p_favorites) { favorites = p_favorites; - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::WRITE); + String favorites_file; + if (Engine::get_singleton()->is_project_manager_hint()) { + favorites_file = EditorPaths::get_singleton()->get_config_dir().plus_file("favorite_dirs"); + } else { + favorites_file = get_project_settings_dir().plus_file("favorites"); + } + FileAccess *f = FileAccess::open(favorites_file, FileAccess::WRITE); if (f) { for (int i = 0; i < favorites.size(); i++) { f->store_line(favorites[i]); @@ -1118,7 +1124,13 @@ Vector EditorSettings::get_favorites() const { void EditorSettings::set_recent_dirs(const Vector &p_recent_dirs) { recent_dirs = p_recent_dirs; - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::WRITE); + String recent_dirs_file; + if (Engine::get_singleton()->is_project_manager_hint()) { + recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().plus_file("recent_dirs"); + } else { + recent_dirs_file = get_project_settings_dir().plus_file("recent_dirs"); + } + FileAccess *f = FileAccess::open(recent_dirs_file, FileAccess::WRITE); if (f) { for (int i = 0; i < recent_dirs.size(); i++) { f->store_line(recent_dirs[i]); @@ -1131,8 +1143,17 @@ Vector EditorSettings::get_recent_dirs() const { return recent_dirs; } -void EditorSettings::load_favorites() { - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::READ); +void EditorSettings::load_favorites_and_recent_dirs() { + String favorites_file; + String recent_dirs_file; + if (Engine::get_singleton()->is_project_manager_hint()) { + favorites_file = EditorPaths::get_singleton()->get_config_dir().plus_file("favorite_dirs"); + recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().plus_file("recent_dirs"); + } else { + favorites_file = get_project_settings_dir().plus_file("favorites"); + recent_dirs_file = get_project_settings_dir().plus_file("recent_dirs"); + } + FileAccess *f = FileAccess::open(favorites_file, FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (!line.is_empty()) { @@ -1142,7 +1163,7 @@ void EditorSettings::load_favorites() { memdelete(f); } - f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::READ); + f = FileAccess::open(recent_dirs_file, FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (!line.is_empty()) { diff --git a/editor/editor_settings.h b/editor/editor_settings.h index f1a0329d65d..078abcb4d9e 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -161,7 +161,7 @@ public: Vector get_favorites() const; void set_recent_dirs(const Vector &p_recent_dirs); Vector get_recent_dirs() const; - void load_favorites(); + void load_favorites_and_recent_dirs(); bool is_dark_theme(); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 4dfa310e085..1cd13e10c8b 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -41,6 +41,7 @@ #include "core/os/os.h" #include "core/string/translation.h" #include "core/version.h" +#include "editor/editor_file_dialog.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_themes.h" @@ -100,8 +101,8 @@ private: LineEdit *install_path; TextureRect *status_rect; TextureRect *install_status_rect; - FileDialog *fdialog; - FileDialog *fdialog_install; + EditorFileDialog *fdialog; + EditorFileDialog *fdialog_install; OptionButton *vcs_metadata_selection; String zip_path; String zip_title; @@ -365,19 +366,19 @@ private: fdialog->set_current_dir(project_path->get_text()); if (mode == MODE_IMPORT) { - fdialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); + fdialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); fdialog->clear_filters(); fdialog->add_filter(vformat("project.godot ; %s %s", VERSION_NAME, TTR("Project"))); fdialog->add_filter("*.zip ; " + TTR("ZIP File")); } else { - fdialog->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + fdialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); } fdialog->popup_file_dialog(); } void _browse_install_path() { fdialog_install->set_current_dir(install_path->get_text()); - fdialog_install->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + fdialog_install->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); fdialog_install->popup_file_dialog(); } @@ -925,12 +926,15 @@ public: spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); default_files_container->add_child(spacer); - fdialog = memnew(FileDialog); - fdialog->set_access(FileDialog::ACCESS_FILESYSTEM); - fdialog_install = memnew(FileDialog); - fdialog_install->set_access(FileDialog::ACCESS_FILESYSTEM); + fdialog = memnew(EditorFileDialog); + fdialog->set_previews_enabled(false); //Crucial, otherwise the engine crashes. + fdialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + fdialog_install = memnew(EditorFileDialog); + fdialog_install->set_previews_enabled(false); //Crucial, otherwise the engine crashes. + fdialog_install->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(fdialog); add_child(fdialog_install); + project_name->connect("text_changed", callable_mp(this, &ProjectDialog::_text_changed)); project_path->connect("text_changed", callable_mp(this, &ProjectDialog::_path_text_changed)); install_path->connect("text_changed", callable_mp(this, &ProjectDialog::_path_text_changed)); @@ -1904,6 +1908,23 @@ void ProjectManager::_notification(int p_what) { } } +Map> ProjectManager::icon_type_cache; + +Ref ProjectManager::_file_dialog_get_icon(const String &p_path) { + return icon_type_cache["ObjectHR"]; +} + +void ProjectManager::_build_icon_type_cache(Ref p_theme) { + List tl; + p_theme->get_icon_list(SNAME("EditorIcons"), &tl); + for (List::Element *E = tl.front(); E; E = E->next()) { + if (!ClassDB::class_exists(E->get())) { + continue; + } + icon_type_cache[E->get()] = p_theme->get_icon(E->get(), SNAME("EditorIcons")); + } +} + void ProjectManager::_dim_window() { // This method must be called before calling `get_tree()->quit()`. // Otherwise, its effect won't be visible @@ -2510,12 +2531,14 @@ ProjectManager::ProjectManager() { float scale_factor = MAX(1, EDSCALE); Vector2i window_size = DisplayServer::get_singleton()->window_get_size(); DisplayServer::get_singleton()->window_set_size(Vector2i(window_size.x * scale_factor, window_size.y * scale_factor)); + + EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon; } // TRANSLATORS: This refers to the application where users manage their Godot projects. DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager")); - FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); set_anchors_and_offsets_preset(Control::PRESET_WIDE); set_theme(create_custom_theme()); @@ -2746,9 +2769,10 @@ ProjectManager::ProjectManager() { language_restart_ask->get_cancel_button()->set_text(TTR("Continue")); add_child(language_restart_ask); - scan_dir = memnew(FileDialog); - scan_dir->set_access(FileDialog::ACCESS_FILESYSTEM); - scan_dir->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + scan_dir = memnew(EditorFileDialog); + scan_dir->set_previews_enabled(false); + scan_dir->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + scan_dir->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden scan_dir->set_current_dir(EditorSettings::get_singleton()->get("filesystem/directories/default_project_path")); add_child(scan_dir); @@ -2812,6 +2836,8 @@ ProjectManager::ProjectManager() { about = memnew(EditorAbout); add_child(about); + + _build_icon_type_cache(get_theme()); } _load_recent_projects(); diff --git a/editor/project_manager.h b/editor/project_manager.h index f99e8796649..d3cd929eb75 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -50,6 +50,9 @@ enum FilterOption { class ProjectManager : public Control { GDCLASS(ProjectManager, Control); + static Map> icon_type_cache; + static void _build_icon_type_cache(Ref p_theme); + TabContainer *tabs; ProjectList *_project_list; @@ -67,7 +70,7 @@ class ProjectManager : public Control { EditorAssetLibrary *asset_library; - FileDialog *scan_dir; + EditorFileDialog *scan_dir; ConfirmationDialog *language_restart_ask; ConfirmationDialog *erase_ask; @@ -129,6 +132,8 @@ class ProjectManager : public Control { void _on_tab_changed(int p_tab); void _on_search_term_changed(const String &p_term); + static Ref _file_dialog_get_icon(const String &p_path); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/main/main.cpp b/main/main.cpp index 1efe3ccd945..bfe560fa319 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -182,13 +182,6 @@ bool profile_gpu = false; /* Helper methods */ -// Used by Mono module, should likely be registered in Engine singleton instead -// FIXME: This is also not 100% accurate, `project_manager` is only true when it was requested, -// but not if e.g. we fail to load and project and fallback to the manager. -bool Main::is_project_manager() { - return project_manager; -} - bool Main::is_cmdline_tool() { return cmdline_tool; } @@ -934,7 +927,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph editor = true; } else if (I->get() == "-p" || I->get() == "--project-manager") { // starts project manager - project_manager = true; } else if (I->get() == "--debug-server") { if (I->next()) { @@ -2548,6 +2540,7 @@ bool Main::start() { #ifdef TOOLS_ENABLED if (project_manager) { Engine::get_singleton()->set_editor_hint(true); + Engine::get_singleton()->set_project_manager_hint(true); ProjectManager *pmanager = memnew(ProjectManager); ProgressDialog *progress_dialog = memnew(ProgressDialog); pmanager->add_child(progress_dialog); diff --git a/main/main.h b/main/main.h index 9728d8a5aa0..cec31545c76 100644 --- a/main/main.h +++ b/main/main.h @@ -45,7 +45,6 @@ class Main { static bool agile_input_event_flushing; public: - static bool is_project_manager(); static bool is_cmdline_tool(); static int test_entrypoint(int argc, char *argv[], bool &tests_need_run); static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 6f542a67e74..a7269d7f872 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -52,10 +52,6 @@ #include "gd_mono_marshal.h" #include "gd_mono_utils.h" -#ifdef TOOLS_ENABLED -#include "main/main.h" -#endif - #ifdef ANDROID_ENABLED #include "android_mono_config.h" #include "support/android_support.h" @@ -143,7 +139,7 @@ void gd_mono_debug_init() { if (Engine::get_singleton()->is_editor_hint() || ProjectSettings::get_singleton()->get_resource_path().is_empty() || - Main::is_project_manager()) { + Engine::get_singleton()->is_project_manager_hint()) { if (da_args.size() == 0) { return; } @@ -423,7 +419,7 @@ void GDMono::initialize_load_assemblies() { bool tool_assemblies_loaded = _load_tools_assemblies(); CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies."); - if (Main::is_project_manager()) { + if (Engine::get_singleton()->is_project_manager_hint()) { return; } #endif @@ -815,7 +811,7 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // If running the project manager, load it from the prebuilt API directory - String assembly_dir = !Main::is_project_manager() + String assembly_dir = !Engine::get_singleton()->is_project_manager_hint() ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); @@ -848,7 +844,7 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // If running the project manager, load it from the prebuilt API directory - String assembly_dir = !Main::is_project_manager() + String assembly_dir = !Engine::get_singleton()->is_project_manager_hint() ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); @@ -932,7 +928,7 @@ void GDMono::_load_api_assemblies() { // this time update them from the prebuilt assemblies directory before trying to load them again. // Shouldn't happen. The project manager loads the prebuilt API assemblies - CRASH_COND_MSG(Main::is_project_manager(), "Failed to load one of the prebuilt API assemblies."); + CRASH_COND_MSG(Engine::get_singleton()->is_project_manager_hint(), "Failed to load one of the prebuilt API assemblies."); // 1. Unload the scripts domain Error domain_unload_err = _unload_scripts_domain();