diff options
Diffstat (limited to 'editor/project_manager.cpp')
-rw-r--r-- | editor/project_manager.cpp | 168 |
1 files changed, 96 insertions, 72 deletions
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 6de4330493..4b3d468a61 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -294,13 +294,13 @@ private: String sp = _test_path(); if (sp != "") { - // set the project name to the select folder name - if (project_name->get_text() == "") { + // If the project name is empty or default, infer the project name from the selected folder name + if (project_name->get_text() == "" || project_name->get_text() == TTR("New Game Project")) { sp = sp.replace("\\", "/"); int lidx = sp.find_last("/"); if (lidx != -1) { - sp = sp.substr(lidx + 1, sp.length()); + sp = sp.substr(lidx + 1, sp.length()).capitalize(); } if (sp == "" && mode == MODE_IMPORT) sp = TTR("Imported Project"); @@ -919,28 +919,37 @@ public: struct ProjectItem { String project; + String project_name; String path; String conf; - int config_version; + String icon; + String main_scene; uint64_t last_modified; bool favorite; bool grayed; - bool ordered_latest_modification; + ProjectListFilter::FilterOption filter_order_option; ProjectItem() {} - ProjectItem(const String &p_project, const String &p_path, const String &p_conf, int p_config_version, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const bool p_ordered_latest_modification = true) { + ProjectItem(const String &p_project, const String &p_name, const String &p_path, const String &p_conf, const String &p_icon, const String &p_main_scene, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const ProjectListFilter::FilterOption p_filter_order_option = ProjectListFilter::FILTER_NAME) { project = p_project; + project_name = p_name; path = p_path; conf = p_conf; - config_version = p_config_version; + icon = p_icon; + main_scene = p_main_scene; last_modified = p_last_modified; favorite = p_favorite; grayed = p_grayed; - ordered_latest_modification = p_ordered_latest_modification; + filter_order_option = p_filter_order_option; } _FORCE_INLINE_ bool operator<(const ProjectItem &l) const { - if (ordered_latest_modification) - return last_modified > l.last_modified; - return project < l.project; + switch (filter_order_option) { + case ProjectListFilter::FILTER_PATH: + return project < l.project; + case ProjectListFilter::FILTER_MODIFIED: + return last_modified > l.last_modified; + default: + return project_name < l.project_name; + } } _FORCE_INLINE_ bool operator==(const ProjectItem &l) const { return project == l.project; } }; @@ -961,9 +970,25 @@ void ProjectManager::_notification(int p_what) { set_process_unhandled_input(is_visible_in_tree()); } break; + case NOTIFICATION_WM_QUIT_REQUEST: { + + _dim_window(); + } break; } } +void ProjectManager::_dim_window() { + + // This method must be called before calling `get_tree()->quit()`. + // Otherwise, its effect won't be visible + + // Dim the project manager window while it's quitting to make it clearer that it's busy. + // No transition is applied, as the effect needs to be visible immediately + float c = 1.0f - float(EDITOR_GET("interface/editor/dim_amount")); + Color dim_color = Color(c, c, c); + gui_base->set_modulate(dim_color); +} + void ProjectManager::_panel_draw(Node *p_hb) { HBoxContainer *hb = Object::cast_to<HBoxContainer>(p_hb); @@ -1240,13 +1265,7 @@ void ProjectManager::_load_recent_projects() { Color font_color = gui_base->get_color("font_color", "Tree"); - bool set_ordered_latest_modification; ProjectListFilter::FilterOption filter_order_option = project_order_filter->get_filter_option(); - if (filter_order_option == ProjectListFilter::FILTER_NAME) { - set_ordered_latest_modification = false; - } else { - set_ordered_latest_modification = true; - } EditorSettings::get_singleton()->set("project_manager/sorting_order", (int)filter_order_option); List<ProjectItem> projects; @@ -1264,10 +1283,30 @@ void ProjectManager::_load_recent_projects() { String project = _name.get_slice("/", 1); String conf = path.plus_file("project.godot"); - int config_version = 0; // Assume 0 until we know better bool favorite = (_name.begins_with("favorite_projects/")) ? true : false; bool grayed = false; + Ref<ConfigFile> cf = memnew(ConfigFile); + Error cf_err = cf->load(conf); + + int config_version = 0; + String project_name = TTR("Unnamed Project"); + if (cf_err == OK) { + + String cf_project_name = static_cast<String>(cf->get_value("application", "config/name", "")); + if (cf_project_name != "") + project_name = cf_project_name.xml_unescape(); + config_version = (int)cf->get_value("", "config_version", 0); + } + + if (config_version > ProjectSettings::CONFIG_VERSION) { + // Comes from an incompatible (more recent) Godot version, grey it out + grayed = true; + } + + String icon = cf->get_value("application", "config/icon", ""); + String main_scene = cf->get_value("application", "run/main_scene", ""); + uint64_t last_modified = 0; if (FileAccess::exists(conf)) { last_modified = FileAccess::get_modified_time(conf); @@ -1282,7 +1321,7 @@ void ProjectManager::_load_recent_projects() { grayed = true; } - ProjectItem item(project, path, conf, config_version, last_modified, favorite, grayed, set_ordered_latest_modification); + ProjectItem item(project, project_name, path, conf, icon, main_scene, last_modified, favorite, grayed, filter_order_option); if (favorite) favorite_projects.push_back(item); else @@ -1310,43 +1349,23 @@ void ProjectManager::_load_recent_projects() { String path = item.path; String conf = item.conf; - Ref<ConfigFile> cf = memnew(ConfigFile); - Error cf_err = cf->load(conf); - - String project_name = TTR("Unnamed Project"); - if (cf_err == OK && cf->has_section_key("application", "config/name")) { - project_name = static_cast<String>(cf->get_value("application", "config/name")).xml_unescape(); - } - - if (filter_option == ProjectListFilter::FILTER_NAME && search_term != "" && project_name.findn(search_term) == -1) + if (filter_option == ProjectListFilter::FILTER_NAME && search_term != "" && item.project_name.findn(search_term) == -1) continue; Ref<Texture> icon; - String main_scene; - if (cf_err == OK) { - item.config_version = (int)cf->get_value("", "config_version", 0); - if (item.config_version > ProjectSettings::CONFIG_VERSION) { - // Comes from an incompatible (more recent) Godot version, grey it out - item.grayed = true; + if (item.icon != "") { + Ref<Image> img; + img.instance(); + Error err = img->load(item.icon.replace_first("res://", path + "/")); + if (err == OK) { + + Ref<Texture> default_icon = get_icon("DefaultProjectIcon", "EditorIcons"); + img->resize(default_icon->get_width(), default_icon->get_height()); + Ref<ImageTexture> it = memnew(ImageTexture); + it->create_from_image(img); + icon = it; } - - String appicon = cf->get_value("application", "config/icon", ""); - if (appicon != "") { - Ref<Image> img; - img.instance(); - Error err = img->load(appicon.replace_first("res://", path + "/")); - if (err == OK) { - - Ref<Texture> default_icon = get_icon("DefaultProjectIcon", "EditorIcons"); - img->resize(default_icon->get_width(), default_icon->get_height()); - Ref<ImageTexture> it = memnew(ImageTexture); - it->create_from_image(img); - icon = it; - } - } - - main_scene = cf->get_value("application", "run/main_scene", ""); } if (icon.is_null()) { @@ -1360,7 +1379,7 @@ void ProjectManager::_load_recent_projects() { HBoxContainer *hb = memnew(HBoxContainer); hb->set_meta("name", project); - hb->set_meta("main_scene", main_scene); + hb->set_meta("main_scene", item.main_scene); hb->set_meta("favorite", is_favorite); hb->connect("draw", this, "_panel_draw", varray(hb)); hb->connect("gui_input", this, "_panel_input", varray(hb)); @@ -1390,7 +1409,7 @@ void ProjectManager::_load_recent_projects() { ec->set_custom_minimum_size(Size2(0, 1)); ec->set_mouse_filter(MOUSE_FILTER_PASS); vb->add_child(ec); - Label *title = memnew(Label(project_name)); + Label *title = memnew(Label(item.project_name)); title->add_font_override("font", gui_base->get_font("title", "EditorFonts")); title->add_color_override("font_color", font_color); title->set_clip_text(true); @@ -1514,6 +1533,7 @@ void ProjectManager::_open_selected_projects() { ERR_FAIL_COND(err); } + _dim_window(); get_tree()->quit(); } @@ -1627,40 +1647,28 @@ void ProjectManager::_show_project(const String &p_path) { OS::get_singleton()->shell_open(String("file://") + p_path); } -void ProjectManager::_scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects) { - - List<String> subdirs; +void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) { + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->change_dir(path); da->list_dir_begin(); String n = da->get_next(); while (n != String()) { if (da->current_is_dir() && !n.begins_with(".")) { - subdirs.push_front(n); + _scan_dir(da->get_current_dir().plus_file(n), r_projects); } else if (n == "project.godot") { r_projects->push_back(da->get_current_dir()); } n = da->get_next(); } da->list_dir_end(); - int m = 0; - for (List<String>::Element *E = subdirs.front(); E; E = E->next()) { - - da->change_dir(E->get()); - - float slice = total / subdirs.size(); - _scan_dir(da, pos + slice * m, slice, r_projects); - da->change_dir(".."); - m++; - } + memdelete(da); } void ProjectManager::_scan_begin(const String &p_base) { print_line("Scanning projects at: " + p_base); List<String> projects; - DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->change_dir(p_base); - _scan_dir(da, 0, 1, &projects); - memdelete(da); + _scan_dir(p_base, &projects); print_line("Found " + itos(projects.size()) + " projects."); for (List<String>::Element *E = projects.front(); E; E = E->next()) { @@ -1792,11 +1800,13 @@ void ProjectManager::_restart_confirm() { Error err = OS::get_singleton()->execute(exec, args, false, &pid); ERR_FAIL_COND(err); + _dim_window(); get_tree()->quit(); } void ProjectManager::_exit_dialog() { + _dim_window(); get_tree()->quit(); } @@ -1983,7 +1993,7 @@ ProjectManager::ProjectManager() { l = memnew(Label); String hash = String(VERSION_HASH); if (hash.length() != 0) - hash = "." + hash.left(7); + hash = "." + hash.left(9); l->set_text("v" VERSION_FULL_BUILD "" + hash); l->set_align(Label::ALIGN_CENTER); top_hb->add_child(l); @@ -2013,6 +2023,7 @@ ProjectManager::ProjectManager() { sort_filters->add_child(sort_label); Vector<String> sort_filter_titles; sort_filter_titles.push_back("Name"); + sort_filter_titles.push_back("Path"); sort_filter_titles.push_back("Last Modified"); project_order_filter = memnew(ProjectListFilter); project_order_filter->_setup_filters(sort_filter_titles); @@ -2166,6 +2177,19 @@ ProjectManager::ProjectManager() { Button *cancel = memnew(Button); cancel->set_text(TTR("Exit")); cancel->set_custom_minimum_size(Size2(100, 1) * EDSCALE); + +#ifndef OSX_ENABLED + // Pressing Command + Q quits the Project Manager + // This is handled by the platform implementation on macOS, + // so only define the shortcut on other platforms + InputEventKey *quit_key = memnew(InputEventKey); + quit_key->set_command(true); + quit_key->set_scancode(KEY_Q); + ShortCut *quit_shortcut = memnew(ShortCut); + quit_shortcut->set_shortcut(quit_key); + cancel->set_shortcut(quit_shortcut); +#endif + cc->add_child(cancel); cancel->connect("pressed", this, "_exit_dialog"); vb->add_child(cc); |