From a4dc7249eecf8990016c090dff4148b5420ed1f8 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 31 Dec 2024 11:47:40 +0000 Subject: [PATCH] Change: Merge Game Options and Game Settings together. Game Settings is now an additional 'Advanced' tab in the Game Options window. --- src/gui.h | 1 - src/intro_gui.cpp | 6 +- src/lang/english.txt | 8 +- src/settings_gui.cpp | 1225 ++++++++++++++++----------------- src/toolbar_gui.cpp | 3 - src/widgets/intro_widget.h | 1 - src/widgets/settings_widget.h | 28 +- 7 files changed, 608 insertions(+), 664 deletions(-) diff --git a/src/gui.h b/src/gui.h index 60c5c394e9..5cfded5c8f 100644 --- a/src/gui.h +++ b/src/gui.h @@ -25,7 +25,6 @@ void InitializeGUI(); /* settings_gui.cpp */ void ShowGameOptions(); -void ShowGameSettings(); /* train_gui.cpp */ void ShowOrdersWindow(const Vehicle *v); diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index 396fa4efb9..d294d1984c 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -351,7 +351,6 @@ struct SelectGameWindow : public Window { case WID_SGI_OPTIONS: ShowGameOptions(); break; case WID_SGI_HIGHSCORE: ShowHighscoreTable(); break; case WID_SGI_HELP: ShowHelpWindow(); break; - case WID_SGI_SETTINGS_OPTIONS:ShowGameSettings(); break; case WID_SGI_GRF_SETTINGS: ShowNewGRFSettings(true, true, false, _grfconfig_newgame); break; case WID_SGI_CONTENT_DOWNLOAD: if (!_network_available) { @@ -414,10 +413,7 @@ static constexpr NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), /* 'Game Options' and 'Settings' buttons */ - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_OPTIONS), SetStringTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_SETTINGS_OPTIONS), SetStringTip(STR_INTRO_CONFIG_SETTINGS_TREE, STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE), SetFill(1, 0), - EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_OPTIONS), SetStringTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), SetFill(1, 0), /* 'AI Settings' and 'Game Script Settings' buttons */ NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), diff --git a/src/lang/english.txt b/src/lang/english.txt index 1e8ea31162..cdf172e1c3 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -444,7 +444,6 @@ STR_SCENEDIT_TOWN_MENU_PACE_HOUSE :Place houses # Settings menu STR_SETTINGS_MENU_GAME_OPTIONS :Game options -STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Settings STR_SETTINGS_MENU_AI_SETTINGS :AI settings STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Game script settings STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF settings @@ -966,6 +965,8 @@ STR_GAME_OPTIONS_TAB_SOUND :Sound STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP :{BLACK}Choose sound and music settings STR_GAME_OPTIONS_TAB_SOCIAL :Social STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP :{BLACK}Choose social integration settings +STR_GAME_OPTIONS_TAB_ADVANCED :Advanced +STR_GAME_OPTIONS_TAB_ADVANCED_TOOLTIP :{BLACK}Change advanced settings STR_GAME_OPTIONS_VOLUME :Volume STR_GAME_OPTIONS_SFX_VOLUME :Sound effects @@ -1219,8 +1220,7 @@ STR_CITY_APPROVAL_PERMISSIVE :Permissive (no STR_WARNING_NO_SUITABLE_AI :{WHITE}No suitable AIs available...{}{}You can download several AIs via the 'Online Content' system -# Settings tree window -STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Settings +# Settings tree in the Game Options window STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expand all STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Collapse all @@ -2203,7 +2203,6 @@ STR_INTRO_MULTIPLAYER :{BLACK}Multipla STR_INTRO_GAME_OPTIONS :{BLACK}Game Options STR_INTRO_HIGHSCORE :{BLACK}Highscore Table STR_INTRO_HELP :{BLACK}Help & Manuals -STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Settings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Settings STR_INTRO_ONLINE_CONTENT :{BLACK}Online Content STR_INTRO_AI_SETTINGS :{BLACK}AI Settings @@ -2225,7 +2224,6 @@ STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Select ' STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Open game options STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Open highscore table STR_INTRO_TOOLTIP_HELP :{BLACK}Get access to documentation and online resources -STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Open settings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Open NewGRF settings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Open AI settings diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 973e966db0..563f2e070e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -196,11 +196,11 @@ static constexpr NWidgetPart _nested_social_plugins_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_FRAME, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_TITLE), NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM), NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_SOCIAL_PLUGIN_PLATFORM), SetMinimalSize(100, 12), SetAlignment(SA_RIGHT), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE), NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_SOCIAL_PLUGIN_STATE), SetMinimalSize(100, 12), SetAlignment(SA_RIGHT), EndContainer(), EndContainer(), @@ -209,7 +209,7 @@ static constexpr NWidgetPart _nested_social_plugins_widgets[] = { static constexpr NWidgetPart _nested_social_plugins_none_widgets[] = { NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE), EndContainer(), }; @@ -357,19 +357,83 @@ std::unique_ptr MakeNWidgetSocialPlugins() return std::make_unique(); } +int SETTING_HEIGHT = 11; ///< Height of a single setting in the tree view in pixels + +static const StringID _game_settings_restrict_dropdown[] = { + STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC + STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED + STR_CONFIG_SETTING_RESTRICT_ALL, // RM_ALL + STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT, // RM_CHANGED_AGAINST_DEFAULT + STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW, // RM_CHANGED_AGAINST_NEW +}; +static_assert(lengthof(_game_settings_restrict_dropdown) == RM_END); + +/** Warnings about hidden search results. */ +enum WarnHiddenResult { + WHR_NONE, ///< Nothing was filtering matches away. + WHR_CATEGORY, ///< Category setting filtered matches away. + WHR_TYPE, ///< Type setting filtered matches away. + WHR_CATEGORY_TYPE, ///< Both category and type settings filtered matches away. +}; + +/** + * Callback function for the reset all settings button + * @param w Window which is calling this callback + * @param confirmed boolean value, true when yes was clicked, false otherwise + */ +static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed) +{ + if (confirmed) { + GetSettingsTree().ResetAll(); + GetSettingsTree().FoldAll(); + w->InvalidateData(); + } +} + struct GameOptionsWindow : Window { + static inline GameSettings *settings_ptr; ///< Pointer to the game settings being displayed and modified. + + SettingEntry *valuewindow_entry = nullptr; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened. + SettingEntry *clicked_entry = nullptr; ///< If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button). + SettingEntry *last_clicked = nullptr; ///< If non-nullptr, pointer to the last clicked setting. + SettingEntry *valuedropdown_entry = nullptr; ///< If non-nullptr, pointer to the value for which a dropdown window is currently opened. + bool closing_dropdown = false; ///< True, if the dropdown list is currently closing. + + SettingFilter filter{}; ///< Filter for the list. + QueryString filter_editbox; ///< Filter editbox; + bool manually_changed_folding = false; ///< Whether the user expanded/collapsed something manually. + WarnHiddenResult warn_missing = WHR_NONE; ///< Whether and how to warn about missing search results. + int warn_lines = 0; ///< Number of lines used for warning about missing search results. + + Scrollbar *vscroll; + GameSettings *opt = nullptr; bool reload = false; int gui_scale = 0; static inline WidgetID active_tab = WID_GO_TAB_GENERAL; - GameOptionsWindow(WindowDesc &desc) : Window(desc), gui_scale(_gui_scale) + GameOptionsWindow(WindowDesc &desc) : Window(desc), filter_editbox(50), gui_scale(_gui_scale) { this->opt = &GetGameSettings(); AddCustomRefreshRates(); - this->InitNested(WN_GAME_OPTIONS_GAME_OPTIONS); + this->filter.mode = (RestrictionMode)_settings_client.gui.settings_restriction_mode; + this->filter.min_cat = RM_ALL; + this->filter.type = ST_ALL; + this->filter.type_hides = false; + this->settings_ptr = &GetGameSettings(); + + GetSettingsTree().FoldAll(); // Close all sub-pages + + this->CreateNestedTree(); + this->vscroll = this->GetScrollbar(WID_GO_SCROLLBAR); + this->FinishInitNested(WN_GAME_OPTIONS_GAME_OPTIONS); + + this->querystrings[WID_GO_FILTER] = &this->filter_editbox; + this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR; + this->SetFocusedWidget(WID_GO_FILTER); + this->OnInvalidateData(0); this->SetTab(GameOptionsWindow::active_tab); @@ -377,6 +441,11 @@ struct GameOptionsWindow : Window { if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) this->GetWidget(WID_GO_SURVEY_SEL)->SetDisplayedPlane(SZSP_NONE); } + void OnInit() override + { + _setting_circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + } + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_CUSTOM_CURRENCY, 0); @@ -488,6 +557,23 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_MUSIC_DROPDOWN: list = BuildSetDropDownList(selected_index); break; + + case WID_GO_RESTRICT_DROPDOWN: + for (int mode = 0; mode != RM_END; mode++) { + /* If we are in adv. settings screen for the new game's settings, + * we don't want to allow comparing with new game's settings. */ + bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame; + + list.push_back(MakeDropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); + } + break; + + case WID_GO_TYPE_DROPDOWN: + list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL)); + list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME)); + list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY)); + list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT)); + break; } return list; @@ -534,6 +620,18 @@ struct GameOptionsWindow : Window { return plugin->GetWidgetString(widget, stringid); } + case WID_GO_RESTRICT_DROPDOWN: + return GetString(_game_settings_restrict_dropdown[this->filter.mode]); + + case WID_GO_TYPE_DROPDOWN: + switch (this->filter.type) { + case ST_GAME: return GetString(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME); + case ST_COMPANY: return GetString(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME); + case ST_CLIENT: return GetString(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT); + default: return GetString(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL); + } + break; + default: return this->Window::GetWidgetString(widget, stringid); } @@ -569,30 +667,79 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_MUSIC_VOLUME: DrawSliderWidget(r, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.music_vol, VolumeMarkFunc); break; + + case WID_GO_OPTIONSPANEL: { + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); + tr.top += this->warn_lines * SETTING_HEIGHT; + uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines; + int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top, + this->vscroll->GetPosition(), last_row, this->last_clicked); + if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE); + break; + } + + case WID_GO_HELP_TEXT: + if (this->last_clicked != nullptr) { + const IntSettingDesc *sd = this->last_clicked->setting; + + Rect tr = r; + std::string str; + switch (sd->GetType()) { + case ST_COMPANY: str = GetString(STR_CONFIG_SETTING_TYPE, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME); break; + case ST_CLIENT: str = GetString(STR_CONFIG_SETTING_TYPE, STR_CONFIG_SETTING_TYPE_CLIENT); break; + case ST_GAME: str = GetString(STR_CONFIG_SETTING_TYPE, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME); break; + default: NOT_REACHED(); + } + DrawString(tr, str); + tr.top += GetCharacterHeight(FS_NORMAL); + + auto [param1, param2] = sd->GetValueParams(sd->GetDefaultValue()); + DrawString(tr, GetString(STR_CONFIG_SETTING_DEFAULT_VALUE, param1, param2)); + tr.top += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal; + + DrawStringMultiLine(tr, sd->GetHelp(), TC_WHITE); + } + break; + + default: + break; } } + /** + * Set the entry that should have its help text displayed, and mark the window dirty so it gets repainted. + * @param pe Setting to display help text of, use \c nullptr to stop displaying help of the currently displayed setting. + */ + void SetDisplayedHelpText(SettingEntry *pe) + { + if (this->last_clicked != pe) this->SetDirty(); + this->last_clicked = pe; + } + void SetTab(WidgetID widget) { - this->SetWidgetsLoweredState(false, WID_GO_TAB_GENERAL, WID_GO_TAB_GRAPHICS, WID_GO_TAB_SOUND, WID_GO_TAB_SOCIAL); + this->SetWidgetsLoweredState(false, WID_GO_TAB_GENERAL, WID_GO_TAB_GRAPHICS, WID_GO_TAB_SOUND, WID_GO_TAB_ADVANCED, WID_GO_TAB_SOCIAL); this->LowerWidget(widget); GameOptionsWindow::active_tab = widget; - int pane; + int plane; switch (widget) { - case WID_GO_TAB_GENERAL: pane = 0; break; - case WID_GO_TAB_GRAPHICS: pane = 1; break; - case WID_GO_TAB_SOUND: pane = 2; break; - case WID_GO_TAB_SOCIAL: pane = 3; break; + case WID_GO_TAB_GENERAL: plane = 0; break; + case WID_GO_TAB_GRAPHICS: plane = 1; break; + case WID_GO_TAB_SOUND: plane = 2; break; + case WID_GO_TAB_SOCIAL: plane = 3; break; + case WID_GO_TAB_ADVANCED: plane = 4; break; default: NOT_REACHED(); } - this->GetWidget(WID_GO_TAB_SELECTION)->SetDisplayedPlane(pane); + this->GetWidget(WID_GO_TAB_SELECTION)->SetDisplayedPlane(plane); this->SetDirty(); } void OnResize() override { + this->vscroll->SetCapacityFromWidget(this, WID_GO_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical()); + bool changed = false; NWidgetResizeBase *wid = this->GetWidget(WID_GO_BASE_GRF_DESCRIPTION); @@ -624,6 +771,10 @@ struct GameOptionsWindow : Window { y = GetStringHeight(str, wid->current_x); changed |= wid->UpdateVerticalSize(y); + wid = this->GetWidget(WID_GO_HELP_TEXT); + y = 2 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal + GetSettingsTree().GetMaxHelpHeight(wid->current_x); + changed |= wid->UpdateVerticalSize(y); + if (changed) this->ReInit(0, 0, this->flags.Test(WindowFlag::Centred)); } @@ -651,6 +802,71 @@ struct GameOptionsWindow : Window { size.width = std::max(size.width, GetDropDownListDimension(this->BuildDropDownList(widget, &selected)).width + padding.width); break; } + + case WID_GO_OPTIONSPANEL: + resize.height = SETTING_HEIGHT = std::max({(int)_setting_circle_size.height, SETTING_BUTTON_HEIGHT, GetCharacterHeight(FS_NORMAL)}) + WidgetDimensions::scaled.vsep_normal; + resize.width = 1; + + size.height = 8 * resize.height + WidgetDimensions::scaled.framerect.Vertical(); + break; + + case WID_GO_HELP_TEXT: { + static const StringID setting_types[] = { + STR_CONFIG_SETTING_TYPE_CLIENT, + STR_CONFIG_SETTING_TYPE_COMPANY_MENU, STR_CONFIG_SETTING_TYPE_COMPANY_INGAME, + STR_CONFIG_SETTING_TYPE_GAME_MENU, STR_CONFIG_SETTING_TYPE_GAME_INGAME, + }; + for (const auto &setting_type : setting_types) { + size.width = std::max(size.width, GetStringBoundingBox(GetString(STR_CONFIG_SETTING_TYPE, setting_type)).width + padding.width); + } + break; + } + + case WID_GO_RESTRICT_CATEGORY: + case WID_GO_RESTRICT_TYPE: + size.width = std::max(GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_CATEGORY).width, GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_TYPE).width); + break; + + default: + break; + } + } + + void OnPaint() override + { + if (this->GetWidget(WID_GO_TAB_SELECTION)->shown_plane != 4) { + this->DrawWidgets(); + return; + } + + if (this->closing_dropdown) { + this->closing_dropdown = false; + assert(this->valuedropdown_entry != nullptr); + this->valuedropdown_entry->SetButtons({}); + this->valuedropdown_entry = nullptr; + } + + /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */ + const Rect panel = this->GetWidget(WID_GO_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext); + StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing; + int new_warn_lines; + if (this->warn_missing == WHR_NONE) { + new_warn_lines = 0; + } else { + new_warn_lines = GetStringLineCount(GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]), panel.Width()); + } + if (this->warn_lines != new_warn_lines) { + this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines); + this->warn_lines = new_warn_lines; + } + + this->DrawWidgets(); + + /* Draw the 'some search results are hidden' notice. */ + if (this->warn_missing != WHR_NONE) { + DrawStringMultiLine(panel.WithHeight(this->warn_lines * GetCharacterHeight(FS_NORMAL)), + GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]), + TC_FROMSTRING, SA_CENTER); } } @@ -678,6 +894,7 @@ struct GameOptionsWindow : Window { case WID_GO_TAB_GENERAL: case WID_GO_TAB_GRAPHICS: case WID_GO_TAB_SOUND: + case WID_GO_TAB_ADVANCED: case WID_GO_TAB_SOCIAL: this->SetTab(widget); break; @@ -876,577 +1093,20 @@ struct GameOptionsWindow : Window { } break; } - } - } - void OnMouseLoop() override - { - if (_left_button_down || this->gui_scale == _gui_scale) return; - - _gui_scale_cfg = this->gui_scale; - - if (AdjustGUIZoom(false)) { - ReInitAllWindows(true); - this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, false); - this->SetDirty(); - } - } - - void OnDropdownSelect(WidgetID widget, int index) override - { - switch (widget) { - case WID_GO_CURRENCY_DROPDOWN: // Currency - if (index == CURRENCY_CUSTOM) ShowCustCurrency(); - this->opt->locale.currency = index; - ReInitAllWindows(false); - break; - - case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options - _settings_client.gui.autosave_interval = _autosave_dropdown_to_minutes[index]; - ChangeAutosaveFrequency(false); - this->SetDirty(); - break; - - case WID_GO_LANG_DROPDOWN: // Change interface language - ReadLanguagePack(&_languages[index]); - CloseWindowByClass(WC_QUERY_STRING); - CheckForMissingGlyphs(); - ClearAllCachedNames(); - UpdateAllVirtCoords(); - CheckBlitter(); - ReInitAllWindows(false); - break; - - case WID_GO_RESOLUTION_DROPDOWN: // Change resolution - if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { - this->SetDirty(); - } - break; - - case WID_GO_REFRESH_RATE_DROPDOWN: { - _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index); - if (_settings_client.gui.refresh_rate > 60) { - /* Show warning to the user that this refresh rate might not be suitable on - * larger maps with many NewGRFs and vehicles. */ - ShowErrorMessage(GetEncodedString(STR_GAME_OPTIONS_REFRESH_RATE_WARNING), {}, WL_INFO); - } - break; - } - - case WID_GO_BASE_GRF_DROPDOWN: - if (_game_mode == GM_MENU) { - CloseWindowByClass(WC_GRF_PARAMETERS); - auto set = BaseGraphics::GetSet(index); - BaseGraphics::SetSet(set); - this->reload = true; - this->InvalidateData(); - } - break; - - case WID_GO_BASE_SFX_DROPDOWN: - ChangeSoundSet(index); - break; - - case WID_GO_BASE_MUSIC_DROPDOWN: - ChangeMusicSet(index); - break; - } - } - - /** - * Some data on this window has become invalid. - * @param data Information about the changed data. @see GameOptionsInvalidationData - * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. - */ - void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override - { - if (!gui_scope) return; - this->SetWidgetLoweredState(WID_GO_SURVEY_PARTICIPATE_BUTTON, _settings_client.network.participate_survey == PS_YES); - this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen); - this->SetWidgetLoweredState(WID_GO_VIDEO_ACCEL_BUTTON, _video_hw_accel); - this->SetWidgetDisabledState(WID_GO_REFRESH_RATE_DROPDOWN, _video_vsync); - -#ifndef __APPLE__ - this->SetWidgetLoweredState(WID_GO_VIDEO_VSYNC_BUTTON, _video_hw_accel && _video_vsync); - this->SetWidgetDisabledState(WID_GO_VIDEO_VSYNC_BUTTON, !_video_hw_accel); -#endif - - this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, _gui_scale_cfg == -1); - this->SetWidgetLoweredState(WID_GO_GUI_SCALE_BEVEL_BUTTON, _settings_client.gui.scale_bevels); -#ifdef HAS_TRUETYPE_FONT - this->SetWidgetLoweredState(WID_GO_GUI_FONT_SPRITE, _fcsettings.prefer_sprite); - this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa); - this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite); -#endif /* HAS_TRUETYPE_FONT */ - - this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU); - - this->SetWidgetDisabledState(WID_GO_BASE_GRF_PARAMETERS, BaseGraphics::GetUsedSet() == nullptr || !BaseGraphics::GetUsedSet()->IsConfigurable()); - - this->SetWidgetDisabledState(WID_GO_BASE_GRF_OPEN_URL, BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->url.empty()); - this->SetWidgetDisabledState(WID_GO_BASE_SFX_OPEN_URL, BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->url.empty()); - this->SetWidgetDisabledState(WID_GO_BASE_MUSIC_OPEN_URL, BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->url.empty()); - - for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) { - this->SetWidgetDisabledState(WID_GO_BASE_GRF_TEXTFILE + tft, BaseGraphics::GetUsedSet() == nullptr || !BaseGraphics::GetUsedSet()->GetTextfile(tft).has_value()); - this->SetWidgetDisabledState(WID_GO_BASE_SFX_TEXTFILE + tft, BaseSounds::GetUsedSet() == nullptr || !BaseSounds::GetUsedSet()->GetTextfile(tft).has_value()); - this->SetWidgetDisabledState(WID_GO_BASE_MUSIC_TEXTFILE + tft, BaseMusic::GetUsedSet() == nullptr || !BaseMusic::GetUsedSet()->GetTextfile(tft).has_value()); - } - - this->SetWidgetsDisabledState(!_network_available, WID_GO_BASE_GRF_CONTENT_DOWNLOAD, WID_GO_BASE_SFX_CONTENT_DOWNLOAD, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD); - } -}; - -static constexpr NWidgetPart _nested_game_options_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), SetPadding(WidgetDimensions::unscaled.sparse), - NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GENERAL), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_GENERAL, STR_GAME_OPTIONS_TAB_GENERAL_TOOLTIP), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GRAPHICS), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_GRAPHICS, STR_GAME_OPTIONS_TAB_GRAPHICS_TOOLTIP), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOUND), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_SOUND, STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOCIAL), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_SOCIAL, STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP), SetFill(1, 0), - EndContainer(), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_TAB_SELECTION), - /* General tab */ - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_LANGUAGE), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), - EndContainer(), - - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0), - EndContainer(), - - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), - EndContainer(), - - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_SURVEY_SEL), - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_SURVEY_PARTICIPATE_BUTTON), SetToolTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PREVIEW_BUTTON), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_LINK_BUTTON), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP), - EndContainer(), - EndContainer(), - EndContainer(), - EndContainer(), - - /* Graphics tab */ - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME), - NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_GUI_SCALE), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(0, 0), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_SCALE_AUTO), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP), - EndContainer(), -#ifdef HAS_TRUETYPE_FONT - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetToolTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_FONT_AA), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetToolTip(STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP), - EndContainer(), -#endif /* HAS_TRUETYPE_FONT */ - EndContainer(), - EndContainer(), - - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_GRAPHICS), - NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_RESOLUTION), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_REFRESH_RATE), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_REFRESH_RATE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_FULLSCREEN), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetToolTip(STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetToolTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP), - EndContainer(), -#ifndef __APPLE__ - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), - NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_VIDEO_VSYNC), - NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_VIDEO_VSYNC_BUTTON), SetToolTip(STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP), - EndContainer(), -#endif - NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_VIDEO_DRIVER_INFO), SetMinimalTextLines(1, 0), SetFill(1, 0), - EndContainer(), - EndContainer(), - EndContainer(), - - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_GRF), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), SetFill(1, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_PARAMETERS), SetStringTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP), - EndContainer(), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(200, 0), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), - NWidget(NWID_VERTICAL), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP), - EndContainer(), - EndContainer(), - EndContainer(), - EndContainer(), - - /* Sound/Music tab */ - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_VOLUME), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_SFX_VOLUME), SetMinimalSize(0, 12), SetStringTip(STR_GAME_OPTIONS_SFX_VOLUME), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_MUSIC_VOLUME), SetMinimalSize(0, 12), SetStringTip(STR_GAME_OPTIONS_MUSIC_VOLUME), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), - EndContainer(), - EndContainer(), - - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_SFX), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP), - EndContainer(), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), - NWidget(NWID_VERTICAL), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP), - EndContainer(), - EndContainer(), - EndContainer(), - - NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_MUSIC), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), - NWidget(NWID_VERTICAL), SetPIPRatio(0, 0, 1), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW), - EndContainer(), - EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP), - EndContainer(), - EndContainer(), - EndContainer(), - EndContainer(), - - /* Social tab */ - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), - NWidgetFunction(MakeNWidgetSocialPlugins), - EndContainer(), - EndContainer(), - EndContainer(), -}; - -static WindowDesc _game_options_desc( - WDP_CENTER, nullptr, 0, 0, - WC_GAME_OPTIONS, WC_NONE, - {}, - _nested_game_options_widgets -); - -/** Open the game options window. */ -void ShowGameOptions() -{ - CloseWindowByClass(WC_GAME_OPTIONS); - new GameOptionsWindow(_game_options_desc); -} - -int SETTING_HEIGHT = 11; ///< Height of a single setting in the tree view in pixels - -static const StringID _game_settings_restrict_dropdown[] = { - STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC - STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED - STR_CONFIG_SETTING_RESTRICT_ALL, // RM_ALL - STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT, // RM_CHANGED_AGAINST_DEFAULT - STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW, // RM_CHANGED_AGAINST_NEW -}; -static_assert(lengthof(_game_settings_restrict_dropdown) == RM_END); - -/** Warnings about hidden search results. */ -enum WarnHiddenResult : uint8_t { - WHR_NONE, ///< Nothing was filtering matches away. - WHR_CATEGORY, ///< Category setting filtered matches away. - WHR_TYPE, ///< Type setting filtered matches away. - WHR_CATEGORY_TYPE, ///< Both category and type settings filtered matches away. -}; - -/** - * Callback function for the reset all settings button - * @param w Window which is calling this callback - * @param confirmed boolean value, true when yes was clicked, false otherwise - */ -static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed) -{ - if (confirmed) { - GetSettingsTree().ResetAll(); - GetSettingsTree().FoldAll(); - w->InvalidateData(); - } -} - -/** Window to edit settings of the game. */ -struct GameSettingsWindow : Window { - static GameSettings *settings_ptr; ///< Pointer to the game settings being displayed and modified. - - SettingEntry *valuewindow_entry = nullptr; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened. - SettingEntry *clicked_entry = nullptr; ///< If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button). - SettingEntry *last_clicked = nullptr; ///< If non-nullptr, pointer to the last clicked setting. - SettingEntry *valuedropdown_entry = nullptr; ///< If non-nullptr, pointer to the value for which a dropdown window is currently opened. - bool closing_dropdown = false; ///< True, if the dropdown list is currently closing. - - SettingFilter filter{}; ///< Filter for the list. - QueryString filter_editbox; ///< Filter editbox; - bool manually_changed_folding = false; ///< Whether the user expanded/collapsed something manually. - WarnHiddenResult warn_missing = WHR_NONE; ///< Whether and how to warn about missing search results. - int warn_lines = 0; ///< Number of lines used for warning about missing search results. - - Scrollbar *vscroll; - - GameSettingsWindow(WindowDesc &desc) : Window(desc), filter_editbox(50) - { - this->filter.mode = (RestrictionMode)_settings_client.gui.settings_restriction_mode; - this->filter.min_cat = RM_ALL; - this->filter.type = ST_ALL; - this->filter.type_hides = false; - this->settings_ptr = &GetGameSettings(); - - GetSettingsTree().FoldAll(); // Close all sub-pages - - this->CreateNestedTree(); - this->vscroll = this->GetScrollbar(WID_GS_SCROLLBAR); - this->FinishInitNested(WN_GAME_OPTIONS_GAME_SETTINGS); - - this->querystrings[WID_GS_FILTER] = &this->filter_editbox; - this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR; - this->SetFocusedWidget(WID_GS_FILTER); - - this->InvalidateData(); - } - - void OnInit() override - { - _setting_circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); - } - - void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override - { - switch (widget) { - case WID_GS_OPTIONSPANEL: - resize.height = SETTING_HEIGHT = std::max({(int)_setting_circle_size.height, SETTING_BUTTON_HEIGHT, GetCharacterHeight(FS_NORMAL)}) + WidgetDimensions::scaled.vsep_normal; - resize.width = 1; - - size.height = 5 * resize.height + WidgetDimensions::scaled.framerect.Vertical(); - break; - - case WID_GS_HELP_TEXT: { - static const StringID setting_types[] = { - STR_CONFIG_SETTING_TYPE_CLIENT, - STR_CONFIG_SETTING_TYPE_COMPANY_MENU, STR_CONFIG_SETTING_TYPE_COMPANY_INGAME, - STR_CONFIG_SETTING_TYPE_GAME_MENU, STR_CONFIG_SETTING_TYPE_GAME_INGAME, - }; - for (const auto &setting_type : setting_types) { - size.width = std::max(size.width, GetStringBoundingBox(GetString(STR_CONFIG_SETTING_TYPE, setting_type)).width + padding.width); - } - size.height = 2 * GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal + - std::max(size.height, GetSettingsTree().GetMaxHelpHeight(size.width)); - break; - } - - case WID_GS_RESTRICT_CATEGORY: - case WID_GS_RESTRICT_TYPE: - size.width = std::max(GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_CATEGORY).width, GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_TYPE).width); - break; - - default: - break; - } - } - - void OnPaint() override - { - if (this->closing_dropdown) { - this->closing_dropdown = false; - assert(this->valuedropdown_entry != nullptr); - this->valuedropdown_entry->SetButtons({}); - this->valuedropdown_entry = nullptr; - } - - /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */ - const Rect panel = this->GetWidget(WID_GS_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext); - StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing; - int new_warn_lines; - if (this->warn_missing == WHR_NONE) { - new_warn_lines = 0; - } else { - new_warn_lines = GetStringLineCount(GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]), panel.Width()); - } - if (this->warn_lines != new_warn_lines) { - this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines); - this->warn_lines = new_warn_lines; - } - - this->DrawWidgets(); - - /* Draw the 'some search results are hidden' notice. */ - if (this->warn_missing != WHR_NONE) { - DrawStringMultiLine(panel.WithHeight(this->warn_lines * GetCharacterHeight(FS_NORMAL)), - GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]), - TC_FROMSTRING, SA_CENTER); - } - } - - std::string GetWidgetString(WidgetID widget, StringID stringid) const override - { - switch (widget) { - case WID_GS_RESTRICT_DROPDOWN: - return GetString(_game_settings_restrict_dropdown[this->filter.mode]); - - case WID_GS_TYPE_DROPDOWN: - switch (this->filter.type) { - case ST_GAME: return GetString(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME); - case ST_COMPANY: return GetString(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME); - case ST_CLIENT: return GetString(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT); - default: return GetString(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL); - } - - default: - return this->Window::GetWidgetString(widget, stringid); - } - } - - DropDownList BuildDropDownList(WidgetID widget) const - { - DropDownList list; - switch (widget) { - case WID_GS_RESTRICT_DROPDOWN: - for (int mode = 0; mode != RM_END; mode++) { - /* If we are in adv. settings screen for the new game's settings, - * we don't want to allow comparing with new game's settings. */ - bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame; - - list.push_back(MakeDropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); - } - break; - - case WID_GS_TYPE_DROPDOWN: - list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL)); - list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME)); - list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY)); - list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT)); - break; - } - return list; - } - - void DrawWidget(const Rect &r, WidgetID widget) const override - { - switch (widget) { - case WID_GS_OPTIONSPANEL: { - Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); - tr.top += this->warn_lines * SETTING_HEIGHT; - uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines; - int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top, - this->vscroll->GetPosition(), last_row, this->last_clicked); - if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE); - break; - } - - case WID_GS_HELP_TEXT: - if (this->last_clicked != nullptr) { - const IntSettingDesc *sd = this->last_clicked->setting; - - Rect tr = r; - std::string str; - switch (sd->GetType()) { - case ST_COMPANY: str = GetString(STR_CONFIG_SETTING_TYPE, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME); break; - case ST_CLIENT: str = GetString(STR_CONFIG_SETTING_TYPE, STR_CONFIG_SETTING_TYPE_CLIENT); break; - case ST_GAME: str = GetString(STR_CONFIG_SETTING_TYPE, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME); break; - default: NOT_REACHED(); - } - DrawString(tr, str); - tr.top += GetCharacterHeight(FS_NORMAL); - - auto [param1, param2] = sd->GetValueParams(sd->GetDefaultValue()); - DrawString(tr, GetString(STR_CONFIG_SETTING_DEFAULT_VALUE, param1, param2)); - tr.top += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal; - - DrawStringMultiLine(tr, sd->GetHelp(), TC_WHITE); - } - break; - - default: - break; - } - } - - /** - * Set the entry that should have its help text displayed, and mark the window dirty so it gets repainted. - * @param pe Setting to display help text of, use \c nullptr to stop displaying help of the currently displayed setting. - */ - void SetDisplayedHelpText(SettingEntry *pe) - { - if (this->last_clicked != pe) this->SetDirty(); - this->last_clicked = pe; - } - - void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override - { - switch (widget) { - case WID_GS_EXPAND_ALL: + case WID_GO_EXPAND_ALL: this->manually_changed_folding = true; GetSettingsTree().UnFoldAll(); this->InvalidateData(); break; - case WID_GS_COLLAPSE_ALL: + case WID_GO_COLLAPSE_ALL: this->manually_changed_folding = true; GetSettingsTree().FoldAll(); this->InvalidateData(); break; - case WID_GS_RESET_ALL: + case WID_GO_RESET_ALL: ShowQuery( GetEncodedString(STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION), GetEncodedString(STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT), @@ -1455,26 +1115,33 @@ struct GameSettingsWindow : Window { ); break; - case WID_GS_RESTRICT_DROPDOWN: { - DropDownList list = this->BuildDropDownList(widget); + case WID_GO_RESTRICT_DROPDOWN: { + int selected; + DropDownList list = this->BuildDropDownList(widget, &selected); if (!list.empty()) { ShowDropDownList(this, std::move(list), this->filter.mode, widget); } break; } - case WID_GS_TYPE_DROPDOWN: { - DropDownList list = this->BuildDropDownList(widget); + case WID_GO_TYPE_DROPDOWN: { + int selected; + DropDownList list = this->BuildDropDownList(widget, &selected); if (!list.empty()) { ShowDropDownList(this, std::move(list), this->filter.type, widget); } break; } + + case WID_GO_OPTIONSPANEL: + OptionsPanelClick(pt); + break; } + } - if (widget != WID_GS_OPTIONSPANEL) return; - - int32_t btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.top); + void OptionsPanelClick(Point pt) + { + int32_t btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GO_OPTIONSPANEL, WidgetDimensions::scaled.framerect.top); if (btn == INT32_MAX || btn < this->warn_lines) return; btn -= this->warn_lines; @@ -1483,7 +1150,8 @@ struct GameSettingsWindow : Window { if (clicked_entry == nullptr) return; // Clicked below the last setting of the page - int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - WidgetDimensions::scaled.frametext.left - (clicked_entry->level + 1) * WidgetDimensions::scaled.hsep_indent; // Shift x coordinate + const NWidgetBase *wid = this->GetWidget(WID_GO_OPTIONSPANEL); + int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - WidgetDimensions::scaled.frametext.left - (clicked_entry->level + 1) * WidgetDimensions::scaled.hsep_indent - wid->pos_x; // Shift x coordinate if (x < 0) return; // Clicked left of the entry SettingsPage *clicked_page = dynamic_cast(clicked_entry); @@ -1524,7 +1192,6 @@ struct GameSettingsWindow : Window { if (this->valuedropdown_entry != nullptr) this->valuedropdown_entry->SetButtons({}); this->closing_dropdown = false; - const NWidgetBase *wid = this->GetWidget(WID_GS_OPTIONSPANEL); int rel_y = (pt.y - wid->pos_y - WidgetDimensions::scaled.framerect.top) % wid->resize_y; Rect wi_rect; @@ -1544,7 +1211,7 @@ struct GameSettingsWindow : Window { list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_STRING1, param1, param2), i)); } - ShowDropDownListAt(this, std::move(list), value, WID_GS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); + ShowDropDownListAt(this, std::move(list), value, WID_GO_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); } } this->SetDirty(); @@ -1650,10 +1317,79 @@ struct GameSettingsWindow : Window { this->SetDirty(); } + void OnMouseLoop() override + { + if (_left_button_down || this->gui_scale == _gui_scale) return; + + _gui_scale_cfg = this->gui_scale; + + if (AdjustGUIZoom(false)) { + ReInitAllWindows(true); + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, false); + this->SetDirty(); + } + } + void OnDropdownSelect(WidgetID widget, int index) override { switch (widget) { - case WID_GS_RESTRICT_DROPDOWN: + case WID_GO_CURRENCY_DROPDOWN: // Currency + if (index == CURRENCY_CUSTOM) ShowCustCurrency(); + this->opt->locale.currency = index; + ReInitAllWindows(false); + break; + + case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options + _settings_client.gui.autosave_interval = _autosave_dropdown_to_minutes[index]; + ChangeAutosaveFrequency(false); + this->SetDirty(); + break; + + case WID_GO_LANG_DROPDOWN: // Change interface language + ReadLanguagePack(&_languages[index]); + CloseWindowByClass(WC_QUERY_STRING); + CheckForMissingGlyphs(); + ClearAllCachedNames(); + UpdateAllVirtCoords(); + CheckBlitter(); + ReInitAllWindows(false); + break; + + case WID_GO_RESOLUTION_DROPDOWN: // Change resolution + if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { + this->SetDirty(); + } + break; + + case WID_GO_REFRESH_RATE_DROPDOWN: { + _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index); + if (_settings_client.gui.refresh_rate > 60) { + /* Show warning to the user that this refresh rate might not be suitable on + * larger maps with many NewGRFs and vehicles. */ + ShowErrorMessage(GetEncodedString(STR_GAME_OPTIONS_REFRESH_RATE_WARNING), {}, WL_INFO); + } + break; + } + + case WID_GO_BASE_GRF_DROPDOWN: + if (_game_mode == GM_MENU) { + CloseWindowByClass(WC_GRF_PARAMETERS); + auto set = BaseGraphics::GetSet(index); + BaseGraphics::SetSet(set); + this->reload = true; + this->InvalidateData(); + } + break; + + case WID_GO_BASE_SFX_DROPDOWN: + ChangeSoundSet(index); + break; + + case WID_GO_BASE_MUSIC_DROPDOWN: + ChangeMusicSet(index); + break; + + case WID_GO_RESTRICT_DROPDOWN: this->filter.mode = (RestrictionMode)index; if (this->filter.mode == RM_CHANGED_AGAINST_DEFAULT || this->filter.mode == RM_CHANGED_AGAINST_NEW) { @@ -1670,12 +1406,12 @@ struct GameSettingsWindow : Window { this->InvalidateData(); break; - case WID_GS_TYPE_DROPDOWN: + case WID_GO_TYPE_DROPDOWN: this->filter.type = (SettingType)index; this->InvalidateData(); break; - case WID_GS_SETTING_DROPDOWN: + case WID_GO_SETTING_DROPDOWN: /* Deal with drop down boxes on the panel. */ assert(this->valuedropdown_entry != nullptr); const IntSettingDesc *sd = this->valuedropdown_entry->setting; @@ -1689,7 +1425,7 @@ struct GameSettingsWindow : Window { void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override { - if (widget != WID_GS_SETTING_DROPDOWN) { + if (widget != WID_GO_SETTING_DROPDOWN) { /* Normally the default implementation of OnDropdownClose() takes care of * a few things. We want that behaviour here too, but only for * "normal" dropdown boxes. The special dropdown boxes added for every @@ -1706,9 +1442,47 @@ struct GameSettingsWindow : Window { } } + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. @see GameOptionsInvalidationData + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override { if (!gui_scope) return; + this->SetWidgetLoweredState(WID_GO_SURVEY_PARTICIPATE_BUTTON, _settings_client.network.participate_survey == PS_YES); + this->SetWidgetLoweredState(WID_GO_FULLSCREEN_BUTTON, _fullscreen); + this->SetWidgetLoweredState(WID_GO_VIDEO_ACCEL_BUTTON, _video_hw_accel); + this->SetWidgetDisabledState(WID_GO_REFRESH_RATE_DROPDOWN, _video_vsync); + +#ifndef __APPLE__ + this->SetWidgetLoweredState(WID_GO_VIDEO_VSYNC_BUTTON, _video_hw_accel && _video_vsync); + this->SetWidgetDisabledState(WID_GO_VIDEO_VSYNC_BUTTON, !_video_hw_accel); +#endif + + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, _gui_scale_cfg == -1); + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_BEVEL_BUTTON, _settings_client.gui.scale_bevels); +#ifdef HAS_TRUETYPE_FONT + this->SetWidgetLoweredState(WID_GO_GUI_FONT_SPRITE, _fcsettings.prefer_sprite); + this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa); + this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite); +#endif /* HAS_TRUETYPE_FONT */ + + this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU); + + this->SetWidgetDisabledState(WID_GO_BASE_GRF_PARAMETERS, BaseGraphics::GetUsedSet() == nullptr || !BaseGraphics::GetUsedSet()->IsConfigurable()); + + this->SetWidgetDisabledState(WID_GO_BASE_GRF_OPEN_URL, BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->url.empty()); + this->SetWidgetDisabledState(WID_GO_BASE_SFX_OPEN_URL, BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->url.empty()); + this->SetWidgetDisabledState(WID_GO_BASE_MUSIC_OPEN_URL, BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->url.empty()); + + for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) { + this->SetWidgetDisabledState(WID_GO_BASE_GRF_TEXTFILE + tft, BaseGraphics::GetUsedSet() == nullptr || !BaseGraphics::GetUsedSet()->GetTextfile(tft).has_value()); + this->SetWidgetDisabledState(WID_GO_BASE_SFX_TEXTFILE + tft, BaseSounds::GetUsedSet() == nullptr || !BaseSounds::GetUsedSet()->GetTextfile(tft).has_value()); + this->SetWidgetDisabledState(WID_GO_BASE_MUSIC_TEXTFILE + tft, BaseMusic::GetUsedSet() == nullptr || !BaseMusic::GetUsedSet()->GetTextfile(tft).has_value()); + } + + this->SetWidgetsDisabledState(!_network_available, WID_GO_BASE_GRF_CONTENT_DOWNLOAD, WID_GO_BASE_SFX_CONTENT_DOWNLOAD, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD); /* Update which settings are to be visible. */ RestrictionMode min_level = (this->filter.mode <= RM_ALL) ? this->filter.mode : RM_BASIC; @@ -1732,13 +1506,13 @@ struct GameSettingsWindow : Window { bool all_folded = true; bool all_unfolded = true; GetSettingsTree().GetFoldingState(all_folded, all_unfolded); - this->SetWidgetDisabledState(WID_GS_EXPAND_ALL, all_unfolded); - this->SetWidgetDisabledState(WID_GS_COLLAPSE_ALL, all_folded); + this->SetWidgetDisabledState(WID_GO_EXPAND_ALL, all_unfolded); + this->SetWidgetDisabledState(WID_GO_COLLAPSE_ALL, all_folded); } void OnEditboxChanged(WidgetID wid) override { - if (wid == WID_GS_FILTER) { + if (wid == WID_GO_FILTER) { this->filter.string.SetFilterTerm(this->filter_editbox.text.GetText()); if (!this->filter.string.IsEmpty() && !this->manually_changed_folding) { /* User never expanded/collapsed single pages and entered a filter term. @@ -1748,70 +1522,253 @@ struct GameSettingsWindow : Window { this->InvalidateData(); } } - - void OnResize() override - { - this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical()); - } }; -GameSettings *GameSettingsWindow::settings_ptr = nullptr; +static constexpr NWidgetPart _nested_game_options_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), SetPadding(WidgetDimensions::unscaled.sparse), + NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GENERAL), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_GENERAL, STR_GAME_OPTIONS_TAB_GENERAL_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GRAPHICS), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_GRAPHICS, STR_GAME_OPTIONS_TAB_GRAPHICS_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOUND), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_SOUND, STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOCIAL), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_SOCIAL, STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_ADVANCED), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_ADVANCED, STR_GAME_OPTIONS_TAB_ADVANCED_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_TAB_SELECTION), + /* General tab */ + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse_resize), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_LANGUAGE), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), -static constexpr NWidgetPart _nested_settings_selection_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), - NWidget(WWT_CAPTION, COLOUR_MAUVE), SetStringTip(STR_CONFIG_SETTING_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_MAUVE), - NWidget(NWID_VERTICAL), SetPIP(WidgetDimensions::unscaled.frametext.top, WidgetDimensions::unscaled.vsep_normal, WidgetDimensions::unscaled.frametext.bottom), - NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_GS_RESTRICT_CATEGORY), SetStringTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY), - NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_SURVEY_SEL), + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_SURVEY_PARTICIPATE_BUTTON), SetToolTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PREVIEW_BUTTON), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_LINK_BUTTON), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP), + EndContainer(), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_GS_RESTRICT_TYPE), SetStringTip(STR_CONFIG_SETTING_RESTRICT_TYPE), - NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + + /* Graphics tab */ + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse_resize), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_GUI_SCALE), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(0, 0), SetResize(1, 0), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_SCALE_AUTO), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP), + EndContainer(), +#ifdef HAS_TRUETYPE_FONT + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetToolTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_FONT_AA), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetToolTip(STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP), + EndContainer(), +#endif /* HAS_TRUETYPE_FONT */ + EndContainer(), + EndContainer(), + + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_GRAPHICS), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_RESOLUTION), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_REFRESH_RATE), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_REFRESH_RATE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_FULLSCREEN), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetToolTip(STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetToolTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP), + EndContainer(), +#ifndef __APPLE__ + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_VIDEO_VSYNC), + NWidget(WWT_BOOLBTN, COLOUR_GREY, WID_GO_VIDEO_VSYNC_BUTTON), SetToolTip(STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP), + EndContainer(), +#endif + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_VIDEO_DRIVER_INFO), SetMinimalTextLines(1, 0), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + EndContainer(), + EndContainer(), + + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_GRF), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_PARAMETERS), SetStringTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP), + EndContainer(), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(200, 0), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP), + EndContainer(), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), - NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_CONFIG_SETTING_FILTER_TITLE), - NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_GS_FILTER), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + + /* Sound/Music tab */ + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse_resize), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_VOLUME), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_SFX_VOLUME), SetMinimalSize(0, 12), SetStringTip(STR_GAME_OPTIONS_SFX_VOLUME), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetResize(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_MUSIC_VOLUME), SetMinimalSize(0, 12), SetStringTip(STR_GAME_OPTIONS_MUSIC_VOLUME), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetResize(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), + EndContainer(), + EndContainer(), + + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_SFX), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP), + EndContainer(), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP), + EndContainer(), + EndContainer(), + EndContainer(), + + NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_MUSIC), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_VERTICAL), SetPIPRatio(0, 0, 1), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW), + EndContainer(), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP), + EndContainer(), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize + EndContainer(), + + /* Social tab */ + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse_resize), + NWidgetFunction(MakeNWidgetSocialPlugins), + NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize + EndContainer(), + + /* Advanced settings tab */ + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.sparse_resize), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_RESTRICT_CATEGORY), SetStringTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_RESTRICT_TYPE), SetStringTip(STR_CONFIG_SETTING_RESTRICT_TYPE), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), + NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_CONFIG_SETTING_FILTER_TITLE), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_GO_FILTER), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + EndContainer(), + + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_GO_OPTIONSPANEL), SetMinimalSize(400, 0), SetFill(1, 1), SetResize(1, 1), SetScrollbar(WID_GO_SCROLLBAR), + EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_GO_SCROLLBAR), + EndContainer(), + + NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_EXPAND_ALL), SetStringTip(STR_CONFIG_SETTING_EXPAND_ALL), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_COLLAPSE_ALL), SetStringTip(STR_CONFIG_SETTING_COLLAPSE_ALL), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_RESET_ALL), SetStringTip(STR_CONFIG_SETTING_RESET_ALL), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_HELP_TEXT), SetFill(1, 0), SetResize(1, 0), EndContainer(), EndContainer(), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PANEL, COLOUR_MAUVE, WID_GS_OPTIONSPANEL), SetMinimalSize(400, 174), SetScrollbar(WID_GS_SCROLLBAR), EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_GS_SCROLLBAR), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_MAUVE), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GS_HELP_TEXT), SetMinimalSize(300, 25), SetFill(1, 1), SetResize(1, 0), - SetPadding(WidgetDimensions::unscaled.frametext), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_EXPAND_ALL), SetStringTip(STR_CONFIG_SETTING_EXPAND_ALL), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_COLLAPSE_ALL), SetStringTip(STR_CONFIG_SETTING_COLLAPSE_ALL), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_RESET_ALL), SetStringTip(STR_CONFIG_SETTING_RESET_ALL), - NWidget(WWT_PANEL, COLOUR_MAUVE), SetFill(1, 0), SetResize(1, 0), + + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), SetResizeWidgetTypeTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE), EndContainer(), - NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), EndContainer(), }; -static WindowDesc _settings_selection_desc( - WDP_CENTER, "settings", 510, 450, +static WindowDesc _game_options_desc( + WDP_CENTER, "game_options", 0, 0, WC_GAME_OPTIONS, WC_NONE, {}, - _nested_settings_selection_widgets + _nested_game_options_widgets ); -/** Open advanced settings window. */ -void ShowGameSettings() +/** Open the game options window. */ +void ShowGameOptions() { CloseWindowByClass(WC_GAME_OPTIONS); - new GameSettingsWindow(_settings_selection_desc); + new GameOptionsWindow(_game_options_desc); } - /** * Draw [<][>] boxes. * @param x the x position to draw diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index f567da94f9..1d9c378a0f 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -228,7 +228,6 @@ static CallBackFunction ToolbarFastForwardClick(Window *) */ enum OptionMenuEntries : uint8_t { OME_GAMEOPTIONS, - OME_SETTINGS, OME_AI_SETTINGS, OME_GAMESCRIPT_SETTINGS, OME_NEWGRFSETTINGS, @@ -261,7 +260,6 @@ static CallBackFunction ToolbarOptionsClick(Window *w) { DropDownList list; list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS)); - list.push_back(MakeDropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS)); /* Changes to the per-AI settings don't get send from the server to the clients. Clients get * the settings once they join but never update it. As such don't show the window at all * to network clients. */ @@ -306,7 +304,6 @@ static CallBackFunction MenuClickSettings(int index) { switch (index) { case OME_GAMEOPTIONS: ShowGameOptions(); return CBF_NONE; - case OME_SETTINGS: ShowGameSettings(); return CBF_NONE; case OME_AI_SETTINGS: ShowAIConfigWindow(); return CBF_NONE; case OME_GAMESCRIPT_SETTINGS: ShowGSConfigWindow(); return CBF_NONE; case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, _grfconfig); return CBF_NONE; diff --git a/src/widgets/intro_widget.h b/src/widgets/intro_widget.h index dcefc172be..6e43b1df4f 100644 --- a/src/widgets/intro_widget.h +++ b/src/widgets/intro_widget.h @@ -29,7 +29,6 @@ enum SelectGameIntroWidgets : WidgetID { WID_SGI_OPTIONS, ///< Options button. WID_SGI_HIGHSCORE, ///< Highscore button. WID_SGI_HELP, ///< Help and manuals button. - WID_SGI_SETTINGS_OPTIONS, ///< Settings button. WID_SGI_GRF_SETTINGS, ///< NewGRF button. WID_SGI_CONTENT_DOWNLOAD, ///< Content Download button. WID_SGI_AI_SETTINGS, ///< AI button. diff --git a/src/widgets/settings_widget.h b/src/widgets/settings_widget.h index 9063d79bba..a4d88669a4 100644 --- a/src/widgets/settings_widget.h +++ b/src/widgets/settings_widget.h @@ -16,6 +16,7 @@ enum GameOptionsWidgets : WidgetID { WID_GO_TAB_GRAPHICS, ///< Graphics tab. WID_GO_TAB_SOUND, ///< Sound tab. WID_GO_TAB_SOCIAL, ///< Social tab. + WID_GO_TAB_ADVANCED, ///< Advanced tab. WID_GO_TAB_SELECTION, ///< Background of the tab selection. WID_GO_CURRENCY_DROPDOWN, ///< Currency dropdown. WID_GO_DISTANCE_DROPDOWN, ///< Measuring unit dropdown. @@ -61,23 +62,20 @@ enum GameOptionsWidgets : WidgetID { WID_GO_SOCIAL_PLUGIN_TITLE, ///< Title of the frame of the social plugin. WID_GO_SOCIAL_PLUGIN_PLATFORM, ///< Platform of the social plugin. WID_GO_SOCIAL_PLUGIN_STATE, ///< State of the social plugin. -}; -/** Widgets of the #GameSettingsWindow class. */ -enum GameSettingsWidgets : WidgetID { - WID_GS_FILTER, ///< Text filter. - WID_GS_OPTIONSPANEL, ///< Panel widget containing the option lists. - WID_GS_SCROLLBAR, ///< Scrollbar. - WID_GS_HELP_TEXT, ///< Information area to display help text of the selected option. - WID_GS_EXPAND_ALL, ///< Expand all button. - WID_GS_COLLAPSE_ALL, ///< Collapse all button. - WID_GS_RESET_ALL, ///< Reset all button. - WID_GS_RESTRICT_CATEGORY, ///< Label upfront to the category drop-down box to restrict the list of settings to show - WID_GS_RESTRICT_TYPE, ///< Label upfront to the type drop-down box to restrict the list of settings to show - WID_GS_RESTRICT_DROPDOWN, ///< The drop down box to restrict the list of settings - WID_GS_TYPE_DROPDOWN, ///< The drop down box to choose client/game/company/all settings + WID_GO_FILTER, ///< Text filter. + WID_GO_OPTIONSPANEL, ///< Panel widget containing the option lists. + WID_GO_SCROLLBAR, ///< Scrollbar. + WID_GO_HELP_TEXT, ///< Information area to display help text of the selected option. + WID_GO_EXPAND_ALL, ///< Expand all button. + WID_GO_COLLAPSE_ALL, ///< Collapse all button. + WID_GO_RESET_ALL, ///< Reset all button. + WID_GO_RESTRICT_CATEGORY, ///< Label upfront to the category drop-down box to restrict the list of settings to show + WID_GO_RESTRICT_TYPE, ///< Label upfront to the type drop-down box to restrict the list of settings to show + WID_GO_RESTRICT_DROPDOWN, ///< The drop down box to restrict the list of settings + WID_GO_TYPE_DROPDOWN, ///< The drop down box to choose client/game/company/all settings - WID_GS_SETTING_DROPDOWN = -1, ///< Dynamically created dropdown for changing setting value. + WID_GO_SETTING_DROPDOWN = -1, ///< Dynamically created dropdown for changing setting value. }; /** Widgets of the #CustomCurrencyWindow class. */