OpenTTD Source 20250528-master-g3aca5d62a8
settings_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "currency.h"
12#include "error.h"
13#include "settings_gui.h"
14#include "textbuf_gui.h"
15#include "command_func.h"
16#include "network/network.h"
18#include "town.h"
19#include "settings_internal.h"
20#include "strings_func.h"
21#include "window_func.h"
22#include "string_func.h"
23#include "dropdown_type.h"
24#include "dropdown_func.h"
25#include "slider_func.h"
26#include "highscore.h"
27#include "base_media_base.h"
28#include "base_media_graphics.h"
29#include "base_media_music.h"
30#include "base_media_sounds.h"
31#include "company_base.h"
32#include "company_func.h"
33#include "viewport_func.h"
35#include "ai/ai.hpp"
36#include "blitter/factory.hpp"
37#include "language.h"
38#include "textfile_gui.h"
39#include "stringfilter_type.h"
40#include "querystring_gui.h"
41#include "fontcache.h"
42#include "zoom_func.h"
43#include "rev.h"
46#include "gui.h"
47#include "mixer.h"
48#include "newgrf_config.h"
49#include "network/core/config.h"
50#include "network/network_gui.h"
53#include "social_integration.h"
54#include "sound_func.h"
55#include "settingentry_gui.h"
57
58#include "table/strings.h"
59
61
62#include "safeguards.h"
63
64
65#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
66# define HAS_TRUETYPE_FONT
67#endif
68
69static const StringID _autosave_dropdown[] = {
70 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF,
71 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES,
72 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES,
73 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES,
74 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES,
76};
77
79static const uint32_t _autosave_dropdown_to_minutes[] = {
80 0,
81 10,
82 30,
83 60,
84 120,
85};
86
88
94{
95 auto it = std::ranges::find(_resolutions, Dimension(_screen.width, _screen.height));
96 return std::distance(_resolutions.begin(), it);
97}
98
99static void ShowCustCurrency();
100
103 const std::string name;
105
107 {
108 this->ConstructWindow();
109 this->LoadTextfile(textfile, BASESET_DIR);
110 }
111
112 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
113 {
114 if (widget == WID_TF_CAPTION) {
115 return GetString(stringid, this->content_type, this->name);
116 }
117
118 return this->Window::GetWidgetString(widget, stringid);
119 }
120};
121
128template <class TBaseSet>
129void ShowBaseSetTextfileWindow(Window *parent, TextfileType file_type, const TBaseSet *baseset, StringID content_type)
130{
131 parent->CloseChildWindowById(WC_TEXTFILE, file_type);
132 new BaseSetTextfileWindow(parent, file_type, baseset->name, *baseset->GetTextfile(file_type), content_type);
133}
134
141template <typename TBaseSet>
142static std::string GetListLabel(const TBaseSet *baseset)
143{
144 if (baseset->GetNumInvalid() == 0) return GetString(STR_JUST_RAW_STRING, baseset->name);
145 return GetString(STR_BASESET_STATUS, baseset->name, baseset->GetNumInvalid());
146}
147
148template <class T>
149DropDownList BuildSetDropDownList(int *selected_index)
150{
151 int n = T::GetNumSets();
152 *selected_index = T::GetIndexOfUsedSet();
153 DropDownList list;
154 for (int i = 0; i < n; i++) {
155 list.push_back(MakeDropDownListStringItem(GetListLabel(T::GetSet(i)), i));
156 }
157 return list;
158}
159
160std::set<int> _refresh_rates = { 30, 60, 75, 90, 100, 120, 144, 240 };
161
167{
168 /* Add the refresh rate as selected in the config. */
169 _refresh_rates.insert(_settings_client.gui.refresh_rate);
170
171 /* Add all the refresh rates of all monitors connected to the machine. */
172 std::vector<int> monitor_rates = VideoDriver::GetInstance()->GetListOfMonitorRefreshRates();
173 std::copy(monitor_rates.begin(), monitor_rates.end(), std::inserter(_refresh_rates, _refresh_rates.end()));
174}
175
176static const int SCALE_NMARKS = (MAX_INTERFACE_SCALE - MIN_INTERFACE_SCALE) / 25 + 1; // Show marks at 25% increments
177static const int VOLUME_NMARKS = 9; // Show 5 values and 4 empty marks.
178
179static std::optional<std::string> ScaleMarkFunc(int, int, int value)
180{
181 /* Label only every 100% mark. */
182 if (value % 100 != 0) return std::string{};
183
184 return GetString(STR_GAME_OPTIONS_GUI_SCALE_MARK, value / 100, 0);
185}
186
187static std::optional<std::string> VolumeMarkFunc(int, int mark, int value)
188{
189 /* Label only every other mark. */
190 if (mark % 2 != 0) return std::string{};
191
192 /* 0-127 does not map nicely to 0-100. Dividing first gives us nice round numbers. */
193 return GetString(STR_GAME_OPTIONS_VOLUME_MARK, value / 31 * 25);
194}
195
197static constexpr Colours GAME_OPTIONS_BACKGROUND = COLOUR_MAUVE;
199static constexpr Colours GAME_OPTIONS_BUTTON = COLOUR_YELLOW;
201static constexpr TextColour GAME_OPTIONS_FRAME = TC_ORANGE;
203static constexpr TextColour GAME_OPTIONS_LABEL = TC_LIGHT_BLUE;
205static constexpr TextColour GAME_OPTIONS_SELECTED = TC_WHITE;
206
207static constexpr NWidgetPart _nested_social_plugins_widgets[] = {
211 NWidget(WWT_TEXT, INVALID_COLOUR), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM), SetTextStyle(GAME_OPTIONS_LABEL),
213 EndContainer(),
215 NWidget(WWT_TEXT, INVALID_COLOUR), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE), SetTextStyle(GAME_OPTIONS_LABEL),
217 EndContainer(),
218 EndContainer(),
219 EndContainer(),
220};
221
222static constexpr NWidgetPart _nested_social_plugins_none_widgets[] = {
224 NWidget(WWT_TEXT, INVALID_COLOUR), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE), SetTextStyle(GAME_OPTIONS_LABEL),
225 EndContainer(),
226};
227
229public:
231 {
232 this->plugins = SocialIntegration::GetPlugins();
233
234 if (this->plugins.empty()) {
235 auto widget = MakeNWidgets(_nested_social_plugins_none_widgets, nullptr);
236 this->Add(std::move(widget));
237 } else {
238 for (size_t i = 0; i < this->plugins.size(); i++) {
239 auto widget = MakeNWidgets(_nested_social_plugins_widgets, nullptr);
240 this->Add(std::move(widget));
241 }
242 }
243
244 this->SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0);
245 }
246
247 void FillWidgetLookup(WidgetLookup &widget_lookup) override
248 {
249 widget_lookup[WID_GO_SOCIAL_PLUGINS] = this;
251 }
252
253 void SetupSmallestSize(Window *w) override
254 {
255 this->current_index = -1;
257 }
258
265 template <typename T>
266 std::string &GetWidestPlugin(T SocialIntegrationPlugin::*member) const
267 {
268 std::string *longest = &(this->plugins[0]->*member);
269 int longest_length = 0;
270
271 for (auto *plugin : this->plugins) {
272 int length = GetStringBoundingBox(plugin->*member).width;
273 if (length > longest_length) {
274 longest_length = length;
275 longest = &(plugin->*member);
276 }
277 }
278
279 return *longest;
280 }
281
282 std::string GetWidgetString(WidgetID widget, StringID) const
283 {
284 switch (widget) {
286 /* For SetupSmallestSize, use the longest string we have. */
287 if (this->current_index < 0) {
289 }
290
291 if (this->plugins[this->current_index]->name.empty()) {
292 return this->plugins[this->current_index]->basepath;
293 }
294
295 return GetString(STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE, this->plugins[this->current_index]->name, this->plugins[this->current_index]->version);
296
298 /* For SetupSmallestSize, use the longest string we have. */
299 if (this->current_index < 0) {
301 }
302
303 return this->plugins[this->current_index]->social_platform;
304
306 static const std::pair<SocialIntegrationPlugin::State, StringID> state_to_string[] = {
307 { SocialIntegrationPlugin::RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_RUNNING },
308 { SocialIntegrationPlugin::FAILED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED },
309 { SocialIntegrationPlugin::PLATFORM_NOT_RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_PLATFORM_NOT_RUNNING },
310 { SocialIntegrationPlugin::UNLOADED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNLOADED },
311 { SocialIntegrationPlugin::DUPLICATE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_DUPLICATE },
312 { SocialIntegrationPlugin::UNSUPPORTED_API, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNSUPPORTED_API },
313 { SocialIntegrationPlugin::INVALID_SIGNATURE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_INVALID_SIGNATURE },
314 };
315
316 /* For SetupSmallestSize, use the longest string we have. */
317 if (this->current_index < 0) {
319
320 /* Set the longest plugin when looking for the longest status. */
321 StringID longest = STR_NULL;
322 int longest_length = 0;
323 for (const auto &[state, string] : state_to_string) {
324 int length = GetStringBoundingBox(GetString(string, longest_plugin)).width;
325 if (length > longest_length) {
326 longest_length = length;
327 longest = string;
328 }
329 }
330
331 return GetString(longest, longest_plugin);
332 }
333
334 const auto plugin = this->plugins[this->current_index];
335
336 /* Find the string for the state. */
337 for (const auto &[state, string] : state_to_string) {
338 if (plugin->state == state) {
339 return GetString(string, plugin->social_platform);
340 }
341 }
342
343 /* Default string, in case no state matches. */
344 return GetString(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED, plugin->social_platform);
345 }
346
347 default: NOT_REACHED();
348 }
349 }
350
351 void Draw(const Window *w) override
352 {
353 this->current_index = 0;
354
355 for (auto &wid : this->children) {
356 wid->Draw(w);
357 this->current_index++;
358 }
359 }
360
361private:
362 int current_index = -1;
363 std::vector<SocialIntegrationPlugin *> plugins{};
364};
365
367std::unique_ptr<NWidgetBase> MakeNWidgetSocialPlugins()
368{
369 return std::make_unique<NWidgetSocialPlugins>();
370}
371
373
374static const StringID _game_settings_restrict_dropdown[] = {
375 STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC
376 STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED
377 STR_CONFIG_SETTING_RESTRICT_ALL, // RM_ALL
378 STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT, // RM_CHANGED_AGAINST_DEFAULT
379 STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW, // RM_CHANGED_AGAINST_NEW
380};
381static_assert(lengthof(_game_settings_restrict_dropdown) == RM_END);
382
390
396static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
397{
398 if (confirmed) {
401 w->InvalidateData();
402 }
403}
404
406 static inline GameSettings *settings_ptr;
407
412 bool closing_dropdown = false;
413
418 int warn_lines = 0;
419
420 Scrollbar *vscroll;
421 Scrollbar *vscroll_description;
422 static constexpr uint NUM_DESCRIPTION_LINES = 5;
423
424 GameSettings *opt = nullptr;
425 bool reload = false;
426 int gui_scale = 0;
427 static inline WidgetID active_tab = WID_GO_TAB_GENERAL;
428
429 GameOptionsWindow(WindowDesc &desc) : Window(desc), filter_editbox(50), gui_scale(_gui_scale)
430 {
431 this->opt = &GetGameSettings();
432
434
436 this->filter.min_cat = RM_ALL;
437 this->filter.type = ST_ALL;
438 this->filter.type_hides = false;
439 this->settings_ptr = &GetGameSettings();
440
441 GetSettingsTree().FoldAll(); // Close all sub-pages
442
443 this->CreateNestedTree();
444 this->vscroll = this->GetScrollbar(WID_GO_SCROLLBAR);
445 this->vscroll_description = this->GetScrollbar(WID_GO_HELP_TEXT_SCROLL);
446 this->vscroll_description->SetCapacity(NUM_DESCRIPTION_LINES);
448
450 this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
451
452 this->OnInvalidateData(0);
453
454 this->SetTab(GameOptionsWindow::active_tab);
455
456 if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) this->GetWidget<NWidgetStacked>(WID_GO_SURVEY_SEL)->SetDisplayedPlane(SZSP_NONE);
457 }
458
459 void OnInit() override
460 {
461 _setting_circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED));
462 }
463
464 void Close([[maybe_unused]] int data = 0) override
465 {
467 if (this->reload) _switch_mode = SM_MENU;
468 this->Window::Close();
469 }
470
477 DropDownList BuildDropDownList(WidgetID widget, int *selected_index) const
478 {
479 DropDownList list;
480 switch (widget) {
481 case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown
482 *selected_index = this->opt->locale.currency;
483 uint64_t disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies();
484
485 /* Add non-custom currencies; sorted naturally */
486 for (const CurrencySpec &currency : _currency_specs) {
487 int i = &currency - _currency_specs.data();
488 if (i == CURRENCY_CUSTOM) continue;
489 if (currency.code.empty()) {
490 list.push_back(MakeDropDownListStringItem(currency.name, i, HasBit(disabled, i)));
491 } else {
492 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_CURRENCY_CODE, currency.name, currency.code), i, HasBit(disabled, i)));
493 }
494 }
495 std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
496
497 /* Append custom currency at the end */
498 list.push_back(MakeDropDownListDividerItem()); // separator line
499 list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
500 break;
501 }
502
503 case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown
504 int index = 0;
505 for (auto &minutes : _autosave_dropdown_to_minutes) {
506 index++;
507 if (_settings_client.gui.autosave_interval <= minutes) break;
508 }
509 *selected_index = index - 1;
510
511 const StringID *items = _autosave_dropdown;
512 for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) {
513 list.push_back(MakeDropDownListStringItem(*items, i));
514 }
515 break;
516 }
517
518 case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown
519 for (uint i = 0; i < _languages.size(); i++) {
520 bool hide_language = IsReleasedVersion() && !_languages[i].IsReasonablyFinished();
521 if (hide_language) continue;
522 bool hide_percentage = IsReleasedVersion() || _languages[i].missing < _settings_client.gui.missing_strings_threshold;
523 std::string name;
524 if (&_languages[i] == _current_language) {
525 *selected_index = i;
526 name = _languages[i].own_name;
527 } else {
528 /* Especially with sprite-fonts, not all localized
529 * names can be rendered. So instead, we use the
530 * international names for anything but the current
531 * selected language. This avoids showing a few ????
532 * entries in the dropdown list. */
533 name = _languages[i].name;
534 }
535 if (hide_percentage) {
536 list.push_back(MakeDropDownListStringItem(std::move(name), i));
537 } else {
538 int percentage = (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS;
539 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, std::move(name), percentage), i));
540 }
541 }
542 std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
543 break;
544 }
545
546 case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown
547 if (_resolutions.empty()) break;
548
549 *selected_index = GetCurrentResolutionIndex();
550 for (uint i = 0; i < _resolutions.size(); i++) {
551 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_RESOLUTION_ITEM, _resolutions[i].width, _resolutions[i].height), i));
552 }
553 break;
554
555 case WID_GO_REFRESH_RATE_DROPDOWN: // Setup refresh rate dropdown
556 for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) {
557 auto i = std::distance(_refresh_rates.begin(), it);
558 if (*it == _settings_client.gui.refresh_rate) *selected_index = i;
559 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, *it), i));
560 }
561 break;
562
564 list = BuildSetDropDownList<BaseGraphics>(selected_index);
565 break;
566
568 list = BuildSetDropDownList<BaseSounds>(selected_index);
569 break;
570
572 list = BuildSetDropDownList<BaseMusic>(selected_index);
573 break;
574
576 for (int mode = 0; mode != RM_END; mode++) {
577 /* If we are in adv. settings screen for the new game's settings,
578 * we don't want to allow comparing with new game's settings. */
579 bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame;
580
581 list.push_back(MakeDropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled));
582 }
583 break;
584
586 list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL));
587 list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME));
588 list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY));
589 list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT));
590 break;
591 }
592
593 return list;
594 }
595
596 std::string GetToggleString(StringID stringid, WidgetID state_widget) const
597 {
598 return GetString(STR_GAME_OPTIONS_SETTING, stringid, this->IsWidgetLowered(state_widget) ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
599 }
600
601 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
602 {
603 switch (widget) {
605 const CurrencySpec &currency = _currency_specs[this->opt->locale.currency];
606 if (currency.code.empty()) return GetString(currency.name);
607 return GetString(STR_GAME_OPTIONS_CURRENCY_CODE, currency.name, currency.code);
608 }
609
611 int index = 0;
612 for (auto &minutes : _autosave_dropdown_to_minutes) {
613 index++;
614 if (_settings_client.gui.autosave_interval <= minutes) break;
615 }
616 return GetString(_autosave_dropdown[index - 1]);
617 }
618
623 case WID_GO_REFRESH_RATE_DROPDOWN: return GetString(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, _settings_client.gui.refresh_rate);
625 auto current_resolution = GetCurrentResolutionIndex();
626
627 if (current_resolution == _resolutions.size()) {
628 return GetString(STR_GAME_OPTIONS_RESOLUTION_OTHER);
629 }
630 return GetString(STR_GAME_OPTIONS_RESOLUTION_ITEM, _resolutions[current_resolution].width, _resolutions[current_resolution].height);
631 }
632
636 const NWidgetSocialPlugins *plugin = this->GetWidget<NWidgetSocialPlugins>(WID_GO_SOCIAL_PLUGINS);
637 assert(plugin != nullptr);
638
639 return plugin->GetWidgetString(widget, stringid);
640 }
641
643 return GetString(_game_settings_restrict_dropdown[this->filter.mode]);
644
646 switch (this->filter.type) {
647 case ST_GAME: return GetString(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME);
648 case ST_COMPANY: return GetString(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME);
649 case ST_CLIENT: return GetString(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT);
650 default: return GetString(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL);
651 }
652 break;
653
655 return GetToggleString(STR_GAME_OPTIONS_PARTICIPATE_SURVEY, WID_GO_SURVEY_PARTICIPATE_BUTTON);
656
658 return GetToggleString(STR_GAME_OPTIONS_GUI_SCALE_AUTO, WID_GO_GUI_SCALE_AUTO);
659
661 return GetToggleString(STR_GAME_OPTIONS_GUI_SCALE_BEVELS, WID_GO_GUI_SCALE_BEVEL_BUTTON);
662
664 return GetToggleString(STR_GAME_OPTIONS_GUI_FONT_SPRITE, WID_GO_GUI_FONT_SPRITE);
665
667 return GetToggleString(STR_GAME_OPTIONS_GUI_FONT_AA, WID_GO_GUI_FONT_AA);
668
670 return GetToggleString(STR_GAME_OPTIONS_FULLSCREEN, WID_GO_FULLSCREEN_BUTTON);
671
673 return GetToggleString(STR_GAME_OPTIONS_VIDEO_ACCELERATION, WID_GO_VIDEO_ACCEL_BUTTON);
674
676 return GetToggleString(STR_GAME_OPTIONS_VIDEO_VSYNC, WID_GO_VIDEO_VSYNC_BUTTON);
677
678 default:
679 return this->Window::GetWidgetString(widget, stringid);
680 }
681 }
682
683 void DrawWidget(const Rect &r, WidgetID widget) const override
684 {
685 switch (widget) {
688 break;
689
692 break;
693
696 break;
697
698 case WID_GO_GUI_SCALE:
699 DrawSliderWidget(r, GAME_OPTIONS_BACKGROUND, GAME_OPTIONS_BUTTON, TC_BLACK, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, SCALE_NMARKS, this->gui_scale, ScaleMarkFunc);
700 break;
701
703 DrawStringMultiLine(r, GetString(STR_GAME_OPTIONS_VIDEO_DRIVER_INFO, std::string{VideoDriver::GetInstance()->GetInfoString()}), GAME_OPTIONS_SELECTED);
704 break;
705
707 DrawSliderWidget(r, GAME_OPTIONS_BACKGROUND, GAME_OPTIONS_BUTTON, TC_BLACK, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.effect_vol, VolumeMarkFunc);
708 break;
709
711 DrawSliderWidget(r, GAME_OPTIONS_BACKGROUND, GAME_OPTIONS_BUTTON, TC_BLACK, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.music_vol, VolumeMarkFunc);
712 break;
713
714 case WID_GO_OPTIONSPANEL: {
716 tr.top += this->warn_lines * SETTING_HEIGHT;
717 uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines;
718 int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top,
719 this->vscroll->GetPosition(), last_row, this->last_clicked);
720 if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE);
721 break;
722 }
723
725 if (this->last_clicked != nullptr) {
726 const IntSettingDesc *sd = this->last_clicked->setting;
727
728 Rect tr = r;
729 std::string str;
730 switch (sd->GetType()) {
731 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;
732 case ST_CLIENT: str = GetString(STR_CONFIG_SETTING_TYPE, STR_CONFIG_SETTING_TYPE_CLIENT); break;
733 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;
734 default: NOT_REACHED();
735 }
736 DrawString(tr, str);
737 tr.top += GetCharacterHeight(FS_NORMAL);
738
739 auto [param1, param2] = sd->GetValueParams(sd->GetDefaultValue());
740 DrawString(tr, GetString(STR_CONFIG_SETTING_DEFAULT_VALUE, param1, param2));
741 }
742 break;
743
744 case WID_GO_HELP_TEXT:
745 if (this->last_clicked != nullptr) {
746 const IntSettingDesc *sd = this->last_clicked->setting;
747
748 DrawPixelInfo tmp_dpi;
749 if (FillDrawPixelInfo(&tmp_dpi, r)) {
750 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
751 int scrolls_pos = this->vscroll_description->GetPosition() * GetCharacterHeight(FS_NORMAL);
752 DrawStringMultiLine(0, r.Width() - 1, -scrolls_pos, r.Height() - 1, sd->GetHelp(), TC_WHITE);
753 }
754 }
755 break;
756
757 default:
758 break;
759 }
760 }
761
767 {
768 if (this->last_clicked != pe) this->SetDirty();
769 this->last_clicked = pe;
770 UpdateHelpTextSize();
771 }
772
773 void UpdateHelpTextSize()
774 {
775 NWidgetResizeBase *wid = this->GetWidget<NWidgetResizeBase>(WID_GO_HELP_TEXT);
776 this->vscroll_description->SetCount(this->last_clicked ? CeilDiv(this->last_clicked->GetMaxHelpHeight(wid->current_x), GetCharacterHeight(FS_NORMAL)) : 0);
777 }
778
779 void SetTab(WidgetID widget)
780 {
782 this->LowerWidget(widget);
783 GameOptionsWindow::active_tab = widget;
784
785 int plane;
786 switch (widget) {
787 case WID_GO_TAB_GENERAL: plane = 0; break;
788 case WID_GO_TAB_GRAPHICS: plane = 1; break;
789 case WID_GO_TAB_SOUND: plane = 2; break;
790 case WID_GO_TAB_SOCIAL: plane = 3; break;
791 case WID_GO_TAB_ADVANCED: plane = 4; break;
792 default: NOT_REACHED();
793 }
794
795 this->GetWidget<NWidgetStacked>(WID_GO_TAB_SELECTION)->SetDisplayedPlane(plane);
797 this->SetDirty();
798 }
799
800 void OnResize() override
801 {
802 this->vscroll->SetCapacityFromWidget(this, WID_GO_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical());
803 UpdateHelpTextSize();
804
805 bool changed = false;
806
807 NWidgetResizeBase *wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_GRF_DESCRIPTION);
808 int y = 0;
809 for (int i = 0; i < BaseGraphics::GetNumSets(); i++) {
810 std::string str = GetString(STR_JUST_RAW_STRING, BaseGraphics::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
811 y = std::max(y, GetStringHeight(str, wid->current_x));
812 }
813 changed |= wid->UpdateVerticalSize(y);
814
815 wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_SFX_DESCRIPTION);
816 y = 0;
817 for (int i = 0; i < BaseSounds::GetNumSets(); i++) {
818 std::string str = GetString(STR_JUST_RAW_STRING, BaseSounds::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
819 y = std::max(y, GetStringHeight(str, wid->current_x));
820 }
821 changed |= wid->UpdateVerticalSize(y);
822
823 wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_MUSIC_DESCRIPTION);
824 y = 0;
825 for (int i = 0; i < BaseMusic::GetNumSets(); i++) {
826 std::string str = GetString(STR_JUST_RAW_STRING, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
827 y = std::max(y, GetStringHeight(str, wid->current_x));
828 }
829 changed |= wid->UpdateVerticalSize(y);
830
831 wid = this->GetWidget<NWidgetResizeBase>(WID_GO_VIDEO_DRIVER_INFO);
832 std::string str = GetString(STR_GAME_OPTIONS_VIDEO_DRIVER_INFO, std::string{VideoDriver::GetInstance()->GetInfoString()});
833 y = GetStringHeight(str, wid->current_x);
834 changed |= wid->UpdateVerticalSize(y);
835
836 if (changed) this->ReInit(0, 0, this->flags.Test(WindowFlag::Centred));
837 }
838
839 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
840 {
841 switch (widget) {
844 Dimension d = maxdim(GetStringBoundingBox(STR_GAME_OPTIONS_SFX_VOLUME), GetStringBoundingBox(STR_GAME_OPTIONS_MUSIC_VOLUME));
845 d.width += padding.width;
846 d.height += padding.height;
847 size = maxdim(size, d);
848 break;
849 }
850
859 int selected;
860 size.width = std::max(size.width, GetDropDownListDimension(this->BuildDropDownList(widget, &selected)).width + padding.width);
861 break;
862 }
863
866 resize.width = 1;
867
868 size.height = 8 * resize.height + WidgetDimensions::scaled.framerect.Vertical();
869 break;
870
872 static const StringID setting_types[] = {
873 STR_CONFIG_SETTING_TYPE_CLIENT,
874 STR_CONFIG_SETTING_TYPE_COMPANY_MENU, STR_CONFIG_SETTING_TYPE_COMPANY_INGAME,
875 STR_CONFIG_SETTING_TYPE_GAME_MENU, STR_CONFIG_SETTING_TYPE_GAME_INGAME,
876 };
877 for (const auto &setting_type : setting_types) {
878 size.width = std::max(size.width, GetStringBoundingBox(GetString(STR_CONFIG_SETTING_TYPE, setting_type)).width + padding.width);
879 }
880 size.height = 2 * GetCharacterHeight(FS_NORMAL);
881 break;
882 }
883
884 case WID_GO_HELP_TEXT:
885 size.height = NUM_DESCRIPTION_LINES * GetCharacterHeight(FS_NORMAL);
886 break;
887
890 size.width = std::max(GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_CATEGORY).width, GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_TYPE).width);
891 break;
892
893 default:
894 break;
895 }
896 }
897
898 void OnPaint() override
899 {
900 if (this->GetWidget<NWidgetStacked>(WID_GO_TAB_SELECTION)->shown_plane != 4) {
901 this->DrawWidgets();
902 return;
903 }
904
905 if (this->closing_dropdown) {
906 this->closing_dropdown = false;
907 assert(this->valuedropdown_entry != nullptr);
908 this->valuedropdown_entry->SetButtons({});
909 this->valuedropdown_entry = nullptr;
910 }
911
912 /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */
913 const Rect panel = this->GetWidget<NWidgetBase>(WID_GO_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext);
914 StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing;
915 int new_warn_lines;
916 if (this->warn_missing == WHR_NONE) {
917 new_warn_lines = 0;
918 } else {
919 new_warn_lines = GetStringLineCount(GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]), panel.Width());
920 }
921 if (this->warn_lines != new_warn_lines) {
922 this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines);
923 this->warn_lines = new_warn_lines;
924 }
925
926 this->DrawWidgets();
927
928 /* Draw the 'some search results are hidden' notice. */
929 if (this->warn_missing != WHR_NONE) {
931 GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]),
932 TC_BLACK, SA_CENTER);
933 }
934 }
935
936 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
937 {
938 if (widget >= WID_GO_BASE_GRF_TEXTFILE && widget < WID_GO_BASE_GRF_TEXTFILE + TFT_CONTENT_END) {
939 if (BaseGraphics::GetUsedSet() == nullptr) return;
940
941 ShowBaseSetTextfileWindow(this, (TextfileType)(widget - WID_GO_BASE_GRF_TEXTFILE), BaseGraphics::GetUsedSet(), STR_CONTENT_TYPE_BASE_GRAPHICS);
942 return;
943 }
944 if (widget >= WID_GO_BASE_SFX_TEXTFILE && widget < WID_GO_BASE_SFX_TEXTFILE + TFT_CONTENT_END) {
945 if (BaseSounds::GetUsedSet() == nullptr) return;
946
947 ShowBaseSetTextfileWindow(this, (TextfileType)(widget - WID_GO_BASE_SFX_TEXTFILE), BaseSounds::GetUsedSet(), STR_CONTENT_TYPE_BASE_SOUNDS);
948 return;
949 }
950 if (widget >= WID_GO_BASE_MUSIC_TEXTFILE && widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_CONTENT_END) {
951 if (BaseMusic::GetUsedSet() == nullptr) return;
952
953 ShowBaseSetTextfileWindow(this, (TextfileType)(widget - WID_GO_BASE_MUSIC_TEXTFILE), BaseMusic::GetUsedSet(), STR_CONTENT_TYPE_BASE_MUSIC);
954 return;
955 }
956 switch (widget) {
959 case WID_GO_TAB_SOUND:
962 this->SetTab(widget);
963 break;
964
967 case PS_ASK:
968 case PS_NO:
970 break;
971
972 case PS_YES:
974 break;
975 }
976
979 break;
980
982 OpenBrowser(NETWORK_SURVEY_DETAILS_LINK);
983 break;
984
986 ShowSurveyResultTextfileWindow(this);
987 break;
988
989 case WID_GO_FULLSCREEN_BUTTON: // Click fullscreen on/off
990 /* try to toggle full-screen on/off */
991 if (!ToggleFullScreen(!_fullscreen)) {
992 ShowErrorMessage(GetEncodedString(STR_ERROR_FULLSCREEN_FAILED), {}, WL_ERROR);
993 }
997 break;
998
1001 ShowErrorMessage(GetEncodedString(STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART), {}, WL_INFO);
1005#ifndef __APPLE__
1010#endif
1011 break;
1012
1014 if (!_video_hw_accel) break;
1015
1018
1024 break;
1025
1028
1030 this->SetDirty();
1031
1033 ReInitAllWindows(true);
1034 break;
1035 }
1036
1037#ifdef HAS_TRUETYPE_FONT
1039 _fcsettings.prefer_sprite = !_fcsettings.prefer_sprite;
1040
1043 this->SetDirty();
1044
1045 InitFontCache(false);
1046 InitFontCache(true);
1047 ClearFontCache();
1051 ReInitAllWindows(true);
1052 break;
1053
1054 case WID_GO_GUI_FONT_AA:
1055 _fcsettings.global_aa = !_fcsettings.global_aa;
1056
1059
1060 ClearFontCache();
1061 break;
1062#endif /* HAS_TRUETYPE_FONT */
1063
1064 case WID_GO_GUI_SCALE:
1065 if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, _ctrl_pressed ? 0 : SCALE_NMARKS, this->gui_scale)) {
1066 this->SetWidgetDirty(widget);
1067 }
1068
1069 if (click_count > 0) this->mouse_capture_widget = widget;
1070 break;
1071
1073 {
1074 if (_gui_scale_cfg == -1) {
1077 } else {
1078 _gui_scale_cfg = -1;
1080 if (AdjustGUIZoom(false)) ReInitAllWindows(true);
1081 this->gui_scale = _gui_scale;
1082 }
1083 this->SetWidgetDirty(widget);
1085 break;
1086 }
1087
1089 auto *used_set = BaseGraphics::GetUsedSet();
1090 if (used_set == nullptr || !used_set->IsConfigurable()) break;
1091 GRFConfig &extra_cfg = used_set->GetOrCreateExtraConfig();
1092 if (extra_cfg.param.empty()) extra_cfg.SetParameterDefaults();
1093 OpenGRFParameterWindow(true, extra_cfg, _game_mode == GM_MENU);
1094 if (_game_mode == GM_MENU) this->reload = true;
1095 break;
1096 }
1097
1101 if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, 0, vol)) {
1102 if (widget == WID_GO_BASE_MUSIC_VOLUME) {
1104 } else {
1105 SetEffectVolume(vol);
1106 }
1107 this->SetWidgetDirty(widget);
1109 }
1110
1111 if (click_count > 0) this->mouse_capture_widget = widget;
1112 break;
1113 }
1114
1116 ShowMusicWindow();
1117 break;
1118 }
1119
1121 if (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->url.empty()) return;
1122 OpenBrowser(BaseGraphics::GetUsedSet()->url);
1123 break;
1124
1126 if (BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->url.empty()) return;
1127 OpenBrowser(BaseSounds::GetUsedSet()->url);
1128 break;
1129
1131 if (BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->url.empty()) return;
1132 OpenBrowser(BaseMusic::GetUsedSet()->url);
1133 break;
1134
1137 break;
1138
1141 break;
1142
1145 break;
1146
1155 int selected;
1156 DropDownList list = this->BuildDropDownList(widget, &selected);
1157 if (!list.empty()) {
1158 ShowDropDownList(this, std::move(list), selected, widget);
1159 } else {
1160 if (widget == WID_GO_RESOLUTION_DROPDOWN) ShowErrorMessage(GetEncodedString(STR_ERROR_RESOLUTION_LIST_FAILED), {}, WL_ERROR);
1161 }
1162 break;
1163 }
1164
1165 case WID_GO_EXPAND_ALL:
1166 this->manually_changed_folding = true;
1168 this->InvalidateData();
1169 break;
1170
1172 this->manually_changed_folding = true;
1174 this->InvalidateData();
1175 break;
1176
1177 case WID_GO_RESET_ALL:
1178 ShowQuery(
1179 GetEncodedString(STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION),
1180 GetEncodedString(STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT),
1181 this,
1183 );
1184 break;
1185
1187 int selected;
1188 DropDownList list = this->BuildDropDownList(widget, &selected);
1189 if (!list.empty()) {
1190 ShowDropDownList(this, std::move(list), this->filter.mode, widget);
1191 }
1192 break;
1193 }
1194
1195 case WID_GO_TYPE_DROPDOWN: {
1196 int selected;
1197 DropDownList list = this->BuildDropDownList(widget, &selected);
1198 if (!list.empty()) {
1199 ShowDropDownList(this, std::move(list), this->filter.type, widget);
1200 }
1201 break;
1202 }
1203
1205 OptionsPanelClick(pt);
1206 break;
1207 }
1208 }
1209
1210 void OptionsPanelClick(Point pt)
1211 {
1212 int32_t btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GO_OPTIONSPANEL, WidgetDimensions::scaled.framerect.top);
1213 if (btn == INT32_MAX || btn < this->warn_lines) return;
1214 btn -= this->warn_lines;
1215
1216 uint cur_row = 0;
1218
1219 if (clicked_entry == nullptr) return; // Clicked below the last setting of the page
1220
1221 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_GO_OPTIONSPANEL);
1222 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
1223 if (x < 0) return; // Clicked left of the entry
1224
1225 SettingsPage *clicked_page = dynamic_cast<SettingsPage*>(clicked_entry);
1226 if (clicked_page != nullptr) {
1227 this->SetDisplayedHelpText(nullptr);
1228 clicked_page->folded = !clicked_page->folded; // Flip 'folded'-ness of the sub-page
1229
1230 this->manually_changed_folding = true;
1231
1232 this->InvalidateData();
1233 return;
1234 }
1235
1236 SettingEntry *pe = dynamic_cast<SettingEntry*>(clicked_entry);
1237 assert(pe != nullptr);
1238 const IntSettingDesc *sd = pe->setting;
1239
1240 /* return if action is only active in network, or only settable by server */
1241 if (!sd->IsEditable()) {
1242 this->SetDisplayedHelpText(pe);
1243 return;
1244 }
1245
1246 auto [min_val, max_val] = sd->GetRange();
1247 int32_t value = sd->Read(ResolveObject(settings_ptr, sd));
1248
1249 /* clicked on the icon on the left side. Either scroller, bool on/off or dropdown */
1250 if (x < SETTING_BUTTON_WIDTH && sd->flags.Test(SettingFlag::GuiDropdown)) {
1251 this->SetDisplayedHelpText(pe);
1252
1253 if (this->valuedropdown_entry == pe) {
1254 /* unclick the dropdown */
1256 this->closing_dropdown = false;
1257 this->valuedropdown_entry->SetButtons({});
1258 this->valuedropdown_entry = nullptr;
1259 } else {
1260 if (this->valuedropdown_entry != nullptr) this->valuedropdown_entry->SetButtons({});
1261 this->closing_dropdown = false;
1262
1263 int rel_y = (pt.y - wid->pos_y - WidgetDimensions::scaled.framerect.top) % wid->resize_y;
1264
1265 Rect wi_rect;
1266 wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
1267 wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
1268 wi_rect.top = pt.y - rel_y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2;
1269 wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
1270
1271 /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
1272 if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
1273 this->valuedropdown_entry = pe;
1274 this->valuedropdown_entry->SetButtons(SettingEntryFlag::LeftDepressed);
1275
1276 DropDownList list;
1277 for (int32_t i = min_val; i <= static_cast<int32_t>(max_val); i++) {
1278 auto [param1, param2] = sd->GetValueParams(i);
1279 list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_STRING1, param1, param2), i));
1280 }
1281
1282 ShowDropDownListAt(this, std::move(list), value, WID_GO_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
1283 }
1284 }
1285 this->SetDirty();
1286 } else if (x < SETTING_BUTTON_WIDTH) {
1287 this->SetDisplayedHelpText(pe);
1288 int32_t oldvalue = value;
1289
1290 if (sd->IsBoolSetting()) {
1291 value ^= 1;
1292 } else {
1293 /* Add a dynamic step-size to the scroller. In a maximum of
1294 * 50-steps you should be able to get from min to max,
1295 * unless specified otherwise in the 'interval' variable
1296 * of the current setting. */
1297 uint32_t step = (sd->interval == 0) ? ((max_val - min_val) / 50) : sd->interval;
1298 if (step == 0) step = 1;
1299
1300 /* don't allow too fast scrolling */
1301 if (this->flags.Test(WindowFlag::Timeout) && this->timeout_timer > 1) {
1302 _left_button_clicked = false;
1303 return;
1304 }
1305
1306 /* Increase or decrease the value and clamp it to extremes */
1307 if (x >= SETTING_BUTTON_WIDTH / 2) {
1308 value += step;
1309 if (min_val < 0) {
1310 assert(static_cast<int32_t>(max_val) >= 0);
1311 if (value > static_cast<int32_t>(max_val)) value = static_cast<int32_t>(max_val);
1312 } else {
1313 if (static_cast<uint32_t>(value) > max_val) value = static_cast<int32_t>(max_val);
1314 }
1315 if (value < min_val) value = min_val; // skip between "disabled" and minimum
1316 } else {
1317 value -= step;
1318 if (value < min_val) value = sd->flags.Test(SettingFlag::GuiZeroIsSpecial) ? 0 : min_val;
1319 }
1320
1321 /* Set up scroller timeout for numeric values */
1322 if (value != oldvalue) {
1323 if (this->clicked_entry != nullptr) { // Release previous buttons if any
1324 this->clicked_entry->SetButtons({});
1325 }
1326 this->clicked_entry = pe;
1328 this->SetTimeout();
1329 _left_button_clicked = false;
1330 }
1331 }
1332
1333 if (value != oldvalue) {
1334 SetSettingValue(sd, value);
1335 this->SetDirty();
1336 }
1337 } else {
1338 /* Only open editbox if clicked for the second time, and only for types where it is sensible for. */
1339 if (this->last_clicked == pe && !sd->IsBoolSetting() && !sd->flags.Test(SettingFlag::GuiDropdown)) {
1340 int64_t value64 = value;
1341 /* Show the correct currency-translated value */
1342 if (sd->flags.Test(SettingFlag::GuiCurrency)) value64 *= GetCurrency().rate;
1343
1344 CharSetFilter charset_filter = CS_NUMERAL; //default, only numeric input allowed
1345 if (min_val < 0) charset_filter = CS_NUMERAL_SIGNED; // special case, also allow '-' sign for negative input
1346
1347 this->valuewindow_entry = pe;
1348 /* Limit string length to 14 so that MAX_INT32 * max currency rate doesn't exceed MAX_INT64. */
1349 ShowQueryString(GetString(STR_JUST_INT, value64), STR_CONFIG_SETTING_QUERY_CAPTION, 15, this, charset_filter, QueryStringFlag::EnableDefault);
1350 }
1351 this->SetDisplayedHelpText(pe);
1352 }
1353 }
1354
1355 void OnTimeout() override
1356 {
1357 if (this->clicked_entry != nullptr) { // On timeout, release any depressed buttons
1358 this->clicked_entry->SetButtons({});
1359 this->clicked_entry = nullptr;
1360 this->SetDirty();
1361 }
1362 }
1363
1364 void OnQueryTextFinished(std::optional<std::string> str) override
1365 {
1366 /* The user pressed cancel */
1367 if (!str.has_value()) return;
1368
1369 assert(this->valuewindow_entry != nullptr);
1370 const IntSettingDesc *sd = this->valuewindow_entry->setting;
1371
1372 int32_t value;
1373 if (!str->empty()) {
1374 auto llvalue = ParseInteger<int64_t>(*str, 10, true);
1375 if (!llvalue.has_value()) return;
1376
1377 /* Save the correct currency-translated value */
1378 if (sd->flags.Test(SettingFlag::GuiCurrency)) llvalue = *llvalue / GetCurrency().rate;
1379
1380 value = ClampTo<int32_t>(*llvalue);
1381 } else {
1382 value = sd->GetDefaultValue();
1383 }
1384
1385 SetSettingValue(this->valuewindow_entry->setting, value);
1386 this->SetDirty();
1387 }
1388
1389 void OnMouseLoop() override
1390 {
1391 if (_left_button_down || this->gui_scale == _gui_scale) return;
1392
1393 _gui_scale_cfg = this->gui_scale;
1394
1395 if (AdjustGUIZoom(false)) {
1396 ReInitAllWindows(true);
1398 this->SetDirty();
1399 }
1400 }
1401
1402 void OnDropdownSelect(WidgetID widget, int index, int) override
1403 {
1404 switch (widget) {
1405 case WID_GO_CURRENCY_DROPDOWN: // Currency
1406 if (index == CURRENCY_CUSTOM) ShowCustCurrency();
1407 this->opt->locale.currency = index;
1408 ReInitAllWindows(false);
1409 break;
1410
1411 case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options
1414 this->SetDirty();
1415 break;
1416
1417 case WID_GO_LANG_DROPDOWN: // Change interface language
1421 ClearAllCachedNames();
1423 CheckBlitter();
1424 ReInitAllWindows(false);
1425 break;
1426
1427 case WID_GO_RESOLUTION_DROPDOWN: // Change resolution
1428 if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) {
1429 this->SetDirty();
1430 }
1431 break;
1432
1434 _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index);
1436 /* Show warning to the user that this refresh rate might not be suitable on
1437 * larger maps with many NewGRFs and vehicles. */
1438 ShowErrorMessage(GetEncodedString(STR_GAME_OPTIONS_REFRESH_RATE_WARNING), {}, WL_INFO);
1439 }
1440 break;
1441 }
1442
1444 if (_game_mode == GM_MENU) {
1446 auto set = BaseGraphics::GetSet(index);
1448 this->reload = true;
1449 this->InvalidateData();
1450 }
1451 break;
1452
1454 ChangeSoundSet(index);
1455 break;
1456
1458 ChangeMusicSet(index);
1459 break;
1460
1462 this->filter.mode = (RestrictionMode)index;
1463 if (this->filter.mode == RM_CHANGED_AGAINST_DEFAULT ||
1464 this->filter.mode == RM_CHANGED_AGAINST_NEW) {
1465
1466 if (!this->manually_changed_folding) {
1467 /* Expand all when selecting 'changes'. Update the filter state first, in case it becomes less restrictive in some cases. */
1470 }
1471 } else {
1472 /* Non-'changes' filter. Save as default. */
1474 }
1475 this->InvalidateData();
1476 break;
1477
1479 this->filter.type = (SettingType)index;
1480 this->InvalidateData();
1481 break;
1482
1484 /* Deal with drop down boxes on the panel. */
1485 assert(this->valuedropdown_entry != nullptr);
1486 const IntSettingDesc *sd = this->valuedropdown_entry->setting;
1487 assert(sd->flags.Test(SettingFlag::GuiDropdown));
1488
1489 SetSettingValue(sd, index);
1490 this->SetDirty();
1491 break;
1492 }
1493 }
1494
1495 void OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close) override
1496 {
1497 if (widget != WID_GO_SETTING_DROPDOWN) {
1498 /* Normally the default implementation of OnDropdownClose() takes care of
1499 * a few things. We want that behaviour here too, but only for
1500 * "normal" dropdown boxes. The special dropdown boxes added for every
1501 * setting that needs one can't have this call. */
1502 Window::OnDropdownClose(pt, widget, index, click_result, instant_close);
1503 } else {
1504 /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
1505 * the same dropdown button was clicked again, and then not open the dropdown again.
1506 * So, we only remember that it was closed, and process it on the next OnPaint, which is
1507 * after OnClick. */
1508 assert(this->valuedropdown_entry != nullptr);
1509 this->closing_dropdown = true;
1510 this->SetDirty();
1511 }
1512 }
1513
1519 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1520 {
1521 if (!gui_scope) return;
1526
1527#ifndef __APPLE__
1530#endif
1531
1534#ifdef HAS_TRUETYPE_FONT
1538#endif /* HAS_TRUETYPE_FONT */
1539
1540 this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
1541
1543
1547
1548 for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) {
1552 }
1553
1555
1556 /* Update which settings are to be visible. */
1557 RestrictionMode min_level = (this->filter.mode <= RM_ALL) ? this->filter.mode : RM_BASIC;
1558 this->filter.min_cat = min_level;
1559 this->filter.type_hides = false;
1561
1562 if (this->filter.string.IsEmpty()) {
1563 this->warn_missing = WHR_NONE;
1564 } else if (min_level < this->filter.min_cat) {
1565 this->warn_missing = this->filter.type_hides ? WHR_CATEGORY_TYPE : WHR_CATEGORY;
1566 } else {
1567 this->warn_missing = this->filter.type_hides ? WHR_TYPE : WHR_NONE;
1568 }
1569 this->vscroll->SetCount(GetSettingsTree().Length() + this->warn_lines);
1570
1571 if (this->last_clicked != nullptr && !GetSettingsTree().IsVisible(this->last_clicked)) {
1572 this->SetDisplayedHelpText(nullptr);
1573 }
1574
1575 bool all_folded = true;
1576 bool all_unfolded = true;
1577 GetSettingsTree().GetFoldingState(all_folded, all_unfolded);
1578 this->SetWidgetDisabledState(WID_GO_EXPAND_ALL, all_unfolded);
1580 }
1581
1582 void OnEditboxChanged(WidgetID wid) override
1583 {
1584 if (wid == WID_GO_FILTER) {
1585 this->filter.string.SetFilterTerm(this->filter_editbox.text.GetText());
1586 if (!this->filter.string.IsEmpty() && !this->manually_changed_folding) {
1587 /* User never expanded/collapsed single pages and entered a filter term.
1588 * Expand everything, to save weird expand clicks, */
1590 }
1591 this->InvalidateData();
1592 }
1593 }
1594};
1595
1596static constexpr NWidgetPart _nested_game_options_widgets[] = {
1599 NWidget(WWT_CAPTION, GAME_OPTIONS_BACKGROUND), SetStringTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1601 EndContainer(),
1604 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1605 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1606 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1607 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1608 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1609 EndContainer(),
1610 EndContainer(),
1613 /* General tab */
1617 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_LANG_DROPDOWN), SetToolTip(STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1618 EndContainer(),
1619
1621 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_AUTOSAVE_DROPDOWN), SetToolTip(STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1622 EndContainer(),
1623
1624 NWidget(WWT_FRAME, GAME_OPTIONS_BACKGROUND), SetStringTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME), SetTextStyle(GAME_OPTIONS_FRAME),
1625 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_CURRENCY_DROPDOWN), SetToolTip(STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1626 EndContainer(),
1627
1628 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_SURVEY_SEL),
1629 NWidget(WWT_FRAME, GAME_OPTIONS_BACKGROUND), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME), SetTextStyle(GAME_OPTIONS_FRAME), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1633 EndContainer(),
1635 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1636 NWidget(WWT_TEXTBTN, GAME_OPTIONS_BUTTON, 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),
1637 EndContainer(),
1638 EndContainer(),
1639 EndContainer(),
1640 EndContainer(),
1641 NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize
1642 EndContainer(),
1643
1644 /* Graphics tab */
1650 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME), SetTextStyle(GAME_OPTIONS_LABEL),
1651 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_GUI_SCALE), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetResize(1, 0), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP),
1652 EndContainer(),
1656 EndContainer(),
1660 EndContainer(),
1661#ifdef HAS_TRUETYPE_FONT
1665 EndContainer(),
1669 EndContainer(),
1670#endif /* HAS_TRUETYPE_FONT */
1671 EndContainer(),
1672 EndContainer(),
1673
1677 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_RESOLUTION), SetTextStyle(GAME_OPTIONS_LABEL),
1678 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_RESOLUTION_DROPDOWN), SetFill(1, 0), SetToolTip(STR_GAME_OPTIONS_RESOLUTION_TOOLTIP),
1679 EndContainer(),
1681 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_REFRESH_RATE), SetTextStyle(GAME_OPTIONS_LABEL),
1682 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_REFRESH_RATE_DROPDOWN), SetFill(1, 0), SetToolTip(STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP),
1683 EndContainer(),
1687 EndContainer(),
1691 EndContainer(),
1692#ifndef __APPLE__
1696 EndContainer(),
1697#endif
1699 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_VIDEO_DRIVER_INFO), SetMinimalTextLines(1, 0), SetFill(1, 0), SetResize(1, 0),
1700 EndContainer(),
1701 EndContainer(),
1702 EndContainer(),
1703
1706 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_BASE_GRF_DROPDOWN), SetToolTip(STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1708 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_GRF_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1709 EndContainer(),
1710 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_BASE_GRF_DESCRIPTION), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1713 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_GRF_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1714 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1715 EndContainer(),
1717 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1718 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1719 EndContainer(),
1720 EndContainer(),
1721 EndContainer(),
1722 EndContainer(),
1723 NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize
1724 EndContainer(),
1725
1726 /* Sound/Music tab */
1731 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_SFX_VOLUME), SetStringTip(STR_GAME_OPTIONS_SFX_VOLUME), SetTextStyle(GAME_OPTIONS_LABEL),
1732 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_VOLUME), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetResize(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
1733 EndContainer(),
1735 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_MUSIC_VOLUME), SetStringTip(STR_GAME_OPTIONS_MUSIC_VOLUME), SetTextStyle(GAME_OPTIONS_LABEL),
1736 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_VOLUME), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetResize(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
1737 EndContainer(),
1738 EndContainer(),
1739
1742 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_BASE_SFX_DROPDOWN), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1743 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_SFX_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1744 EndContainer(),
1745 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1748 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_SFX_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1749 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1750 EndContainer(),
1752 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1753 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1754 EndContainer(),
1755 EndContainer(),
1756 EndContainer(),
1757
1760 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_DROPDOWN), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1761 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1762 EndContainer(),
1764 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1766 NWidget(WWT_PUSHIMGBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
1767 EndContainer(),
1768 EndContainer(),
1771 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1772 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1773 EndContainer(),
1775 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1776 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1777 EndContainer(),
1778 EndContainer(),
1779 EndContainer(),
1780 EndContainer(),
1781 NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize
1782 EndContainer(),
1783
1784 /* Social tab */
1787 NWidget(NWID_SPACER), SetFill(1, 1), SetResize(1, 1), // Allows this pane to resize
1788 EndContainer(),
1789
1790 /* Advanced settings tab */
1794 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_RESTRICT_CATEGORY), SetStringTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY), SetTextStyle(GAME_OPTIONS_LABEL),
1795 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_RESTRICT_DROPDOWN), SetToolTip(STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
1796 EndContainer(),
1798 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_RESTRICT_TYPE), SetStringTip(STR_CONFIG_SETTING_RESTRICT_TYPE), SetTextStyle(GAME_OPTIONS_LABEL),
1799 NWidget(WWT_DROPDOWN, GAME_OPTIONS_BUTTON, WID_GO_TYPE_DROPDOWN), SetToolTip(STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
1800 EndContainer(),
1802 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_CONFIG_SETTING_FILTER_TITLE), SetTextStyle(GAME_OPTIONS_LABEL),
1803 NWidget(WWT_EDITBOX, GAME_OPTIONS_BACKGROUND, WID_GO_FILTER), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1804 EndContainer(),
1805 EndContainer(),
1806
1809 EndContainer(),
1811 EndContainer(),
1812
1814 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_EXPAND_ALL), SetStringTip(STR_CONFIG_SETTING_EXPAND_ALL), SetFill(1, 0), SetResize(1, 0),
1815 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_COLLAPSE_ALL), SetStringTip(STR_CONFIG_SETTING_COLLAPSE_ALL), SetFill(1, 0), SetResize(1, 0),
1816 NWidget(WWT_PUSHTXTBTN, GAME_OPTIONS_BUTTON, WID_GO_RESET_ALL), SetStringTip(STR_CONFIG_SETTING_RESET_ALL), SetFill(1, 0), SetResize(1, 0),
1817 EndContainer(),
1818
1819 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_SETTING_PROPERTIES), SetFill(1, 0), SetResize(1, 0),
1823 EndContainer(),
1824 EndContainer(),
1825 EndContainer(),
1826
1828 NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
1830 EndContainer(),
1831 EndContainer(),
1832};
1833
1834static WindowDesc _game_options_desc(
1835 WDP_CENTER, "game_options", 0, 0,
1837 {},
1838 _nested_game_options_widgets
1839);
1840
1843{
1845 new GameOptionsWindow(_game_options_desc);
1846}
1847
1857void DrawArrowButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_left, bool clickable_right)
1858{
1859 int colour = GetColourGradient(button_colour, SHADE_DARKER);
1860 Dimension dim = NWidgetScrollbar::GetHorizontalDimension();
1861
1862 Rect lr = {x, y, x + (int)dim.width - 1, y + (int)dim.height - 1};
1863 Rect rr = {x + (int)dim.width, y, x + (int)dim.width * 2 - 1, y + (int)dim.height - 1};
1864
1865 DrawFrameRect(lr, button_colour, (state == 1) ? FrameFlag::Lowered : FrameFlags{});
1866 DrawFrameRect(rr, button_colour, (state == 2) ? FrameFlag::Lowered : FrameFlags{});
1867 DrawSpriteIgnorePadding(SPR_ARROW_LEFT, PAL_NONE, lr, SA_CENTER);
1868 DrawSpriteIgnorePadding(SPR_ARROW_RIGHT, PAL_NONE, rr, SA_CENTER);
1869
1870 /* Grey out the buttons that aren't clickable */
1871 bool rtl = _current_text_dir == TD_RTL;
1872 if (rtl ? !clickable_right : !clickable_left) {
1874 }
1875 if (rtl ? !clickable_left : !clickable_right) {
1877 }
1878}
1879
1889void DrawUpDownButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_up, bool clickable_down)
1890{
1891 int colour = GetColourGradient(button_colour, SHADE_DARKER);
1892
1893 Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
1896
1897 DrawFrameRect(ur, button_colour, (state == 1) ? FrameFlag::Lowered : FrameFlags{});
1898 DrawFrameRect(dr, button_colour, (state == 2) ? FrameFlag::Lowered : FrameFlags{});
1899 DrawSpriteIgnorePadding(SPR_ARROW_UP, PAL_NONE, ur, SA_CENTER);
1900 DrawSpriteIgnorePadding(SPR_ARROW_DOWN, PAL_NONE, dr, SA_CENTER);
1901
1902 /* Grey out the buttons that aren't clickable */
1903 if (!clickable_up) GfxFillRect(ur.Shrink(WidgetDimensions::scaled.bevel), colour, FILLRECT_CHECKER);
1904 if (!clickable_down) GfxFillRect(dr.Shrink(WidgetDimensions::scaled.bevel), colour, FILLRECT_CHECKER);
1905}
1906
1915void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
1916{
1917 int colour = GetColourGradient(button_colour, SHADE_DARKER);
1918
1919 Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
1920
1921 DrawFrameRect(r, button_colour, state ? FrameFlag::Lowered : FrameFlags{});
1922 DrawSpriteIgnorePadding(SPR_ARROW_DOWN, PAL_NONE, r, SA_CENTER);
1923
1924 if (!clickable) {
1926 }
1927}
1928
1938void DrawBoolButton(int x, int y, Colours button_colour, Colours background, bool state, bool clickable)
1939{
1940 Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
1941 DrawFrameRect(r, state ? COLOUR_GREEN : background, state ? FrameFlags{FrameFlag::Lowered} : FrameFlags{FrameFlag::Lowered, FrameFlag::BorderOnly});
1942 if (!clickable) {
1943 GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(state ? COLOUR_GREEN : background, SHADE_DARKER), FILLRECT_CHECKER);
1944 }
1945
1946 Rect button_rect = r.WithWidth(SETTING_BUTTON_WIDTH / 3, state ^ (_current_text_dir == TD_RTL));
1947 DrawFrameRect(button_rect, button_colour, {});
1948 if (!clickable) {
1949 GfxFillRect(button_rect.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(button_colour, SHADE_DARKER), FILLRECT_CHECKER);
1950 }
1951}
1952
1954 WidgetID query_widget{};
1955
1957 {
1958 this->InitNested();
1959
1960 SetButtonState();
1961 }
1962
1963 void SetButtonState()
1964 {
1966 this->SetWidgetDisabledState(WID_CC_RATE_UP, GetCustomCurrency().rate == UINT16_MAX);
1969 }
1970
1971 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1972 {
1973 switch (widget) {
1974 case WID_CC_RATE: return GetString(STR_CURRENCY_EXCHANGE_RATE, 1, 1);
1975 case WID_CC_SEPARATOR: return GetString(STR_CURRENCY_SEPARATOR, GetCustomCurrency().separator);
1976 case WID_CC_PREFIX: return GetString(STR_CURRENCY_PREFIX, GetCustomCurrency().prefix);
1977 case WID_CC_SUFFIX: return GetString(STR_CURRENCY_SUFFIX, GetCustomCurrency().suffix);
1978 case WID_CC_YEAR:
1979 return GetString((GetCustomCurrency().to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER, GetCustomCurrency().to_euro);
1980
1981 case WID_CC_PREVIEW:
1982 return GetString(STR_CURRENCY_PREVIEW, 10000);
1983
1984 default:
1985 return this->Window::GetWidgetString(widget, stringid);
1986 }
1987 }
1988
1989 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1990 {
1991 switch (widget) {
1992 /* Set the appropriate width for the up/down buttons. */
1993 case WID_CC_RATE_DOWN:
1994 case WID_CC_RATE_UP:
1995 case WID_CC_YEAR_DOWN:
1996 case WID_CC_YEAR_UP:
1997 size = maxdim(size, {(uint)SETTING_BUTTON_WIDTH / 2, (uint)SETTING_BUTTON_HEIGHT});
1998 break;
1999
2000 /* Set the appropriate width for the edit buttons. */
2002 case WID_CC_PREFIX_EDIT:
2003 case WID_CC_SUFFIX_EDIT:
2004 size = maxdim(size, {(uint)SETTING_BUTTON_WIDTH, (uint)SETTING_BUTTON_HEIGHT});
2005 break;
2006
2007 /* Make sure the window is wide enough for the widest exchange rate */
2008 case WID_CC_RATE:
2009 size = GetStringBoundingBox(GetString(STR_CURRENCY_EXCHANGE_RATE, 1, INT32_MAX));
2010 break;
2011 }
2012 }
2013
2014 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
2015 {
2016 int line = 0;
2017 int len = 0;
2018 std::string str;
2020
2021 switch (widget) {
2022 case WID_CC_RATE_DOWN:
2023 if (GetCustomCurrency().rate > 1) GetCustomCurrency().rate--;
2024 if (GetCustomCurrency().rate == 1) this->DisableWidget(WID_CC_RATE_DOWN);
2026 break;
2027
2028 case WID_CC_RATE_UP:
2029 if (GetCustomCurrency().rate < UINT16_MAX) GetCustomCurrency().rate++;
2030 if (GetCustomCurrency().rate == UINT16_MAX) this->DisableWidget(WID_CC_RATE_UP);
2032 break;
2033
2034 case WID_CC_RATE:
2035 str = GetString(STR_JUST_INT, GetCustomCurrency().rate);
2036 len = 5;
2037 line = WID_CC_RATE;
2038 afilter = CS_NUMERAL;
2039 break;
2040
2042 case WID_CC_SEPARATOR:
2044 len = 7;
2045 line = WID_CC_SEPARATOR;
2046 break;
2047
2048 case WID_CC_PREFIX_EDIT:
2049 case WID_CC_PREFIX:
2050 str = GetCustomCurrency().prefix;
2051 len = 15;
2052 line = WID_CC_PREFIX;
2053 break;
2054
2055 case WID_CC_SUFFIX_EDIT:
2056 case WID_CC_SUFFIX:
2057 str = GetCustomCurrency().suffix;
2058 len = 15;
2059 line = WID_CC_SUFFIX;
2060 break;
2061
2062 case WID_CC_YEAR_DOWN:
2066 break;
2067
2068 case WID_CC_YEAR_UP:
2072 break;
2073
2074 case WID_CC_YEAR:
2075 str = GetString(STR_JUST_INT, GetCustomCurrency().to_euro);
2076 len = 7;
2077 line = WID_CC_YEAR;
2078 afilter = CS_NUMERAL;
2079 break;
2080 }
2081
2082 if (len != 0) {
2083 this->query_widget = line;
2084 ShowQueryString(str, STR_CURRENCY_CHANGE_PARAMETER, len + 1, this, afilter, {});
2085 }
2086
2087 this->SetTimeout();
2088 this->SetDirty();
2089 }
2090
2091 void OnQueryTextFinished(std::optional<std::string> str) override
2092 {
2093 if (!str.has_value()) return;
2094
2095 switch (this->query_widget) {
2096 case WID_CC_RATE: {
2097 auto val = ParseInteger(*str, 10, true);
2098 if (!val.has_value()) return;
2099 GetCustomCurrency().rate = Clamp(*val, 1, UINT16_MAX);
2100 break;
2101 }
2102
2103 case WID_CC_SEPARATOR: // Thousands separator
2104 GetCustomCurrency().separator = std::move(*str);
2105 break;
2106
2107 case WID_CC_PREFIX:
2108 GetCustomCurrency().prefix = std::move(*str);
2109 break;
2110
2111 case WID_CC_SUFFIX:
2112 GetCustomCurrency().suffix = std::move(*str);
2113 break;
2114
2115 case WID_CC_YEAR: { // Year to switch to euro
2117 if (!str->empty()) {
2118 auto val = ParseInteger(*str, 10, true);
2119 if (!val.has_value()) return;
2121 }
2122 GetCustomCurrency().to_euro = year;
2123 break;
2124 }
2125 }
2127 SetButtonState();
2128 }
2129
2130 void OnTimeout() override
2131 {
2132 this->SetDirty();
2133 }
2134};
2135
2136static constexpr NWidgetPart _nested_cust_currency_widgets[] = {
2138 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
2139 NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_CURRENCY_WINDOW, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2140 EndContainer(),
2141 NWidget(WWT_PANEL, COLOUR_GREY),
2146 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_DOWN), SetArrowWidgetTypeTip(AWV_DECREASE, STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP),
2147 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_UP), SetArrowWidgetTypeTip(AWV_INCREASE, STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP),
2148 EndContainer(),
2149 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_RATE), SetToolTip(STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP), SetFill(1, 0),
2150 EndContainer(),
2152 NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SEPARATOR_EDIT), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(0, 1),
2153 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_SEPARATOR), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(1, 0),
2154 EndContainer(),
2156 NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_PREFIX_EDIT), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(0, 1),
2157 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_PREFIX), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(1, 0),
2158 EndContainer(),
2160 NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SUFFIX_EDIT), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(0, 1),
2161 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_SUFFIX), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(1, 0),
2162 EndContainer(),
2165 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_DOWN), SetArrowWidgetTypeTip(AWV_DECREASE, STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
2166 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_UP), SetArrowWidgetTypeTip(AWV_INCREASE, STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
2167 EndContainer(),
2168 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_YEAR), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP), SetFill(1, 0),
2169 EndContainer(),
2170 EndContainer(),
2171 NWidget(WWT_LABEL, INVALID_COLOUR, WID_CC_PREVIEW),
2172 SetToolTip(STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP),
2173 EndContainer(),
2174 EndContainer(),
2175};
2176
2177static WindowDesc _cust_currency_desc(
2178 WDP_CENTER, {}, 0, 0,
2180 {},
2181 _nested_cust_currency_widgets
2182);
2183
2185static void ShowCustCurrency()
2186{
2188 new CustomCurrencyWindow(_cust_currency_desc);
2189}
void UpdateAllVirtCoords()
Update the viewport coordinates of all signs.
Base functions for all AIs.
Generic functions for replacing base data (graphics, sounds).
Generic functions for replacing base graphics data.
Generic functions for replacing base music data.
Generic functions for replacing base sounds data.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
static const GraphicsSet * GetUsedSet()
Return the used set.
static int GetNumSets()
Count the number of available graphics sets.
static const GraphicsSet * GetSet(int index)
Get the name of the graphics set at the specified index.
static bool SetSet(const GraphicsSet *set)
Set the set to be used.
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
Enum-as-bit-set wrapper.
static MusicDriver * GetInstance()
Get the currently active instance of the music driver.
virtual void SetVolume(uint8_t vol)=0
Set the volume, if possible.
Baseclass for nested widgets.
virtual void FillWidgetLookup(WidgetLookup &widget_lookup)=0
Fill the Window::widget_lookup with pointers to nested widgets in the tree.
uint current_x
Current horizontal size (after resizing).
int pos_y
Vertical position of top-left corner of the widget in the window.
int pos_x
Horizontal position of top-left corner of the widget in the window.
uint resize_y
Vertical resize step (0 means not resizable).
void Add(std::unique_ptr< NWidgetBase > &&wid)
Append widget wid to container.
Definition widget.cpp:1313
std::vector< std::unique_ptr< NWidgetBase > > children
Child widgets in container.
void SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_post)
Set additional pre/inter/post space for the container.
Definition widget.cpp:1536
Base class for a resizable nested widget.
bool UpdateVerticalSize(uint min_y)
Set absolute (post-scaling) minimal size of the widget.
Definition widget.cpp:1127
void FillWidgetLookup(WidgetLookup &widget_lookup) override
Fill the Window::widget_lookup with pointers to nested widgets in the tree.
void Draw(const Window *w) override
Draw the widgets of the tree.
void SetupSmallestSize(Window *w) override
Compute smallest size needed by the widget.
std::string & GetWidestPlugin(T SocialIntegrationPlugin::*member) const
Find of all the plugins the one where the member is the widest (in pixels).
Vertical container.
void SetupSmallestSize(Window *w) override
Compute smallest size needed by the widget.
Definition widget.cpp:1762
Scrollbar data structure.
size_type GetCapacity() const
Gets the number of visible elements of the scrollbar.
void SetCount(size_t num)
Sets the number of elements in the list.
void SetCapacity(size_t capacity)
Set the capacity of visible elements.
size_type GetScrolledRowFromWidget(int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition widget.cpp:2482
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition widget.cpp:2556
size_type GetCount() const
Gets the number of elements in the list.
size_type GetPosition() const
Gets the position of the first visible element in the list.
std::string social_platform
Social platform this plugin is for.
std::string name
Name of the plugin.
std::string version
Version of the plugin.
@ PLATFORM_NOT_RUNNING
The plugin failed to initialize because the Social Platform is not running.
@ UNSUPPORTED_API
The plugin does not support the current API version.
@ RUNNING
The plugin is successfully loaded and running.
@ FAILED
The plugin failed to initialize.
@ DUPLICATE
Another plugin of the same Social Platform is already loaded.
@ INVALID_SIGNATURE
The signature of the plugin is invalid.
@ UNLOADED
The plugin is unloaded upon request.
static std::vector< SocialIntegrationPlugin * > GetPlugins()
Get the list of loaded social integration plugins.
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
virtual void ToggleVsync(bool vsync)
Change the vsync setting.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
virtual std::vector< int > GetListOfMonitorRefreshRates()
Get a list of refresh rates of each available monitor.
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:40
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:38
int hsep_indent
Width of indentation for tree layouts.
Definition window_gui.h:63
Functions related to commands.
Definition of stuff that is very close to a company, like the company struct itself.
Functions related to companies.
Configuration options of the network stuff.
static const std::string NETWORK_SURVEY_DETAILS_LINK
Link with more details & privacy statement of the survey.
Definition config.h:30
std::array< CurrencySpec, CURRENCY_END > _currency_specs
Array of currencies used by the system.
Definition currency.cpp:79
Functions to handle different currencies.
static constexpr TimerGameCalendar::Year MIN_EURO_YEAR
The earliest year custom currencies may switch to the Euro.
Definition currency.h:19
@ CURRENCY_CUSTOM
Custom currency.
Definition currency.h:58
CurrencySpec & GetCustomCurrency()
Get the custom currency.
Definition currency.h:109
static constexpr TimerGameCalendar::Year CF_NOEURO
Currency never switches to the Euro (as far as known).
Definition currency.h:17
const CurrencySpec & GetCurrency()
Get the currently selected currency.
Definition currency.h:118
std::vector< Dimension > _resolutions
List of resolutions.
Definition driver.cpp:28
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist)
Show a drop down list.
Definition dropdown.cpp:414
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
Definition dropdown.cpp:373
void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, bool instant_close, bool persist)
Show a drop down list.
Definition dropdown.cpp:396
Common drop down list components.
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Functions related to errors.
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition error.h:26
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Factory to 'query' all available blitters.
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition fileio_type.h:95
void InitFontCache(bool monospace)
(Re)initialize the font cache related things, i.e.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
Functions to read fonts from files and cache them.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition gfx.cpp:705
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:958
int GetStringLineCount(std::string_view str, int maxw)
Calculates number of lines of string.
Definition gfx.cpp:729
bool _left_button_down
Is left mouse button pressed?
Definition gfx.cpp:41
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:887
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:658
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
bool _left_button_clicked
Is left mouse button clicked?
Definition gfx.cpp:42
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition gfx.cpp:115
int _gui_scale_cfg
GUI scale in config.
Definition gfx.cpp:64
bool DrawStringMultiLineWithClipping(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw a multiline string, possibly over multiple lines, if the region is within the current display cl...
Definition gfx.cpp:860
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition gfx.cpp:775
SwitchMode _switch_mode
The next mainloop command.
Definition gfx.cpp:49
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition gfx.cpp:1554
bool AdjustGUIZoom(bool automatic)
Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested.
Definition gfx.cpp:1799
int _gui_scale
GUI scale, 100 is 100%.
Definition gfx.cpp:63
void CheckBlitter()
Check whether we still use the right blitter, or use another (better) one.
Definition gfxinit.cpp:325
@ FS_SMALL
Index of the small font in the font tables.
Definition gfx_type.h:252
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:251
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:385
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:393
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:302
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition gfx_type.h:341
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetAlternateColourTip(Colours colour, StringID tip)
Widget part function for setting the alternate colour and tooltip.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetTextStyle(TextColour colour, FontSize size=FS_NORMAL)
Widget part function for setting the text style.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart SetResizeWidgetTypeTip(ResizeWidgetValues widget_type, StringID tip)
Widget part function for setting the resize widget type and tooltip.
std::unique_ptr< NWidgetBase > MakeNWidgets(std::span< const NWidgetPart > nwid_parts, std::unique_ptr< NWidgetBase > &&container)
Construct a nested widget tree from an array of parts.
Definition widget.cpp:3431
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart SetArrowWidgetTypeTip(ArrowWidgetValues widget_type, StringID tip={})
Widget part function for setting the arrow widget type and tooltip.
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
constexpr NWidgetPart SetAlignment(StringAlignment align)
Widget part function for setting the alignment of text/images.
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
constexpr NWidgetPart SetPIPRatio(uint8_t ratio_pre, uint8_t ratio_inter, uint8_t ratio_post)
Widget part function for setting a pre/inter/post ratio.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:955
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1535
GUI functions that shouldn't be here.
Declaration of functions and types defined in highscore.h and highscore_gui.h.
Information about languages and their files.
LanguageList _languages
The actual list of language meta data.
Definition strings.cpp:54
const LanguageMetadata * _current_language
The currently loaded language.
Definition strings.cpp:55
bool ReadLanguagePack(const LanguageMetadata *lang)
Read a particular language.
Definition strings.cpp:2001
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
void ShowQuery(EncodedString &&caption, EncodedString &&message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
@ WID_TF_CAPTION
The caption of the window.
Definition misc_widget.h:50
Functions to mix sound samples.
Base for all music playback.
void ChangeMusicSet(int index)
Change the configured music set and reset playback.
bool _network_available
is network mode available?
Definition network.cpp:69
Basic functions/variables used all over the place.
Part of the network protocol handling content distribution.
void ShowNetworkContentListWindow(ContentVector *cv=nullptr, ContentType type1=CONTENT_TYPE_END, ContentType type2=CONTENT_TYPE_END)
Show the content list window with a given set of content.
GUIs related to networking.
Part of the network protocol handling opt-in survey.
@ Length
Vehicle length (trains and road vehicles)
Functions to find and configure NewGRFs.
void ChangeAutosaveFrequency(bool reset)
Reset the interval of the autosave.
Definition openttd.cpp:1315
@ SM_MENU
Switch to game intro menu.
Definition openttd.h:33
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
Base for the GUIs that have an edit box in them.
declaration of OTTD revision dependent variables
A number of safeguards to prevent using unsafe methods.
SettingsContainer & GetSettingsTree()
Construct settings tree.
Declarations of classes for handling display of individual configuration settings.
RestrictionMode
How the list of advanced settings is filtered.
@ RM_CHANGED_AGAINST_DEFAULT
Show only settings which are different compared to default values.
@ RM_ALL
List all settings regardless of the default/newgame/... values.
@ RM_CHANGED_AGAINST_NEW
Show only settings which are different compared to the user's new game setting values.
@ RM_END
End for iteration.
@ RM_BASIC
Display settings associated to the "basic" list.
SettingEntryFlag
Flags for SettingEntry.
@ LeftDepressed
Of a numeric setting entry, the left button is depressed.
@ RightDepressed
Of a numeric setting entry, the right button is depressed.
bool SetSettingValue(const IntSettingDesc *sd, int32_t value, bool force_newgame)
Top function to save the new value of an element of the Settings struct.
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
static constexpr TextColour GAME_OPTIONS_LABEL
Colour for label text of game options.
static constexpr Colours GAME_OPTIONS_BACKGROUND
Colour for background of game options.
WarnHiddenResult
Warnings about hidden search results.
@ WHR_CATEGORY_TYPE
Both category and type settings filtered matches away.
@ WHR_CATEGORY
Category setting filtered matches away.
@ WHR_NONE
Nothing was filtering matches away.
@ WHR_TYPE
Type setting filtered matches away.
void DrawArrowButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_left, bool clickable_right)
Draw [<][>] boxes.
static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
Callback function for the reset all settings button.
void DrawBoolButton(int x, int y, Colours button_colour, Colours background, bool state, bool clickable)
Draw a toggle button.
void DrawUpDownButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_up, bool clickable_down)
Draw [^][v] buttons.
void ShowBaseSetTextfileWindow(Window *parent, TextfileType file_type, const TBaseSet *baseset, StringID content_type)
Open the BaseSet version of the textfile window.
static const uint32_t _autosave_dropdown_to_minutes[]
Available settings for autosave intervals.
static std::string GetListLabel(const TBaseSet *baseset)
Get string to use when listing this set in the settings window.
static void AddCustomRefreshRates()
Add the refresh rate from the config and the refresh rates from all the monitors to our list of refre...
std::unique_ptr< NWidgetBase > MakeNWidgetSocialPlugins()
Construct nested container widget for managing the list of social plugins.
void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
Draw a dropdown button.
int SETTING_HEIGHT
Height of a single setting in the tree view in pixels.
Dimension _setting_circle_size
Dimension of the circle +/- icon. This is here as not all users are within the class of the settings ...
static constexpr TextColour GAME_OPTIONS_FRAME
Colour for frame text of game options.
static uint GetCurrentResolutionIndex()
Get index of the current screen resolution.
static constexpr Colours GAME_OPTIONS_BUTTON
Colour for buttons of game options.
static void ShowCustCurrency()
Open custom currency window.
static constexpr TextColour GAME_OPTIONS_SELECTED
Colour for selected text of game options.
void ShowGameOptions()
Open the game options window.
Functions for setting GUIs.
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
#define SETTING_BUTTON_HEIGHT
Height of setting buttons.
Functions and types used internally for the settings configurations.
@ GuiCurrency
The number represents money, so when reading value multiply by exchange rate.
@ GuiZeroIsSpecial
A value of zero is possible and has a custom string (the one after "strval").
@ GuiDropdown
The value represents a limited number of string-options (internally integer) presented as dropdown.
SettingType
Type of settings for filtering.
@ ST_CLIENT
Client setting.
@ ST_ALL
Used in setting filter to match all types.
@ ST_GAME
Game setting.
@ ST_COMPANY
Company setting.
GameSettings & GetGameSettings()
Get the settings-object applicable for the current situation: the newgame settings when we're in the ...
@ WID_GO_BASE_SFX_OPEN_URL
Open base SFX URL.
@ WID_GO_SETTING_DROPDOWN
Dynamically created dropdown for changing setting value.
@ WID_GO_BASE_MUSIC_DESCRIPTION
Description of selected base music set.
@ WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD
'Get Content' button for base music.
@ WID_GO_RESTRICT_DROPDOWN
The drop down box to restrict the list of settings.
@ WID_GO_RESOLUTION_DROPDOWN
Dropdown for the resolution.
@ WID_GO_COLLAPSE_ALL
Collapse all button.
@ WID_GO_CURRENCY_DROPDOWN
Currency dropdown.
@ WID_GO_BASE_GRF_DESCRIPTION
Description of selected base GRF.
@ WID_GO_BASE_SFX_DESCRIPTION
Description of selected base SFX.
@ WID_GO_GUI_FONT_AA_TEXT
Text for anti-alias toggle.
@ WID_GO_RESET_ALL
Reset all button.
@ WID_GO_GUI_SCALE_BEVEL_BUTTON
Toggle for chunky bevels.
@ WID_GO_GUI_SCALE
GUI Scale slider.
@ WID_GO_BASE_SFX_TEXTFILE
Open base SFX readme, changelog (+1) or license (+2).
@ WID_GO_TAB_ADVANCED
Advanced tab.
@ WID_GO_GUI_FONT_SPRITE
Toggle whether to prefer the sprite font over TTF fonts.
@ WID_GO_GUI_SCALE_AUTO
Autodetect GUI scale button.
@ WID_GO_SOCIAL_PLUGINS
Main widget handling the social plugins.
@ WID_GO_BASE_GRF_CONTENT_DOWNLOAD
'Get Content' button for base GRF.
@ WID_GO_FILTER
Text filter.
@ WID_GO_BASE_GRF_TEXTFILE
Open base GRF readme, changelog (+1) or license (+2).
@ WID_GO_TAB_GENERAL
General tab.
@ WID_GO_VIDEO_VSYNC_TEXT
Text for video vsync toggle.
@ WID_GO_BASE_GRF_DROPDOWN
Use to select a base GRF.
@ WID_GO_BASE_MUSIC_VOLUME
Change music volume.
@ WID_GO_GUI_FONT_SPRITE_TEXT
Text for sprite font toggle.
@ WID_GO_BASE_SFX_VOLUME
Change sound effects volume.
@ WID_GO_BASE_GRF_PARAMETERS
Base GRF parameters.
@ WID_GO_LANG_DROPDOWN
Language dropdown.
@ WID_GO_VIDEO_ACCEL_TEXT
Text for video acceleration toggle.
@ WID_GO_GUI_FONT_AA
Toggle whether to anti-alias fonts.
@ WID_GO_VIDEO_VSYNC_BUTTON
Toggle for video vsync.
@ WID_GO_SURVEY_LINK_BUTTON
Button to open browser to go to the survey website.
@ WID_GO_SURVEY_PARTICIPATE_TEXT
Text for automated survey toggle.
@ WID_GO_OPTIONSPANEL
Panel widget containing the option lists.
@ WID_GO_TAB_SELECTION
Background of the tab selection.
@ WID_GO_SURVEY_PARTICIPATE_BUTTON
Toggle for participating in the automated survey.
@ WID_GO_AUTOSAVE_DROPDOWN
Dropdown to say how often to autosave.
@ WID_GO_TAB_GRAPHICS
Graphics tab.
@ WID_GO_HELP_TEXT_SCROLL
Scrollbar for setting description.
@ WID_GO_SCROLLBAR
Scrollbar.
@ WID_GO_GUI_SCALE_AUTO_TEXT
Text for Autodetect GUI scale.
@ WID_GO_TEXT_MUSIC_VOLUME
Music volume label.
@ WID_GO_GUI_SCALE_BEVEL_TEXT
Text for chunky bevels.
@ WID_GO_BASE_MUSIC_JUKEBOX
Open the jukebox.
@ WID_GO_SOCIAL_PLUGIN_STATE
State of the social plugin.
@ WID_GO_SETTING_PROPERTIES
Information area to display setting type and default value.
@ WID_GO_SURVEY_SEL
Selection to hide survey if no JSON library is compiled in.
@ WID_GO_REFRESH_RATE_DROPDOWN
Dropdown for all available refresh rates.
@ WID_GO_EXPAND_ALL
Expand all button.
@ WID_GO_SOCIAL_PLUGIN_TITLE
Title of the frame of the social plugin.
@ WID_GO_BASE_GRF_OPEN_URL
Open base GRF URL.
@ WID_GO_BASE_MUSIC_TEXTFILE
Open base music readme, changelog (+1) or license (+2).
@ WID_GO_RESTRICT_CATEGORY
Label upfront to the category drop-down box to restrict the list of settings to show.
@ WID_GO_VIDEO_ACCEL_BUTTON
Toggle for video acceleration.
@ WID_GO_TAB_SOCIAL
Social tab.
@ WID_GO_FULLSCREEN_TEXT
Text for toggle fullscreen.
@ WID_GO_HELP_TEXT
Information area to display help text of the selected option.
@ WID_GO_SURVEY_PREVIEW_BUTTON
Button to open a preview window with the survey results.
@ WID_GO_BASE_SFX_CONTENT_DOWNLOAD
'Get Content' button for base SFX.
@ WID_GO_SOCIAL_PLUGIN_PLATFORM
Platform of the social plugin.
@ WID_GO_BASE_MUSIC_DROPDOWN
Use to select a base music set.
@ WID_GO_BASE_MUSIC_OPEN_URL
Open base music URL.
@ WID_GO_TYPE_DROPDOWN
The drop down box to choose client/game/company/all settings.
@ WID_GO_FULLSCREEN_BUTTON
Toggle fullscreen.
@ WID_GO_TAB_SOUND
Sound tab.
@ WID_GO_BASE_SFX_DROPDOWN
Use to select a base SFX.
@ WID_GO_TEXT_SFX_VOLUME
Sound effects volume label.
@ WID_GO_VIDEO_DRIVER_INFO
Label showing details about the current video driver.
@ WID_GO_RESTRICT_TYPE
Label upfront to the type drop-down box to restrict the list of settings to show.
@ WID_CC_YEAR_DOWN
Down button.
@ WID_CC_YEAR
Year of introduction.
@ WID_CC_SUFFIX_EDIT
Suffix edit button.
@ WID_CC_SEPARATOR_EDIT
Separator edit button.
@ WID_CC_RATE_DOWN
Down button.
@ WID_CC_RATE_UP
Up button.
@ WID_CC_PREVIEW
Preview.
@ WID_CC_PREFIX
Current prefix.
@ WID_CC_PREFIX_EDIT
Prefix edit button.
@ WID_CC_SUFFIX
Current suffix.
@ WID_CC_YEAR_UP
Up button.
@ WID_CC_SEPARATOR
Current separator.
@ WID_CC_RATE
Rate of currency.
void DrawSliderWidget(Rect r, Colours wedge_colour, Colours handle_colour, TextColour text_colour, int min_value, int max_value, int nmarks, int value, SliderMarkFunc *mark_func)
Draw a slider widget with knob at given value.
Definition slider.cpp:34
bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int nmarks, int &value)
Handle click on a slider widget to change the value.
Definition slider.cpp:94
Interface definitions for game to report/respond to social integration.
void ChangeSoundSet(int index)
Change the configured sound set and reset sounds.
Definition sound.cpp:167
Functions related to sound.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
Parse strings.
static std::optional< T > ParseInteger(std::string_view arg, int base=10, bool clamp=false)
Change a string into its number representation.
Functions related to low-level strings.
CharSetFilter
Valid filter types for IsValidChar.
Definition string_type.h:24
@ CS_NUMERAL
Only numeric ones.
Definition string_type.h:26
@ CS_NUMERAL_SIGNED
Only numbers and '-' for negative values.
Definition string_type.h:28
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Definition string_type.h:25
Searching and filtering using a stringterm.
void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
Check whether the currently loaded language pack uses characters that the currently loaded font does ...
Definition strings.cpp:2353
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:91
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:415
std::string_view GetCurrentLanguageIsoCode()
Get the ISO language code of the currently loaded language.
Definition strings.cpp:2249
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:57
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
@ TD_RTL
Text is written right-to-left by default.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Window for displaying the textfile of a BaseSet.
const std::string name
Name of the content.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
const StringID content_type
STR_CONTENT_TYPE_xxx for title.
Data structure describing a single setting in a tab.
uint8_t level
Nesting level of this setting entry.
MusicSettings music
settings related to music/sound
NetworkSettings network
settings related to the network
GUISettings gui
settings related to the GUI
Specification of a currency.
Definition currency.h:76
std::string separator
The thousands separator for this currency.
Definition currency.h:78
std::string prefix
Prefix to apply when formatting money in this currency.
Definition currency.h:80
TimerGameCalendar::Year to_euro
Year of switching to the Euro. May also be CF_NOEURO or CF_ISEURO.
Definition currency.h:79
std::string suffix
Suffix to apply when formatting money in this currency.
Definition currency.h:81
std::string code
3 letter untranslated code to identify the currency.
Definition currency.h:82
uint16_t rate
The conversion rate compared to the base currency.
Definition currency.h:77
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void OnTimeout() override
Called when this window's timeout has been reached.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Definition gfx_type.h:158
bool prefer_sprite
Whether to prefer the built-in sprite font over resizable fonts.
Definition fontcache.h:205
bool global_aa
Whether to anti alias all font sizes.
Definition fontcache.h:206
Information about GRF, used in the game and (part of it) in savegames.
void SetParameterDefaults()
Set the default value for all parameters as specified by action14.
std::vector< uint32_t > param
GRF parameters.
uint8_t settings_restriction_mode
selected restriction mode in adv. settings GUI.
uint16_t refresh_rate
How often we refresh the screen (time between draw-ticks).
uint32_t autosave_interval
how often should we do autosaves?
uint8_t missing_strings_threshold
the number of missing strings before showing the warning
bool scale_bevels
bevels are scaled with GUI scale.
void OnResize() override
Called after the window got resized.
SettingFilter filter
Filter for the list.
bool closing_dropdown
True, if the dropdown list is currently closing.
void OnTimeout() override
Called when this window's timeout has been reached.
void OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close) override
A dropdown window associated to this window has been closed.
SettingEntry * valuewindow_entry
If non-nullptr, pointer to setting for which a value-entering window has been opened.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
SettingEntry * valuedropdown_entry
If non-nullptr, pointer to the value for which a dropdown window is currently opened.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void OnPaint() override
The window must be repainted.
SettingEntry * clicked_entry
If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button).
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
QueryString filter_editbox
Filter editbox;.
WarnHiddenResult warn_missing
Whether and how to warn about missing search results.
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
void SetDisplayedHelpText(SettingEntry *pe)
Set the entry that should have its help text displayed, and mark the window dirty so it gets repainte...
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
int warn_lines
Number of lines used for warning about missing search results.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
bool manually_changed_folding
Whether the user expanded/collapsed something manually.
SettingEntry * last_clicked
If non-nullptr, pointer to the last clicked setting.
DropDownList BuildDropDownList(WidgetID widget, int *selected_index) const
Build the dropdown list for a specific widget.
void OnInit() override
Notification that the nested widget tree gets initialized.
static GameSettings * settings_ptr
Pointer to the game settings being displayed and modified.
All settings together for the game.
LocaleSettings locale
settings related to used currency/unit system in the current game
Base integer type, including boolean, settings.
std::tuple< int32_t, uint32_t > GetRange() const
Get the min/max range for the setting.
Definition settings.cpp:476
int32_t GetDefaultValue() const
Get the default value of the setting.
Definition settings.cpp:467
StringID GetHelp() const
Get the help text of the setting.
Definition settings.cpp:436
virtual bool IsBoolSetting() const
Check whether this setting is a boolean type setting.
std::pair< StringParameter, StringParameter > GetValueParams(int32_t value) const
Get parameters for drawing the value of the setting.
Definition settings.cpp:445
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition settings.cpp:567
int32_t interval
the interval to use between settings in the 'settings' window. If interval is '0' the interval is dyn...
char own_name[32]
the localized name of this language
Definition language.h:30
uint8_t currency
currency we currently use
uint8_t effect_vol
The requested effects volume.
uint8_t music_vol
The requested music volume.
Partial widget specification to allow NWidgets to be written nested.
ParticipateSurvey participate_survey
Participate in the automated survey.
Coordinates of a point in 2D.
Data stored about a string that can be modified in the GUI.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
static const int ACTION_CLEAR
Clear editbox.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Specification of a rectangle with absolute coordinates of all edges.
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
int Width() const
Get width of Rect.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
int Height() const
Get height of Rect.
bool IsEditable(bool do_command=false) const
Check whether the setting is editable in the current gamemode.
Definition settings.cpp:894
SettingFlags flags
Handles how a setting would show up in the GUI (text/currency, etc.).
SettingType GetType() const
Return the type of the setting.
Definition settings.cpp:911
Standard setting.
void SetButtons(SettingEntryFlags new_val)
Set the button-depressed flags (#SettingsEntryFlag::LeftDepressed and #SettingsEntryFlag::RightDepres...
uint GetMaxHelpHeight(int maxw) override
Get the biggest height of the help text(s), if the width is at least maxw.
const IntSettingDesc * setting
Setting description of the setting.
Filter for settings list.
SettingType type
Filter based on type.
bool type_hides
Whether the type hides filtered strings.
RestrictionMode mode
Filter based on category.
RestrictionMode min_cat
Minimum category needed to display all filtered strings (RM_BASIC, RM_ADVANCED, or RM_ALL).
StringFilter string
Filter string.
bool UpdateFilterState(SettingFilter &filter, bool force_visible)
Update the filter state.
void GetFoldingState(bool &all_folded, bool &all_unfolded) const
Recursively accumulate the folding state of the tree.
void ResetAll()
Resets all settings to their default values.
void FoldAll()
Recursively close all folds of sub-pages.
void UnFoldAll()
Recursively open all folds of sub-pages.
BaseSettingEntry * FindEntry(uint row, uint *cur_row)
Find the setting entry at row number row_num.
uint Draw(GameSettings *settings_ptr, int left, int right, int y, uint first_row, uint max_row, BaseSettingEntry *selected, uint cur_row=0, uint parent_last=0) const
Draw a row in the settings panel.
Data structure describing one page of settings in the settings window.
bool folded
Sub-page is folded (not visible except for its title)
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(std::string_view str)
Set the term to filter on.
Templated helper to make a type-safe 'typedef' representing a single POD value.
std::string_view GetText() const
Get the current text.
Definition textbuf.cpp:284
Window for displaying a textfile.
TextfileType file_type
Type of textfile to view.
virtual void LoadTextfile(const std::string &textfile, Subdirectory dir)
Loads the textfile text from file and setup lines.
High level window description.
Definition window_gui.h:167
Data structure for an opened window.
Definition window_gui.h:273
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:967
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1091
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1778
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition window_gui.h:320
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:777
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3205
Window * parent
Parent window.
Definition window_gui.h:328
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:555
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:503
WidgetID mouse_capture_widget
ID of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse capture.
Definition window_gui.h:326
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1064
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:391
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:515
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1768
void CloseChildWindowById(WindowClass wc, WindowNumber number) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1079
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:484
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:491
void SetWidgetsLoweredState(bool lowered_stat, Args... widgets)
Sets the lowered/raised status of a list of widgets.
Definition window_gui.h:526
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:441
void EnableWidget(WidgetID widget_index)
Sets a widget to Enabled.
Definition window_gui.h:400
virtual void OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close)
A dropdown window associated to this window has been closed.
Definition window.cpp:285
void SetTimeout()
Set the timeout flag of the window and initiate the timer.
Definition window_gui.h:355
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:460
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1791
WindowFlags flags
Window flags.
Definition window_gui.h:300
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:312
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:381
int height
Height of the window (number of pixels down in y direction)
Definition window_gui.h:312
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:311
@ CONTENT_TYPE_BASE_SOUNDS
The content consists of base sounds.
@ CONTENT_TYPE_BASE_GRAPHICS
The content consists of base graphics.
@ CONTENT_TYPE_BASE_MUSIC
The content consists of base music.
Stuff related to the text buffer GUI.
@ EnableDefault
enable the 'Default' button ("\0" is returned)
std::optional< std::string > GetTextfile(TextfileType type, Subdirectory dir, std::string_view filename)
Search a textfile file next to the given content.
GUI functions related to textfiles.
TextfileType
Additional text files accompanying Tar archives.
@ TFT_LICENSE
Content license.
@ TFT_README
Content readme.
@ TFT_CHANGELOG
Content changelog.
Base of the town class.
bool _video_vsync
Whether we should use vsync (only if active video driver supports HW acceleration).
bool _video_hw_accel
Whether to consider hardware accelerated video drivers on startup.
Base of all video drivers.
Functions related to (drawing on) viewports.
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition widget.cpp:298
void SetupWidgetDimensions()
Set up pre-scaled versions of Widget Dimensions.
Definition widget.cpp:80
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_PUSHBTN
Normal push-button (no toggle button) with custom drawing.
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ WWT_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
@ WWT_LABEL
Centered label.
Definition widget_type.h:49
@ NWID_SPACER
Invisible widget that takes some space.
Definition widget_type.h:71
@ WWT_EDITBOX
a textbox for typing
Definition widget_type.h:63
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:67
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:45
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:40
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:53
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:77
@ WWT_BOOLBTN
Standard boolean toggle button.
Definition widget_type.h:47
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:69
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:61
@ WWT_FRAME
Frame.
Definition widget_type.h:52
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:38
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:60
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:57
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:62
@ WWT_TEXT
Pure simple text.
Definition widget_type.h:50
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:72
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
@ EqualSize
Containers should keep all their (resizing) children equally large.
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition widget_type.h:21
@ AWV_INCREASE
Arrow to the right or in case of RTL to the left.
Definition widget_type.h:22
std::map< WidgetID, class NWidgetBase * > WidgetLookup
Lookup between widget IDs and NWidget objects.
@ RWV_HIDE_BEVEL
Bevel of resize box is hidden.
Definition widget_type.h:30
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1182
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Definition window.cpp:3381
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1194
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3173
Window functions not directly related to making/drawing windows.
@ BorderOnly
Draw border only, no background.
@ Lowered
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
@ Centred
Window is centered and shall stay centered after ReInit.
@ Timeout
Window timeout counter.
@ WDP_CENTER
Center the window.
Definition window_gui.h:145
int WidgetID
Widget ID.
Definition window_type.h:20
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
Definition window_type.h:28
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:47
@ WC_MUSIC_WINDOW
Music window; Window numbers:
@ WC_CUSTOM_CURRENCY
Custom currency; Window numbers:
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_TEXTFILE
textfile; Window numbers:
@ WC_DROPDOWN_MENU
Drop down menu; Window numbers:
@ WC_QUERY_STRING
Query string window; Window numbers:
@ WC_GRF_PARAMETERS
NewGRF parameters; Window numbers:
Functions related to zooming.