From d1ed959e9d79899c38908e63095092fc46837a52 Mon Sep 17 00:00:00 2001 From: Malcolm Anderson Date: Sat, 11 Oct 2025 13:53:02 -0700 Subject: [PATCH] Display icon next to project's Godot version in Project Manager if its version differs from current version Handle Godot 3.x projects Update editor/project_manager/project_list.h Add icons, major/minor recognition support, and note for downgrading Apply suggestions from code review # Conflicts: # editor/project_manager/project_list.h Update editor/project_manager/project_list.cpp Add convert option # Conflicts: # editor/project_manager/project_list.cpp Apply suggestions from code review Update editor/project_manager/project_list.cpp Use blue for upgrade and yellow for downgrade Remove "unknown version" case, move it to unsupported features/warning indicator Update editor/project_manager/project_list.h Co-authored-by: Geometror Co-authored-by: Tomasz Chabora Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> --- editor/icons/ProjectDowngrade.svg | 1 + editor/icons/ProjectDowngradeMajor.svg | 1 + editor/icons/ProjectUpgrade.svg | 1 + editor/icons/ProjectUpgradeMajor.svg | 1 + editor/project_manager/project_list.cpp | 85 +++++++++++++++++++++++-- editor/project_manager/project_list.h | 11 ++++ 6 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 editor/icons/ProjectDowngrade.svg create mode 100644 editor/icons/ProjectDowngradeMajor.svg create mode 100644 editor/icons/ProjectUpgrade.svg create mode 100644 editor/icons/ProjectUpgradeMajor.svg diff --git a/editor/icons/ProjectDowngrade.svg b/editor/icons/ProjectDowngrade.svg new file mode 100644 index 0000000000..34abaf97bc --- /dev/null +++ b/editor/icons/ProjectDowngrade.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/ProjectDowngradeMajor.svg b/editor/icons/ProjectDowngradeMajor.svg new file mode 100644 index 0000000000..dc59e033ae --- /dev/null +++ b/editor/icons/ProjectDowngradeMajor.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/ProjectUpgrade.svg b/editor/icons/ProjectUpgrade.svg new file mode 100644 index 0000000000..15e3dcca34 --- /dev/null +++ b/editor/icons/ProjectUpgrade.svg @@ -0,0 +1 @@ + diff --git a/editor/icons/ProjectUpgradeMajor.svg b/editor/icons/ProjectUpgradeMajor.svg new file mode 100644 index 0000000000..c37c629780 --- /dev/null +++ b/editor/icons/ProjectUpgradeMajor.svg @@ -0,0 +1 @@ + diff --git a/editor/project_manager/project_list.cpp b/editor/project_manager/project_list.cpp index 677c1228e1..5d4c70b801 100644 --- a/editor/project_manager/project_list.cpp +++ b/editor/project_manager/project_list.cpp @@ -71,6 +71,24 @@ void ProjectListItemControl::_notification(int p_what) { project_title->end_bulk_theme_override(); project_path->add_theme_color_override(SceneStringName(font_color), get_theme_color(SceneStringName(font_color), SNAME("ProjectList"))); + + switch (version_match_type) { + case VersionMatchType::PROJECT_USES_OLDER_MAJOR: + project_different_version->set_texture(get_editor_theme_icon(SNAME("ProjectUpgradeMajor"))); + break; + case VersionMatchType::PROJECT_USES_OLDER_MINOR: + project_different_version->set_texture(get_editor_theme_icon(SNAME("ProjectUpgrade"))); + break; + case VersionMatchType::PROJECT_USES_NEWER_MAJOR: + project_different_version->set_texture(get_editor_theme_icon(SNAME("ProjectDowngradeMajor"))); + break; + case VersionMatchType::PROJECT_USES_NEWER_MINOR: + project_different_version->set_texture(get_editor_theme_icon(SNAME("ProjectDowngrade"))); + break; + default: + break; + } + project_unsupported_features->set_texture(get_editor_theme_icon(SNAME("NodeWarning"))); favorite_focus_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); @@ -267,6 +285,7 @@ void ProjectListItemControl::set_project_version(const String &p_info) { void ProjectListItemControl::set_unsupported_features(PackedStringArray p_features) { if (p_features.size() > 0) { String tooltip_text = ""; + bool unknown_version = false; for (int i = 0; i < p_features.size(); i++) { if (ProjectList::project_feature_looks_like_version(p_features[i])) { PackedStringArray project_version_split = p_features[i].split("."); @@ -275,18 +294,67 @@ void ProjectListItemControl::set_unsupported_features(PackedStringArray p_featur project_version_major = project_version_split[0].to_int(); project_version_minor = project_version_split[1].to_int(); } - if (GODOT_VERSION_MAJOR != project_version_major || GODOT_VERSION_MINOR <= project_version_minor) { - // Don't show a warning if the project was last edited in a previous minor version. - tooltip_text += TTR("This project was last edited in a different Godot version: ") + p_features[i] + "\n"; + + version_match_type = VersionMatchType::PROJECT_USES_SAME; + if (project_version_major > GODOT_VERSION_MAJOR) { + version_match_type = VersionMatchType::PROJECT_USES_NEWER_MAJOR; + } else if (project_version_major < GODOT_VERSION_MAJOR) { + version_match_type = VersionMatchType::PROJECT_USES_OLDER_MAJOR; + } else { + // Project is same major version. + // Is it the same minor version, or an upgrade or downgrade? + if (project_version_minor > GODOT_VERSION_MINOR) { + version_match_type = VersionMatchType::PROJECT_USES_NEWER_MINOR; + } else if (project_version_minor < GODOT_VERSION_MINOR) { + version_match_type = VersionMatchType::PROJECT_USES_OLDER_MINOR; + } + } + + if (version_match_type != VersionMatchType::PROJECT_USES_SAME) { + String project_version_tooltip_text = TTR("This project was last edited in a different Godot version: ") + p_features[i] + "\n"; + if (version_match_type == VersionMatchType::PROJECT_USES_OLDER_MAJOR || version_match_type == VersionMatchType::PROJECT_USES_OLDER_MINOR) { + project_version_tooltip_text += vformat(TTR("Opening it will upgrade it to Godot %s.%s."), GODOT_VERSION_MAJOR, GODOT_VERSION_MINOR) + "\n"; + } else if (version_match_type == VersionMatchType::PROJECT_USES_NEWER_MAJOR || version_match_type == VersionMatchType::PROJECT_USES_NEWER_MINOR) { + project_version_tooltip_text += vformat(TTR("Opening it will downgrade it to Godot %s.%s."), GODOT_VERSION_MAJOR, GODOT_VERSION_MINOR) + "\n"; + project_version_tooltip_text += TTR("Downgrading projects is not recommended.") + "\n"; + } + project_different_version->set_focus_mode(FOCUS_ACCESSIBILITY); + project_different_version->set_tooltip_text(project_version_tooltip_text); + project_different_version->show(); + } else { + project_different_version->hide(); + } + } else { + if (p_features[i] == "3.x") { + version_match_type = VersionMatchType::PROJECT_USES_OLDER_MAJOR; + String project_version_tooltip_text = TTR("This project was last edited in a different Godot version: ") + p_features[i] + "\n"; + project_version_tooltip_text += vformat(TTR("Opening it will upgrade it to Godot %s.%s."), GODOT_VERSION_MAJOR, GODOT_VERSION_MINOR) + "\n"; + project_different_version->set_focus_mode(FOCUS_ACCESSIBILITY); + project_different_version->set_tooltip_text(project_version_tooltip_text); + project_different_version->show(); + } else if (p_features[i] == TTR("Unknown version")) { + unknown_version = true; + project_different_version->hide(); } - p_features.remove_at(i); - i--; } + + p_features.remove_at(i); + i--; + } + + // This is actually triggered when the project.godot file's config_version + // is less than 4, so perhaps it'd be more accurate to say the engine configuration + // file's version is not supported...? If the config/features array includes + // a proper version number, it will be displayed alongside the "unknown version" + // warning otherwise. + if (unknown_version) { + tooltip_text += TTR("This project uses an unknown version of Godot.") + "\n"; } if (p_features.size() > 0) { String unsupported_features_str = String(", ").join(p_features); tooltip_text += TTR("This project uses features unsupported by the current build:") + "\n" + unsupported_features_str; } + if (tooltip_text.is_empty()) { return; } @@ -295,6 +363,7 @@ void ProjectListItemControl::set_unsupported_features(PackedStringArray p_featur project_unsupported_features->set_tooltip_text(tooltip_text); project_unsupported_features->show(); } else { + project_different_version->hide(); project_unsupported_features->hide(); } } @@ -439,6 +508,12 @@ ProjectListItemControl::ProjectListItemControl() { path_hb->add_child(project_unsupported_features); project_unsupported_features->hide(); + project_different_version = memnew(TextureRect); + project_different_version->set_name("ProjectDifferentVersion"); + project_different_version->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + path_hb->add_child(project_different_version); + project_different_version->hide(); + project_version = memnew(Label); project_version->set_focus_mode(FOCUS_ACCESSIBILITY); project_version->set_name("ProjectVersion"); diff --git a/editor/project_manager/project_list.h b/editor/project_manager/project_list.h index f0c84d35ab..2c8ecac595 100644 --- a/editor/project_manager/project_list.h +++ b/editor/project_manager/project_list.h @@ -55,6 +55,7 @@ class ProjectListItemControl : public HBoxContainer { Label *last_edited_info = nullptr; Label *project_version = nullptr; TextureRect *project_unsupported_features = nullptr; + TextureRect *project_different_version = nullptr; HBoxContainer *tag_container = nullptr; Button *touch_menu_button = nullptr; @@ -67,6 +68,16 @@ class ProjectListItemControl : public HBoxContainer { bool is_hovering = false; bool is_favorite = false; + enum class VersionMatchType { + PROJECT_USES_SAME, + PROJECT_USES_OLDER_MAJOR, + PROJECT_USES_OLDER_MINOR, + PROJECT_USES_NEWER_MAJOR, + PROJECT_USES_NEWER_MINOR, + }; + + VersionMatchType version_match_type = VersionMatchType::PROJECT_USES_SAME; + void _update_favorite_button_focus_color(); void _favorite_button_pressed(); void _explore_button_pressed();