From 55591b1b2ffb302eee351a293850e863151be3bf Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 28 Jan 2022 23:50:24 +0100 Subject: [PATCH 1/3] Merge old and new FileDialogDesc --- src/openrct2-ui/UiContext.Linux.cpp | 10 ++++---- src/openrct2-ui/UiContext.Win32.cpp | 4 ++-- src/openrct2-ui/UiContext.macOS.mm | 4 ++-- src/openrct2-ui/windows/LoadSave.cpp | 35 ++++++++++++---------------- src/openrct2/Context.cpp | 16 ++----------- src/openrct2/config/Config.cpp | 18 ++++++-------- src/openrct2/platform/platform.h | 25 ++++---------------- src/openrct2/ui/UiContext.h | 8 +++---- 8 files changed, 42 insertions(+), 78 deletions(-) diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index e7e952071b..10fbe927f1 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -138,7 +138,7 @@ namespace OpenRCT2::Ui { case DIALOG_TYPE::KDIALOG: { - std::string action = (desc.Type == FILE_DIALOG_TYPE::OPEN) ? "--getopenfilename" : "--getsavefilename"; + std::string action = (desc.Type == FileDialogType::Open) ? "--getopenfilename" : "--getsavefilename"; std::string filter = GetKDialogFilterString(desc.Filters); std::string cmd = String::StdFormat( "%s --title '%s' %s '%s' '%s'", executablePath.c_str(), desc.Title.c_str(), action.c_str(), @@ -154,7 +154,7 @@ namespace OpenRCT2::Ui { std::string action = "--file-selection"; std::string flags; - if (desc.Type == FILE_DIALOG_TYPE::SAVE) + if (desc.Type == FileDialogType::Save) { flags = "--confirm-overwrite --save"; } @@ -165,7 +165,7 @@ namespace OpenRCT2::Ui std::string output; if (Platform::Execute(cmd, &output) == 0) { - if (desc.Type == FILE_DIALOG_TYPE::SAVE) + if (desc.Type == FileDialogType::Save) { // The default file extension is taken from the **first** available filter, since // we cannot obtain it from zenity's output. This means that the FileDialogDesc::Filters @@ -197,14 +197,14 @@ namespace OpenRCT2::Ui if (!result.empty()) { - if (desc.Type == FILE_DIALOG_TYPE::OPEN && access(result.c_str(), F_OK) == -1) + if (desc.Type == FileDialogType::Open && access(result.c_str(), F_OK) == -1) { std::string msg = String::StdFormat( "\"%s\" not found: %s, please choose another file\n", result.c_str(), strerror(errno)); ShowMessageBox(window, msg); return ShowFileDialog(window, desc); } - if (desc.Type == FILE_DIALOG_TYPE::SAVE && access(result.c_str(), F_OK) != -1 && dtype == DIALOG_TYPE::KDIALOG) + if (desc.Type == FileDialogType::Save && access(result.c_str(), F_OK) != -1 && dtype == DIALOG_TYPE::KDIALOG) { std::string cmd = String::StdFormat("%s --yesno \"Overwrite %s?\"", executablePath.c_str(), result.c_str()); if (Platform::Execute(cmd) != 0) diff --git a/src/openrct2-ui/UiContext.Win32.cpp b/src/openrct2-ui/UiContext.Win32.cpp index 2d7afc879a..6dca213912 100644 --- a/src/openrct2-ui/UiContext.Win32.cpp +++ b/src/openrct2-ui/UiContext.Win32.cpp @@ -139,12 +139,12 @@ namespace OpenRCT2::Ui // Open dialog BOOL dialogResult = FALSE; DWORD commonFlags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; - if (desc.Type == FILE_DIALOG_TYPE::OPEN) + if (desc.Type == FileDialogType::Open) { openFileName.Flags = commonFlags | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST; dialogResult = GetOpenFileNameW(&openFileName); } - else if (desc.Type == FILE_DIALOG_TYPE::SAVE) + else if (desc.Type == FileDialogType::Save) { openFileName.Flags = commonFlags | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT; dialogResult = GetSaveFileNameW(&openFileName); diff --git a/src/openrct2-ui/UiContext.macOS.mm b/src/openrct2-ui/UiContext.macOS.mm index c62158990c..a8ea74be6f 100644 --- a/src/openrct2-ui/UiContext.macOS.mm +++ b/src/openrct2-ui/UiContext.macOS.mm @@ -110,7 +110,7 @@ namespace OpenRCT2::Ui NSString* directory; NSSavePanel* panel; - if (desc.Type == FILE_DIALOG_TYPE::SAVE) + if (desc.Type == FileDialogType::Save) { NSString* filePath = [NSString stringWithUTF8String:desc.DefaultFilename.c_str()]; directory = filePath.stringByDeletingLastPathComponent; @@ -118,7 +118,7 @@ namespace OpenRCT2::Ui panel = [NSSavePanel savePanel]; panel.nameFieldStringValue = [NSString stringWithFormat:@"%@.%@", basename, extensions.firstObject]; } - else if (desc.Type == FILE_DIALOG_TYPE::OPEN) + else if (desc.Type == FileDialogType::Open) { directory = [NSString stringWithUTF8String:desc.InitialDirectory.c_str()]; NSOpenPanel* open = [NSOpenPanel openPanel]; diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 6f6abbfeab..3a6552aec2 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -354,8 +354,8 @@ static void WindowLoadsaveResize(rct_window* w) static bool Browse(bool isSave, char* path, size_t pathSize) { - file_dialog_desc desc = {}; - const utf8* extension = ""; + OpenRCT2::Ui::FileDialogDesc desc = {}; + u8string extension = ""; auto fileType = FileExtension::Unknown; rct_string_id title = STR_NONE; switch (_type & 0x0E) @@ -364,38 +364,34 @@ static bool Browse(bool isSave, char* path, size_t pathSize) extension = ".park"; fileType = FileExtension::PARK; title = isSave ? STR_FILE_DIALOG_TITLE_SAVE_GAME : STR_FILE_DIALOG_TITLE_LOAD_GAME; - desc.filters[0].name = language_get_string(STR_OPENRCT2_SAVED_GAME); - desc.filters[0].pattern = GetFilterPatternByType(_type, isSave); + desc.Filters.push_back({ language_get_string(STR_OPENRCT2_SAVED_GAME), GetFilterPatternByType(_type, isSave) }); break; case LOADSAVETYPE_LANDSCAPE: extension = ".park"; fileType = FileExtension::PARK; title = isSave ? STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE : STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE; - desc.filters[0].name = language_get_string(STR_OPENRCT2_LANDSCAPE_FILE); - desc.filters[0].pattern = GetFilterPatternByType(_type, isSave); + desc.Filters.push_back({ language_get_string(STR_OPENRCT2_LANDSCAPE_FILE), GetFilterPatternByType(_type, isSave) }); break; case LOADSAVETYPE_SCENARIO: extension = ".park"; fileType = FileExtension::PARK; title = STR_FILE_DIALOG_TITLE_SAVE_SCENARIO; - desc.filters[0].name = language_get_string(STR_OPENRCT2_SCENARIO_FILE); - desc.filters[0].pattern = GetFilterPatternByType(_type, isSave); + desc.Filters.push_back({ language_get_string(STR_OPENRCT2_SCENARIO_FILE), GetFilterPatternByType(_type, isSave) }); break; case LOADSAVETYPE_TRACK: extension = ".td6"; fileType = FileExtension::TD6; title = isSave ? STR_FILE_DIALOG_TITLE_SAVE_TRACK : STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN; - desc.filters[0].name = language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE); - desc.filters[0].pattern = GetFilterPatternByType(_type, isSave); + desc.Filters.push_back( + { language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE), GetFilterPatternByType(_type, isSave) }); break; case LOADSAVETYPE_HEIGHTMAP: title = STR_FILE_DIALOG_TITLE_LOAD_HEIGHTMAP; - desc.filters[0].name = language_get_string(STR_OPENRCT2_HEIGHTMAP_FILE); - desc.filters[0].pattern = GetFilterPatternByType(_type, isSave); + desc.Filters.push_back({ language_get_string(STR_OPENRCT2_HEIGHTMAP_FILE), GetFilterPatternByType(_type, isSave) }); break; } @@ -420,21 +416,20 @@ static bool Browse(bool isSave, char* path, size_t pathSize) } } - desc.initial_directory = _directory; - desc.type = isSave ? FileDialogType::Save : FileDialogType::Open; - desc.default_filename = isSave ? path : nullptr; + desc.InitialDirectory = _directory; + desc.Type = isSave ? OpenRCT2::Ui::FileDialogType::Save : OpenRCT2::Ui::FileDialogType::Open; + desc.DefaultFilename = isSave ? path : ""; // Add 'all files' filter. If the number of filters is increased, this code will need to be adjusted. - desc.filters[1].name = language_get_string(STR_ALL_FILES); - desc.filters[1].pattern = "*"; + desc.Filters.push_back({ language_get_string(STR_ALL_FILES), "*" }); - desc.title = language_get_string(title); - if (platform_open_common_file_dialog(path, &desc, pathSize)) + desc.Title = language_get_string(title); + if (platform_open_common_file_dialog(path, desc, pathSize)) { // When the given save type was given, Windows still interprets a filename with a dot in its name as a custom extension, // meaning files like "My Coaster v1.2" will not get the .td6 extension by default. if (isSave && get_file_extension_type(path) != fileType) - path_append_extension(path, extension, pathSize); + path_append_extension(path, extension.c_str(), pathSize); return true; } diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 165b76d412..f769f8d370 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -1508,23 +1508,11 @@ const utf8* context_get_path_legacy(int32_t pathId) return result; } -bool platform_open_common_file_dialog(utf8* outFilename, file_dialog_desc* desc, size_t outSize) +bool platform_open_common_file_dialog(utf8* outFilename, OpenRCT2::Ui::FileDialogDesc& desc, size_t outSize) { try { - FileDialogDesc desc2; - desc2.Type = static_cast(desc->type); - desc2.Title = String::ToStd(desc->title); - desc2.InitialDirectory = String::ToStd(desc->initial_directory); - desc2.DefaultFilename = String::ToStd(desc->default_filename); - for (const auto& filter : desc->filters) - { - if (filter.name != nullptr) - { - desc2.Filters.push_back({ String::ToStd(filter.name), String::ToStd(filter.pattern) }); - } - } - std::string result = GetContext()->GetUiContext()->ShowFileDialog(desc2); + std::string result = GetContext()->GetUiContext()->ShowFileDialog(desc); String::Set(outFilename, outSize, result.c_str()); return !result.empty(); } diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 31624328a7..c5adfd73d5 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -716,20 +716,16 @@ namespace Config static bool SelectGogInstaller(utf8* installerPath) { - file_dialog_desc desc; - memset(&desc, 0, sizeof(desc)); - desc.type = FileDialogType::Open; - desc.title = language_get_string(STR_SELECT_GOG_INSTALLER); - desc.filters[0].name = language_get_string(STR_GOG_INSTALLER); - desc.filters[0].pattern = "*.exe"; - desc.filters[1].name = language_get_string(STR_ALL_FILES); - desc.filters[1].pattern = "*"; - desc.filters[2].name = nullptr; + FileDialogDesc desc{}; + desc.Type = FileDialogType::Open; + desc.Title = language_get_string(STR_SELECT_GOG_INSTALLER); + desc.Filters.push_back({ language_get_string(STR_GOG_INSTALLER), "*.exe" }); + desc.Filters.push_back({ language_get_string(STR_ALL_FILES), "*" }); const auto userHomePath = Platform::GetFolderPath(SPECIAL_FOLDER::USER_HOME); - desc.initial_directory = userHomePath.c_str(); + desc.InitialDirectory = userHomePath.c_str(); - return platform_open_common_file_dialog(installerPath, &desc, 4096); + return platform_open_common_file_dialog(installerPath, desc, 4096); } static bool ExtractGogInstaller(u8string_view installerPath, u8string_view targetPath) diff --git a/src/openrct2/platform/platform.h b/src/openrct2/platform/platform.h index c76d71fb33..269d07c0a2 100644 --- a/src/openrct2/platform/platform.h +++ b/src/openrct2/platform/platform.h @@ -20,6 +20,10 @@ #endif // __ANDROID__ struct TTFFontDescriptor; +namespace OpenRCT2::Ui +{ + struct FileDialogDesc; +} #ifndef MAX_PATH # define MAX_PATH 260 @@ -62,25 +66,6 @@ struct rct2_time uint8_t second; }; -enum class FileDialogType : uint8_t -{ - Open, - Save -}; - -struct file_dialog_desc -{ - FileDialogType type; - const utf8* title; - const utf8* initial_directory; - const utf8* default_filename; - struct - { - const utf8* name; // E.g. "Image Files" - const utf8* pattern; // E.g. "*.png;*.jpg;*.gif" - } filters[8]; -}; - // Platform shared definitions void platform_toggle_windowed_mode(); void platform_refresh_video(bool recreate_window); @@ -94,7 +79,7 @@ bool platform_lock_single_instance(); int32_t platform_get_drives(); uint32_t platform_get_ticks(); void platform_sleep(uint32_t ms); -bool platform_open_common_file_dialog(utf8* outFilename, file_dialog_desc* desc, size_t outSize); +bool platform_open_common_file_dialog(utf8* outFilename, OpenRCT2::Ui::FileDialogDesc& desc, size_t outSize); std::string platform_get_rct1_steam_dir(); std::string platform_get_rct2_steam_dir(); diff --git a/src/openrct2/ui/UiContext.h b/src/openrct2/ui/UiContext.h index 7cce48a4be..c5f16c42a2 100644 --- a/src/openrct2/ui/UiContext.h +++ b/src/openrct2/ui/UiContext.h @@ -65,10 +65,10 @@ namespace OpenRCT2 return !(lhs == rhs); } - enum class FILE_DIALOG_TYPE + enum class FileDialogType : uint8_t { - OPEN, - SAVE, + Open, + Save }; struct FileDialogDesc @@ -79,7 +79,7 @@ namespace OpenRCT2 std::string Pattern; // E.g. "*.png;*.jpg;*.gif" }; - FILE_DIALOG_TYPE Type = FILE_DIALOG_TYPE::OPEN; + FileDialogType Type = FileDialogType::Open; std::string Title; std::string InitialDirectory; std::string DefaultFilename; From fd6b327adb3207fbf20beef26bbc60d6d0790363 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 29 Jan 2022 13:56:20 +0100 Subject: [PATCH 2/3] Use emplace_back() instead of push_back() --- src/openrct2-ui/windows/LoadSave.cpp | 14 +++++++------- src/openrct2/config/Config.cpp | 4 ++-- src/openrct2/ui/UiContext.h | 6 ++++++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 3a6552aec2..895bb21750 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -364,34 +364,34 @@ static bool Browse(bool isSave, char* path, size_t pathSize) extension = ".park"; fileType = FileExtension::PARK; title = isSave ? STR_FILE_DIALOG_TITLE_SAVE_GAME : STR_FILE_DIALOG_TITLE_LOAD_GAME; - desc.Filters.push_back({ language_get_string(STR_OPENRCT2_SAVED_GAME), GetFilterPatternByType(_type, isSave) }); + desc.Filters.emplace_back(language_get_string(STR_OPENRCT2_SAVED_GAME), GetFilterPatternByType(_type, isSave)); break; case LOADSAVETYPE_LANDSCAPE: extension = ".park"; fileType = FileExtension::PARK; title = isSave ? STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE : STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE; - desc.Filters.push_back({ language_get_string(STR_OPENRCT2_LANDSCAPE_FILE), GetFilterPatternByType(_type, isSave) }); + desc.Filters.emplace_back(language_get_string(STR_OPENRCT2_LANDSCAPE_FILE), GetFilterPatternByType(_type, isSave)); break; case LOADSAVETYPE_SCENARIO: extension = ".park"; fileType = FileExtension::PARK; title = STR_FILE_DIALOG_TITLE_SAVE_SCENARIO; - desc.Filters.push_back({ language_get_string(STR_OPENRCT2_SCENARIO_FILE), GetFilterPatternByType(_type, isSave) }); + desc.Filters.emplace_back(language_get_string(STR_OPENRCT2_SCENARIO_FILE), GetFilterPatternByType(_type, isSave)); break; case LOADSAVETYPE_TRACK: extension = ".td6"; fileType = FileExtension::TD6; title = isSave ? STR_FILE_DIALOG_TITLE_SAVE_TRACK : STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN; - desc.Filters.push_back( - { language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE), GetFilterPatternByType(_type, isSave) }); + desc.Filters.emplace_back( + language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE), GetFilterPatternByType(_type, isSave)); break; case LOADSAVETYPE_HEIGHTMAP: title = STR_FILE_DIALOG_TITLE_LOAD_HEIGHTMAP; - desc.Filters.push_back({ language_get_string(STR_OPENRCT2_HEIGHTMAP_FILE), GetFilterPatternByType(_type, isSave) }); + desc.Filters.emplace_back(language_get_string(STR_OPENRCT2_HEIGHTMAP_FILE), GetFilterPatternByType(_type, isSave)); break; } @@ -421,7 +421,7 @@ static bool Browse(bool isSave, char* path, size_t pathSize) desc.DefaultFilename = isSave ? path : ""; // Add 'all files' filter. If the number of filters is increased, this code will need to be adjusted. - desc.Filters.push_back({ language_get_string(STR_ALL_FILES), "*" }); + desc.Filters.emplace_back(language_get_string(STR_ALL_FILES), "*"); desc.Title = language_get_string(title); if (platform_open_common_file_dialog(path, desc, pathSize)) diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index c5adfd73d5..0b9780e611 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -719,8 +719,8 @@ namespace Config FileDialogDesc desc{}; desc.Type = FileDialogType::Open; desc.Title = language_get_string(STR_SELECT_GOG_INSTALLER); - desc.Filters.push_back({ language_get_string(STR_GOG_INSTALLER), "*.exe" }); - desc.Filters.push_back({ language_get_string(STR_ALL_FILES), "*" }); + desc.Filters.emplace_back(language_get_string(STR_GOG_INSTALLER), "*.exe"); + desc.Filters.emplace_back(language_get_string(STR_ALL_FILES), "*"); const auto userHomePath = Platform::GetFolderPath(SPECIAL_FOLDER::USER_HOME); desc.InitialDirectory = userHomePath.c_str(); diff --git a/src/openrct2/ui/UiContext.h b/src/openrct2/ui/UiContext.h index c5f16c42a2..33d8f25b0a 100644 --- a/src/openrct2/ui/UiContext.h +++ b/src/openrct2/ui/UiContext.h @@ -77,6 +77,12 @@ namespace OpenRCT2 { std::string Name; // E.g. "Image Files" std::string Pattern; // E.g. "*.png;*.jpg;*.gif" + + Filter(u8string_view name, u8string_view pattern) + : Name(name) + , Pattern(pattern) + { + } }; FileDialogType Type = FileDialogType::Open; From 2f0e6389da2a162650762eb134e2af247a920776 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 29 Jan 2022 14:09:13 +0100 Subject: [PATCH 3/3] Use u8string in FileDialogDesc --- src/openrct2-ui/windows/LoadSave.cpp | 2 +- src/openrct2/ui/UiContext.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 895bb21750..fc988b33a7 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -418,7 +418,7 @@ static bool Browse(bool isSave, char* path, size_t pathSize) desc.InitialDirectory = _directory; desc.Type = isSave ? OpenRCT2::Ui::FileDialogType::Save : OpenRCT2::Ui::FileDialogType::Open; - desc.DefaultFilename = isSave ? path : ""; + desc.DefaultFilename = isSave ? path : u8string(); // Add 'all files' filter. If the number of filters is increased, this code will need to be adjusted. desc.Filters.emplace_back(language_get_string(STR_ALL_FILES), "*"); diff --git a/src/openrct2/ui/UiContext.h b/src/openrct2/ui/UiContext.h index 33d8f25b0a..3660fc42f4 100644 --- a/src/openrct2/ui/UiContext.h +++ b/src/openrct2/ui/UiContext.h @@ -75,8 +75,8 @@ namespace OpenRCT2 { struct Filter { - std::string Name; // E.g. "Image Files" - std::string Pattern; // E.g. "*.png;*.jpg;*.gif" + u8string Name; // E.g. "Image Files" + u8string Pattern; // E.g. "*.png;*.jpg;*.gif" Filter(u8string_view name, u8string_view pattern) : Name(name) @@ -86,9 +86,9 @@ namespace OpenRCT2 }; FileDialogType Type = FileDialogType::Open; - std::string Title; - std::string InitialDirectory; - std::string DefaultFilename; + u8string Title; + u8string InitialDirectory; + u8string DefaultFilename; std::vector Filters; };