diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index d4e341f003..7993728ecc 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3724,6 +3724,8 @@ STR_6260 :Show blocked tiles STR_6261 :Show wide paths STR_6262 :Master volume STR_6263 :{SMALLFONT}{BLACK}Toggle all sound on/off +STR_6264 :Always use system file browser +STR_6265 :{SMALLFONT}{BLACK}When enabled, your operating system's file browser will be used instead of OpenRCT2's. ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 5c81b57a87..9dab710ace 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -2,6 +2,7 @@ ------------------------------------------------------------------------ - Feature: [#5993] Ride window prices can now be set via text input. - Feature: [#6998] Guests now wait for passing vehicles before crossing railway tracks. +- Feature: [#7658] Add option to always use system file browsing window. - Feature: [#7694] Debug option to visualize paths that the game detects as wide. - Feature: [#7713] The virtual floor now takes land ownership rights into account. - Feature: [#7771] Danish translation. diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 0a2fe4459f..8dc5272f4d 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -218,8 +218,7 @@ public: uint32_t type = intent->GetUIntExtra(INTENT_EXTRA_LOADSAVE_TYPE); std::string defaultName = intent->GetStringExtra(INTENT_EXTRA_PATH); loadsave_callback callback = (loadsave_callback)intent->GetPointerExtra(INTENT_EXTRA_CALLBACK); - rct_window* w = window_loadsave_open(type, defaultName.c_str()); - window_loadsave_set_loadsave_callback(callback); + rct_window* w = window_loadsave_open(type, defaultName.c_str(), callback); return w; } diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index 5413b260c2..14c47f1fab 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -161,11 +161,6 @@ static void window_loadsave_sort_list(); static rct_window* window_overwrite_prompt_open(const char* name, const char* path); -void window_loadsave_set_loadsave_callback(loadsave_callback cb) -{ - _loadSaveCallback = cb; -} - static int32_t window_loadsave_get_dir(utf8* last_save, char* path, const char* subdir, size_t pathSize) { if (last_save && platform_ensure_directory_exists(last_save)) @@ -182,9 +177,11 @@ static int32_t window_loadsave_get_dir(utf8* last_save, char* path, const char* return 1; } -rct_window* window_loadsave_open(int32_t type, const char* defaultName) +static bool browse(bool isSave, char* path, size_t pathSize); + +rct_window* window_loadsave_open(int32_t type, const char* defaultName, loadsave_callback callback) { - _loadSaveCallback = nullptr; + _loadSaveCallback = callback; _type = type; _defaultName[0] = '\0'; @@ -193,6 +190,20 @@ rct_window* window_loadsave_open(int32_t type, const char* defaultName) safe_strcpy(_defaultName, defaultName, sizeof(_defaultName)); } + bool isSave = (type & 0x01) == LOADSAVETYPE_SAVE; + bool success = false; + char path[MAX_PATH]; + + // Bypass the lot? + if (gConfigGeneral.use_native_browse_dialog) + { + if (browse(isSave, path, sizeof(path))) + { + window_loadsave_select(nullptr, path); + } + return nullptr; + } + rct_window* w = window_bring_to_front_by_class(WC_LOADSAVE); if (w == nullptr) { @@ -210,10 +221,6 @@ rct_window* window_loadsave_open(int32_t type, const char* defaultName) w->no_list_items = 0; w->selected_list_item = -1; - bool isSave = (type & 0x01) == LOADSAVETYPE_SAVE; - bool success = false; - char path[MAX_PATH]; - switch (type & 0x0E) { case LOADSAVETYPE_GAME: diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index 6b3199e510..254957c4ec 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -175,6 +175,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, WIDX_SAVE_PLUGIN_DATA_CHECKBOX, WIDX_STAY_CONNECTED_AFTER_DESYNC, + WIDX_ALWAYS_NATIVE_LOADSAVE, WIDX_AUTOSAVE, WIDX_AUTOSAVE_DROPDOWN, WIDX_PATH_TO_RCT1_TEXT, @@ -355,11 +356,12 @@ static rct_widget window_options_advanced_widgets[] = { { WWT_CHECKBOX, 2, 10, 299, 84, 95, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, STR_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM_TIP }, // Allow loading with incorrect checksum { WWT_CHECKBOX, 2, 10, 299, 99, 110, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP }, // Export plug-in objects with saved games { WWT_CHECKBOX, 2, 10, 299, 114, 125, STR_STAY_CONNECTED_AFTER_DESYNC, STR_STAY_CONNECTED_AFTER_DESYNC_TIP }, // Do not disconnect after the client desynchronises with the server - { WWT_DROPDOWN, 1, 165, 299, 130, 141, STR_NONE, STR_NONE }, // Autosave dropdown - { WWT_BUTTON, 1, 288, 298, 131, 140, STR_DROPDOWN_GLYPH, STR_AUTOSAVE_FREQUENCY_TIP }, // Autosave dropdown button - { WWT_LABEL, 1, 23, 298, 148, 159, STR_PATH_TO_RCT1, STR_PATH_TO_RCT1_TIP }, // RCT 1 path text - { WWT_BUTTON, 1, 24, 289, 163, 176, STR_NONE, STR_STRING_TOOLTIP }, // RCT 1 path button - { WWT_BUTTON, 1, 289, 299, 163, 176, STR_CLOSE_X, STR_PATH_TO_RCT1_CLEAR_TIP }, // RCT 1 path clear button + { WWT_CHECKBOX, 1, 10, 299, 129, 140, STR_ALWAYS_NATIVE_LOADSAVE, STR_ALWAYS_NATIVE_LOADSAVE_TIP }, // Use native load/save window + { WWT_DROPDOWN, 1, 165, 299, 145, 157, STR_NONE, STR_NONE }, // Autosave dropdown + { WWT_BUTTON, 1, 288, 298, 146, 156, STR_DROPDOWN_GLYPH, STR_AUTOSAVE_FREQUENCY_TIP }, // Autosave dropdown button + { WWT_LABEL, 1, 23, 298, 165, 176, STR_PATH_TO_RCT1, STR_PATH_TO_RCT1_TIP }, // RCT 1 path text + { WWT_BUTTON, 1, 24, 289, 180, 193, STR_NONE, STR_STRING_TOOLTIP }, // RCT 1 path button + { WWT_BUTTON, 1, 289, 299, 180, 193, STR_CLOSE_X, STR_PATH_TO_RCT1_CLEAR_TIP }, // RCT 1 path clear button { WIDGETS_END }, }; @@ -594,6 +596,7 @@ static uint64_t window_options_page_enabled_widgets[] = { (1 << WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM) | (1 << WIDX_SAVE_PLUGIN_DATA_CHECKBOX) | (1 << WIDX_STAY_CONNECTED_AFTER_DESYNC) | + (1 << WIDX_ALWAYS_NATIVE_LOADSAVE) | (1 << WIDX_AUTOSAVE) | (1 << WIDX_AUTOSAVE_DROPDOWN) | (1 << WIDX_PATH_TO_RCT1_TEXT) | @@ -929,6 +932,11 @@ static void window_options_mouseup(rct_window* w, rct_widgetindex widgetIndex) config_save_default(); window_invalidate(w); break; + case WIDX_ALWAYS_NATIVE_LOADSAVE: + gConfigGeneral.use_native_browse_dialog = !gConfigGeneral.use_native_browse_dialog; + config_save_default(); + window_invalidate(w); + break; case WIDX_PATH_TO_RCT1_BUTTON: { utf8string rct1path = platform_open_directory_browser(language_get_string(STR_PATH_TO_RCT1_BROWSER)); @@ -1888,6 +1896,7 @@ static void window_options_invalidate(rct_window* w) w, WIDX_ALLOW_LOADING_WITH_INCORRECT_CHECKSUM, gConfigGeneral.allow_loading_with_incorrect_checksum); widget_set_checkbox_value(w, WIDX_SAVE_PLUGIN_DATA_CHECKBOX, gConfigGeneral.save_plugin_data); widget_set_checkbox_value(w, WIDX_STAY_CONNECTED_AFTER_DESYNC, gConfigNetwork.stay_connected); + widget_set_checkbox_value(w, WIDX_ALWAYS_NATIVE_LOADSAVE, gConfigGeneral.use_native_browse_dialog); break; case WINDOW_OPTIONS_PAGE_TWITCH: diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index 2faa5e10b9..85b0c94e26 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -88,8 +88,7 @@ rct_window* window_scenarioselect_open(scenarioselect_callback callback, bool ti rct_window* window_error_open(rct_string_id title, rct_string_id message); -rct_window* window_loadsave_open(int32_t type, const char* defaultName); -void window_loadsave_set_loadsave_callback(loadsave_callback cb); +rct_window* window_loadsave_open(int32_t type, const char* defaultName, loadsave_callback callback); rct_window* window_track_place_open(const struct track_design_file_ref* tdFileRef); rct_window* window_track_manage_open(struct track_design_file_ref* tdFileRef); diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 285c2a51d6..44c2d57f64 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -202,6 +202,7 @@ namespace Config model->last_save_landscape_directory = reader->GetCString("last_landscape_directory", nullptr); model->last_save_scenario_directory = reader->GetCString("last_scenario_directory", nullptr); model->last_save_track_directory = reader->GetCString("last_track_directory", nullptr); + model->use_native_browse_dialog = reader->GetBoolean("use_native_browse_dialog", false); model->window_limit = reader->GetInt32("window_limit", WINDOW_LIMIT_MAX); model->zoom_to_cursor = reader->GetBoolean("zoom_to_cursor", true); model->render_weather_effects = reader->GetBoolean("render_weather_effects", true); @@ -273,6 +274,7 @@ namespace Config writer->WriteString("last_landscape_directory", model->last_save_landscape_directory); writer->WriteString("last_scenario_directory", model->last_save_scenario_directory); writer->WriteString("last_track_directory", model->last_save_track_directory); + writer->WriteBoolean("use_native_browse_dialog", model->use_native_browse_dialog); writer->WriteInt32("window_limit", model->window_limit); writer->WriteBoolean("zoom_to_cursor", model->zoom_to_cursor); writer->WriteBoolean("render_weather_effects", model->render_weather_effects); diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 99fb103da3..34bf2d8c6b 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -83,6 +83,7 @@ struct GeneralConfiguration bool show_real_names_of_guests; bool allow_early_completion; + // Loading and saving bool confirmation_prompt; int32_t load_save_sort; utf8* last_save_game_directory; @@ -90,6 +91,7 @@ struct GeneralConfiguration utf8* last_save_scenario_directory; utf8* last_save_track_directory; utf8* last_run_version; + bool use_native_browse_dialog; }; struct InterfaceConfiguration diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 3529c3a775..f23704ab58 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3888,6 +3888,9 @@ enum STR_MASTER_VOLUME = 6262, STR_MASTER_VOLUME_TIP = 6263, + STR_ALWAYS_NATIVE_LOADSAVE = 6264, + STR_ALWAYS_NATIVE_LOADSAVE_TIP = 6265, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 };