OpenTTD Source 20250328-master-gc3457cd4c0
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"
56
57#include "table/strings.h"
58
60
61#include "safeguards.h"
62
63
64#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
65# define HAS_TRUETYPE_FONT
66#endif
67
68static const StringID _autosave_dropdown[] = {
69 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF,
70 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES,
71 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES,
72 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES,
73 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES,
75};
76
78static const uint32_t _autosave_dropdown_to_minutes[] = {
79 0,
80 10,
81 30,
82 60,
83 120,
84};
85
87
93{
94 auto it = std::ranges::find(_resolutions, Dimension(_screen.width, _screen.height));
95 return std::distance(_resolutions.begin(), it);
96}
97
98static void ShowCustCurrency();
99
102 const std::string name;
104
106 {
107 this->ConstructWindow();
108 this->LoadTextfile(textfile, BASESET_DIR);
109 }
110
111 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
112 {
113 if (widget == WID_TF_CAPTION) {
114 return GetString(stringid, this->content_type, this->name);
115 }
116
117 return this->Window::GetWidgetString(widget, stringid);
118 }
119};
120
127template <class TBaseSet>
128void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, StringID content_type)
129{
130 CloseWindowById(WC_TEXTFILE, file_type);
131 new BaseSetTextfileWindow(file_type, baseset->name, *baseset->GetTextfile(file_type), content_type);
132}
133
140template <typename TBaseSet>
141static std::string GetListLabel(const TBaseSet *baseset)
142{
143 if (baseset->GetNumInvalid() == 0) return GetString(STR_JUST_RAW_STRING, baseset->name);
144 return GetString(STR_BASESET_STATUS, baseset->name, baseset->GetNumInvalid());
145}
146
147template <class T>
148DropDownList BuildSetDropDownList(int *selected_index)
149{
150 int n = T::GetNumSets();
151 *selected_index = T::GetIndexOfUsedSet();
152 DropDownList list;
153 for (int i = 0; i < n; i++) {
154 list.push_back(MakeDropDownListStringItem(GetListLabel(T::GetSet(i)), i));
155 }
156 return list;
157}
158
159std::set<int> _refresh_rates = { 30, 60, 75, 90, 100, 120, 144, 240 };
160
166{
167 /* Add the refresh rate as selected in the config. */
168 _refresh_rates.insert(_settings_client.gui.refresh_rate);
169
170 /* Add all the refresh rates of all monitors connected to the machine. */
171 std::vector<int> monitorRates = VideoDriver::GetInstance()->GetListOfMonitorRefreshRates();
172 std::copy(monitorRates.begin(), monitorRates.end(), std::inserter(_refresh_rates, _refresh_rates.end()));
173}
174
175static const int SCALE_NMARKS = (MAX_INTERFACE_SCALE - MIN_INTERFACE_SCALE) / 25 + 1; // Show marks at 25% increments
176static const int VOLUME_NMARKS = 9; // Show 5 values and 4 empty marks.
177
178static std::optional<std::string> ScaleMarkFunc(int, int, int value)
179{
180 /* Label only every 100% mark. */
181 if (value % 100 != 0) return std::string{};
182
183 return GetString(STR_GAME_OPTIONS_GUI_SCALE_MARK, value / 100, 0);
184}
185
186static std::optional<std::string> VolumeMarkFunc(int, int mark, int value)
187{
188 /* Label only every other mark. */
189 if (mark % 2 != 0) return std::string{};
190
191 // 0-127 does not map nicely to 0-100. Dividing first gives us nice round numbers.
192 return GetString(STR_GAME_OPTIONS_VOLUME_MARK, value / 31 * 25);
193}
194
195static constexpr NWidgetPart _nested_social_plugins_widgets[] = {
199 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM),
201 EndContainer(),
203 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE),
205 EndContainer(),
206 EndContainer(),
207 EndContainer(),
208};
209
210static constexpr NWidgetPart _nested_social_plugins_none_widgets[] = {
212 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE),
213 EndContainer(),
214};
215
217public:
219 {
220 this->plugins = SocialIntegration::GetPlugins();
221
222 if (this->plugins.empty()) {
223 auto widget = MakeNWidgets(_nested_social_plugins_none_widgets, nullptr);
224 this->Add(std::move(widget));
225 } else {
226 for (size_t i = 0; i < this->plugins.size(); i++) {
227 auto widget = MakeNWidgets(_nested_social_plugins_widgets, nullptr);
228 this->Add(std::move(widget));
229 }
230 }
231
232 this->SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0);
233 }
234
235 void FillWidgetLookup(WidgetLookup &widget_lookup) override
236 {
237 widget_lookup[WID_GO_SOCIAL_PLUGINS] = this;
239 }
240
241 void SetupSmallestSize(Window *w) override
242 {
243 this->current_index = -1;
245 }
246
253 template <typename T>
254 std::string &GetWidestPlugin(T SocialIntegrationPlugin::*member) const
255 {
256 std::string *longest = &(this->plugins[0]->*member);
257 int longest_length = 0;
258
259 for (auto *plugin : this->plugins) {
260 int length = GetStringBoundingBox(plugin->*member).width;
261 if (length > longest_length) {
262 longest_length = length;
263 longest = &(plugin->*member);
264 }
265 }
266
267 return *longest;
268 }
269
270 std::string GetWidgetString(WidgetID widget, StringID) const
271 {
272 switch (widget) {
274 /* For SetupSmallestSize, use the longest string we have. */
275 if (this->current_index < 0) {
277 }
278
279 if (this->plugins[this->current_index]->name.empty()) {
280 return this->plugins[this->current_index]->basepath;
281 }
282
283 return GetString(STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE, this->plugins[this->current_index]->name, this->plugins[this->current_index]->version);
284
286 /* For SetupSmallestSize, use the longest string we have. */
287 if (this->current_index < 0) {
289 }
290
291 return this->plugins[this->current_index]->social_platform;
292
294 static const std::pair<SocialIntegrationPlugin::State, StringID> state_to_string[] = {
295 { SocialIntegrationPlugin::RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_RUNNING },
296 { SocialIntegrationPlugin::FAILED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED },
297 { SocialIntegrationPlugin::PLATFORM_NOT_RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_PLATFORM_NOT_RUNNING },
298 { SocialIntegrationPlugin::UNLOADED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNLOADED },
299 { SocialIntegrationPlugin::DUPLICATE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_DUPLICATE },
300 { SocialIntegrationPlugin::UNSUPPORTED_API, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNSUPPORTED_API },
301 { SocialIntegrationPlugin::INVALID_SIGNATURE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_INVALID_SIGNATURE },
302 };
303
304 /* For SetupSmallestSize, use the longest string we have. */
305 if (this->current_index < 0) {
307
308 /* Set the longest plugin when looking for the longest status. */
309 StringID longest = STR_NULL;
310 int longest_length = 0;
311 for (const auto &[state, string] : state_to_string) {
312 int length = GetStringBoundingBox(GetString(string, longest_plugin)).width;
313 if (length > longest_length) {
314 longest_length = length;
315 longest = string;
316 }
317 }
318
319 return GetString(longest, longest_plugin);
320 }
321
322 const auto plugin = this->plugins[this->current_index];
323
324 /* Find the string for the state. */
325 for (const auto &[state, string] : state_to_string) {
326 if (plugin->state == state) {
327 return GetString(string, plugin->social_platform);
328 }
329 }
330
331 /* Default string, in case no state matches. */
332 return GetString(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED, plugin->social_platform);
333 }
334
335 default: NOT_REACHED();
336 }
337 }
338
339 void Draw(const Window *w) override
340 {
341 this->current_index = 0;
342
343 for (auto &wid : this->children) {
344 wid->Draw(w);
345 this->current_index++;
346 }
347 }
348
349private:
350 int current_index = -1;
351 std::vector<SocialIntegrationPlugin *> plugins{};
352};
353
355std::unique_ptr<NWidgetBase> MakeNWidgetSocialPlugins()
356{
357 return std::make_unique<NWidgetSocialPlugins>();
358}
359
361 GameSettings *opt = nullptr;
362 bool reload = false;
363 int gui_scale = 0;
364 static inline WidgetID active_tab = WID_GO_TAB_GENERAL;
365
366 GameOptionsWindow(WindowDesc &desc) : Window(desc), gui_scale(_gui_scale)
367 {
368 this->opt = &GetGameSettings();
369
371
373 this->OnInvalidateData(0);
374
375 this->SetTab(GameOptionsWindow::active_tab);
376
377 if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) this->GetWidget<NWidgetStacked>(WID_GO_SURVEY_SEL)->SetDisplayedPlane(SZSP_NONE);
378 }
379
380 void Close([[maybe_unused]] int data = 0) override
381 {
384 if (this->reload) _switch_mode = SM_MENU;
385 this->Window::Close();
386 }
387
395 {
396 DropDownList list;
397 switch (widget) {
398 case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown
399 *selected_index = this->opt->locale.currency;
400 uint64_t disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies();
401
402 /* Add non-custom currencies; sorted naturally */
403 for (const CurrencySpec &currency : _currency_specs) {
404 int i = &currency - _currency_specs.data();
405 if (i == CURRENCY_CUSTOM) continue;
406 if (currency.code.empty()) {
407 list.push_back(MakeDropDownListStringItem(currency.name, i, HasBit(disabled, i)));
408 } else {
409 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_CURRENCY_CODE, currency.name, currency.code), i, HasBit(disabled, i)));
410 }
411 }
412 std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
413
414 /* Append custom currency at the end */
415 list.push_back(MakeDropDownListDividerItem()); // separator line
416 list.push_back(MakeDropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
417 break;
418 }
419
420 case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown
421 int index = 0;
423 index++;
425 }
426 *selected_index = index - 1;
427
428 const StringID *items = _autosave_dropdown;
429 for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) {
430 list.push_back(MakeDropDownListStringItem(*items, i));
431 }
432 break;
433 }
434
435 case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown
436 for (uint i = 0; i < _languages.size(); i++) {
437 bool hide_language = IsReleasedVersion() && !_languages[i].IsReasonablyFinished();
438 if (hide_language) continue;
439 bool hide_percentage = IsReleasedVersion() || _languages[i].missing < _settings_client.gui.missing_strings_threshold;
440 char *name;
441 if (&_languages[i] == _current_language) {
442 *selected_index = i;
443 name = _languages[i].own_name;
444 } else {
445 /* Especially with sprite-fonts, not all localized
446 * names can be rendered. So instead, we use the
447 * international names for anything but the current
448 * selected language. This avoids showing a few ????
449 * entries in the dropdown list. */
450 name = _languages[i].name;
451 }
452 if (hide_percentage) {
453 list.push_back(MakeDropDownListStringItem(name, i));
454 } else {
456 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, name, percentage), i));
457 }
458 }
459 std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
460 break;
461 }
462
463 case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown
464 if (_resolutions.empty()) break;
465
467 for (uint i = 0; i < _resolutions.size(); i++) {
468 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_RESOLUTION_ITEM, _resolutions[i].width, _resolutions[i].height), i));
469 }
470 break;
471
472 case WID_GO_REFRESH_RATE_DROPDOWN: // Setup refresh rate dropdown
473 for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) {
474 auto i = std::distance(_refresh_rates.begin(), it);
476 list.push_back(MakeDropDownListStringItem(GetString(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, *it), i));
477 }
478 break;
479
482 break;
483
486 break;
487
490 break;
491 }
492
493 return list;
494 }
495
496 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
497 {
498 switch (widget) {
500 const CurrencySpec &currency = _currency_specs[this->opt->locale.currency];
501 if (currency.code.empty()) return GetString(currency.name);
502 return GetString(STR_GAME_OPTIONS_CURRENCY_CODE, currency.name, currency.code);
503 }
504
506 int index = 0;
508 index++;
510 }
511 return GetString(_autosave_dropdown[index - 1]);
512 }
513
521
522 if (current_resolution == _resolutions.size()) {
524 }
526 }
527
532 assert(plugin != nullptr);
533
534 return plugin->GetWidgetString(widget, stringid);
535 }
536
537 default:
538 return this->Window::GetWidgetString(widget, stringid);
539 }
540 }
541
542 void DrawWidget(const Rect &r, WidgetID widget) const override
543 {
544 switch (widget) {
547 break;
548
551 break;
552
555 break;
556
557 case WID_GO_GUI_SCALE:
558 DrawSliderWidget(r, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, SCALE_NMARKS, this->gui_scale, ScaleMarkFunc);
559 break;
560
563 break;
564
566 DrawSliderWidget(r, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.effect_vol, VolumeMarkFunc);
567 break;
568
570 DrawSliderWidget(r, 0, INT8_MAX, VOLUME_NMARKS, _settings_client.music.music_vol, VolumeMarkFunc);
571 break;
572 }
573 }
574
575 void SetTab(WidgetID widget)
576 {
578 this->LowerWidget(widget);
579 GameOptionsWindow::active_tab = widget;
580
581 int pane;
582 switch (widget) {
583 case WID_GO_TAB_GENERAL: pane = 0; break;
584 case WID_GO_TAB_GRAPHICS: pane = 1; break;
585 case WID_GO_TAB_SOUND: pane = 2; break;
586 case WID_GO_TAB_SOCIAL: pane = 3; break;
587 default: NOT_REACHED();
588 }
589
590 this->GetWidget<NWidgetStacked>(WID_GO_TAB_SELECTION)->SetDisplayedPlane(pane);
591 this->SetDirty();
592 }
593
594 void OnResize() override
595 {
596 bool changed = false;
597
599 int y = 0;
600 for (int i = 0; i < BaseGraphics::GetNumSets(); i++) {
601 std::string str = GetString(STR_JUST_RAW_STRING, BaseGraphics::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
602 y = std::max(y, GetStringHeight(str, wid->current_x));
603 }
604 changed |= wid->UpdateVerticalSize(y);
605
607 y = 0;
608 for (int i = 0; i < BaseSounds::GetNumSets(); i++) {
609 std::string str = GetString(STR_JUST_RAW_STRING, BaseSounds::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
610 y = std::max(y, GetStringHeight(str, wid->current_x));
611 }
612 changed |= wid->UpdateVerticalSize(y);
613
615 y = 0;
616 for (int i = 0; i < BaseMusic::GetNumSets(); i++) {
617 std::string str = GetString(STR_JUST_RAW_STRING, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
618 y = std::max(y, GetStringHeight(str, wid->current_x));
619 }
620 changed |= wid->UpdateVerticalSize(y);
621
623 std::string str = GetString(STR_GAME_OPTIONS_VIDEO_DRIVER_INFO, std::string{VideoDriver::GetInstance()->GetInfoString()});
624 y = GetStringHeight(str, wid->current_x);
625 changed |= wid->UpdateVerticalSize(y);
626
627 if (changed) this->ReInit(0, 0, this->flags.Test(WindowFlag::Centred));
628 }
629
631 {
632 switch (widget) {
636 d.width += padding.width;
637 d.height += padding.height;
638 size = maxdim(size, d);
639 break;
640 }
641
650 int selected;
651 size.width = std::max(size.width, GetDropDownListDimension(this->BuildDropDownList(widget, &selected)).width + padding.width);
652 break;
653 }
654 }
655 }
656
657 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
658 {
659 if (widget >= WID_GO_BASE_GRF_TEXTFILE && widget < WID_GO_BASE_GRF_TEXTFILE + TFT_CONTENT_END) {
660 if (BaseGraphics::GetUsedSet() == nullptr) return;
661
663 return;
664 }
665 if (widget >= WID_GO_BASE_SFX_TEXTFILE && widget < WID_GO_BASE_SFX_TEXTFILE + TFT_CONTENT_END) {
666 if (BaseSounds::GetUsedSet() == nullptr) return;
667
669 return;
670 }
671 if (widget >= WID_GO_BASE_MUSIC_TEXTFILE && widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_CONTENT_END) {
672 if (BaseMusic::GetUsedSet() == nullptr) return;
673
675 return;
676 }
677 switch (widget) {
680 case WID_GO_TAB_SOUND:
682 this->SetTab(widget);
683 break;
684
687 case PS_ASK:
688 case PS_NO:
690 break;
691
692 case PS_YES:
694 break;
695 }
696
699 break;
700
702 OpenBrowser(NETWORK_SURVEY_DETAILS_LINK);
703 break;
704
706 ShowSurveyResultTextfileWindow();
707 break;
708
709 case WID_GO_FULLSCREEN_BUTTON: // Click fullscreen on/off
710 /* try to toggle full-screen on/off */
711 if (!ToggleFullScreen(!_fullscreen)) {
713 }
716 break;
717
723#ifndef __APPLE__
727#endif
728 break;
729
731 if (!_video_hw_accel) break;
732
735
740 break;
741
744
746 this->SetDirty();
747
749 ReInitAllWindows(true);
750 break;
751 }
752
753#ifdef HAS_TRUETYPE_FONT
755 _fcsettings.prefer_sprite = !_fcsettings.prefer_sprite;
756
759 this->SetDirty();
760
761 InitFontCache(false);
762 InitFontCache(true);
763 ClearFontCache();
767 ReInitAllWindows(true);
768 break;
769
771 _fcsettings.global_aa = !_fcsettings.global_aa;
772
775
776 ClearFontCache();
777 break;
778#endif /* HAS_TRUETYPE_FONT */
779
780 case WID_GO_GUI_SCALE:
781 if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, _ctrl_pressed ? 0 : SCALE_NMARKS, this->gui_scale)) {
782 this->SetWidgetDirty(widget);
783 }
784
785 if (click_count > 0) this->mouse_capture_widget = widget;
786 break;
787
789 {
790 if (_gui_scale_cfg == -1) {
793 } else {
794 _gui_scale_cfg = -1;
796 if (AdjustGUIZoom(false)) ReInitAllWindows(true);
797 this->gui_scale = _gui_scale;
798 }
799 this->SetWidgetDirty(widget);
800 break;
801 }
802
804 auto *used_set = BaseGraphics::GetUsedSet();
805 if (used_set == nullptr || !used_set->IsConfigurable()) break;
806 GRFConfig &extra_cfg = used_set->GetOrCreateExtraConfig();
807 if (extra_cfg.param.empty()) extra_cfg.SetParameterDefaults();
808 OpenGRFParameterWindow(true, extra_cfg, _game_mode == GM_MENU);
809 if (_game_mode == GM_MENU) this->reload = true;
810 break;
811 }
812
816 if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, 0, vol)) {
817 if (widget == WID_GO_BASE_MUSIC_VOLUME) {
819 } else {
820 SetEffectVolume(vol);
821 }
822 this->SetWidgetDirty(widget);
824 }
825
826 if (click_count > 0) this->mouse_capture_widget = widget;
827 break;
828 }
829
831 ShowMusicWindow();
832 break;
833 }
834
836 if (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->url.empty()) return;
837 OpenBrowser(BaseGraphics::GetUsedSet()->url);
838 break;
839
841 if (BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->url.empty()) return;
842 OpenBrowser(BaseSounds::GetUsedSet()->url);
843 break;
844
846 if (BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->url.empty()) return;
847 OpenBrowser(BaseMusic::GetUsedSet()->url);
848 break;
849
852 break;
853
856 break;
857
860 break;
861
870 int selected;
871 DropDownList list = this->BuildDropDownList(widget, &selected);
872 if (!list.empty()) {
873 ShowDropDownList(this, std::move(list), selected, widget);
874 } else {
876 }
877 break;
878 }
879 }
880 }
881
882 void OnMouseLoop() override
883 {
884 if (_left_button_down || this->gui_scale == _gui_scale) return;
885
886 _gui_scale_cfg = this->gui_scale;
887
888 if (AdjustGUIZoom(false)) {
889 ReInitAllWindows(true);
891 this->SetDirty();
892 }
893 }
894
895 void OnDropdownSelect(WidgetID widget, int index) override
896 {
897 switch (widget) {
898 case WID_GO_CURRENCY_DROPDOWN: // Currency
899 if (index == CURRENCY_CUSTOM) ShowCustCurrency();
900 this->opt->locale.currency = index;
901 ReInitAllWindows(false);
902 break;
903
904 case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options
907 this->SetDirty();
908 break;
909
910 case WID_GO_LANG_DROPDOWN: // Change interface language
914 ClearAllCachedNames();
916 CheckBlitter();
917 ReInitAllWindows(false);
918 break;
919
920 case WID_GO_RESOLUTION_DROPDOWN: // Change resolution
921 if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) {
922 this->SetDirty();
923 }
924 break;
925
927 _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index);
929 /* Show warning to the user that this refresh rate might not be suitable on
930 * larger maps with many NewGRFs and vehicles. */
932 }
933 break;
934 }
935
937 if (_game_mode == GM_MENU) {
939 auto set = BaseGraphics::GetSet(index);
941 this->reload = true;
942 this->InvalidateData();
943 }
944 break;
945
947 ChangeSoundSet(index);
948 break;
949
951 ChangeMusicSet(index);
952 break;
953 }
954 }
955
961 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
962 {
963 if (!gui_scope) return;
968
969#ifndef __APPLE__
972#endif
973
976#ifdef HAS_TRUETYPE_FONT
980#endif /* HAS_TRUETYPE_FONT */
981
982 this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
983
985
989
990 for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) {
994 }
995
997 }
998};
999
1000static constexpr NWidgetPart _nested_game_options_widgets[] = {
1002 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1003 NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1004 EndContainer(),
1005 NWidget(WWT_PANEL, COLOUR_GREY),
1007 NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GENERAL), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_GENERAL, STR_GAME_OPTIONS_TAB_GENERAL_TOOLTIP), SetFill(1, 0),
1008 NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GRAPHICS), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_GRAPHICS, STR_GAME_OPTIONS_TAB_GRAPHICS_TOOLTIP), SetFill(1, 0),
1009 NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOUND), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_SOUND, STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP), SetFill(1, 0),
1010 NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOCIAL), SetMinimalTextLines(2, 0), SetStringTip(STR_GAME_OPTIONS_TAB_SOCIAL, STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP), SetFill(1, 0),
1011 EndContainer(),
1012 EndContainer(),
1013 NWidget(WWT_PANEL, COLOUR_GREY),
1015 /* General tab */
1017 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_LANGUAGE),
1018 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0),
1019 EndContainer(),
1020
1021 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME),
1022 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0),
1023 EndContainer(),
1024
1025 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME),
1026 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0),
1027 EndContainer(),
1028
1029 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_SURVEY_SEL),
1030 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1032 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY),
1033 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PARTICIPATE_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP),
1034 EndContainer(),
1036 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PREVIEW_BUTTON), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP),
1037 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_LINK_BUTTON), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP),
1038 EndContainer(),
1039 EndContainer(),
1040 EndContainer(),
1041 EndContainer(),
1042
1043 /* Graphics tab */
1045 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME),
1047 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_GUI_SCALE), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(0, 0), SetToolTip(STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP),
1049 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO),
1050 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_AUTO), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP),
1051 EndContainer(),
1053 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS),
1054 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP),
1055 EndContainer(),
1056#ifdef HAS_TRUETYPE_FONT
1058 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE),
1059 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP),
1060 EndContainer(),
1062 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_GUI_FONT_AA),
1063 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP),
1064 EndContainer(),
1065#endif /* HAS_TRUETYPE_FONT */
1066 EndContainer(),
1067 EndContainer(),
1068
1069 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_GRAPHICS),
1072 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_RESOLUTION),
1073 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_RESOLUTION_TOOLTIP),
1074 EndContainer(),
1076 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_REFRESH_RATE),
1077 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_REFRESH_RATE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP),
1078 EndContainer(),
1080 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_FULLSCREEN),
1081 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP),
1082 EndContainer(),
1084 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION),
1085 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP),
1086 EndContainer(),
1087#ifndef __APPLE__
1089 NWidget(WWT_TEXT, INVALID_COLOUR), SetMinimalSize(0, 12), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_VIDEO_VSYNC),
1090 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_VSYNC_BUTTON), SetAspect(WidgetDimensions::ASPECT_SETTINGS_BUTTON), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP),
1091 EndContainer(),
1092#endif
1095 EndContainer(),
1096 EndContainer(),
1097 EndContainer(),
1098
1099 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_GRF), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), SetFill(1, 0),
1101 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), SetFill(1, 0),
1102 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_PARAMETERS), SetStringTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS),
1103 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1104 EndContainer(),
1105 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(200, 0), SetStringTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0),
1108 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1109 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1110 EndContainer(),
1112 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1113 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1114 EndContainer(),
1115 EndContainer(),
1116 EndContainer(),
1117 EndContainer(),
1118
1119 /* Sound/Music tab */
1121 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_VOLUME), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1123 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_SFX_VOLUME), SetMinimalSize(0, 12), SetStringTip(STR_GAME_OPTIONS_SFX_VOLUME),
1124 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
1125 EndContainer(),
1127 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GO_TEXT_MUSIC_VOLUME), SetMinimalSize(0, 12), SetStringTip(STR_GAME_OPTIONS_MUSIC_VOLUME),
1128 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetToolTip(STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
1129 EndContainer(),
1130 EndContainer(),
1131
1132 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_SFX), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1134 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), SetFill(1, 0),
1135 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1136 EndContainer(),
1137 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0),
1140 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1141 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1142 EndContainer(),
1144 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1145 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1146 EndContainer(),
1147 EndContainer(),
1148 EndContainer(),
1149
1150 NWidget(WWT_FRAME, COLOUR_GREY), SetStringTip(STR_GAME_OPTIONS_BASE_MUSIC), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1152 NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), SetFill(1, 0),
1153 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_CONTENT_DOWNLOAD), SetStringTip(STR_GAME_OPTIONS_ONLINE_CONTENT, STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP),
1154 EndContainer(),
1156 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetToolTip(STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0),
1158 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetSpriteTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
1159 EndContainer(),
1160 EndContainer(),
1163 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1164 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1165 EndContainer(),
1167 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1168 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1169 EndContainer(),
1170 EndContainer(),
1171 EndContainer(),
1172 EndContainer(),
1173
1174 /* Social tab */
1177 EndContainer(),
1178 EndContainer(),
1179 EndContainer(),
1180};
1181
1182static WindowDesc _game_options_desc(
1183 WDP_CENTER, nullptr, 0, 0,
1185 {},
1186 _nested_game_options_widgets
1187);
1188
1191{
1193 new GameOptionsWindow(_game_options_desc);
1194}
1195
1197
1198static const StringID _game_settings_restrict_dropdown[] = {
1199 STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC
1200 STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED
1201 STR_CONFIG_SETTING_RESTRICT_ALL, // RM_ALL
1202 STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT, // RM_CHANGED_AGAINST_DEFAULT
1203 STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW, // RM_CHANGED_AGAINST_NEW
1204};
1205static_assert(lengthof(_game_settings_restrict_dropdown) == RM_END);
1206
1214
1220static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
1221{
1222 if (confirmed) {
1225 w->InvalidateData();
1226 }
1227}
1228
1232
1237 bool closing_dropdown = false;
1238
1243 int warn_lines = 0;
1244
1245 Scrollbar *vscroll;
1246
1248 {
1250 this->filter.min_cat = RM_ALL;
1251 this->filter.type = ST_ALL;
1252 this->filter.type_hides = false;
1253 this->settings_ptr = &GetGameSettings();
1254
1255 GetSettingsTree().FoldAll(); // Close all sub-pages
1256
1257 this->CreateNestedTree();
1258 this->vscroll = this->GetScrollbar(WID_GS_SCROLLBAR);
1260
1262 this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
1264
1265 this->InvalidateData();
1266 }
1267
1268 void OnInit() override
1269 {
1270 _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED));
1271 }
1272
1274 {
1275 switch (widget) {
1278 resize.width = 1;
1279
1280 size.height = 5 * resize.height + WidgetDimensions::scaled.framerect.Vertical();
1281 break;
1282
1283 case WID_GS_HELP_TEXT: {
1284 static const StringID setting_types[] = {
1288 };
1289 for (const auto &setting_type : setting_types) {
1290 size.width = std::max(size.width, GetStringBoundingBox(GetString(STR_CONFIG_SETTING_TYPE, setting_type)).width + padding.width);
1291 }
1293 std::max(size.height, GetSettingsTree().GetMaxHelpHeight(size.width));
1294 break;
1295 }
1296
1300 break;
1301
1302 default:
1303 break;
1304 }
1305 }
1306
1307 void OnPaint() override
1308 {
1309 if (this->closing_dropdown) {
1310 this->closing_dropdown = false;
1311 assert(this->valuedropdown_entry != nullptr);
1312 this->valuedropdown_entry->SetButtons({});
1313 this->valuedropdown_entry = nullptr;
1314 }
1315
1316 /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */
1317 const Rect panel = this->GetWidget<NWidgetBase>(WID_GS_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext);
1319 int new_warn_lines;
1320 if (this->warn_missing == WHR_NONE) {
1321 new_warn_lines = 0;
1322 } else {
1323 new_warn_lines = GetStringLineCount(GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]), panel.Width());
1324 }
1325 if (this->warn_lines != new_warn_lines) {
1326 this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines);
1327 this->warn_lines = new_warn_lines;
1328 }
1329
1330 this->DrawWidgets();
1331
1332 /* Draw the 'some search results are hidden' notice. */
1333 if (this->warn_missing != WHR_NONE) {
1334 DrawStringMultiLine(panel.WithHeight(this->warn_lines * GetCharacterHeight(FS_NORMAL)),
1335 GetString(warn_str, _game_settings_restrict_dropdown[this->filter.min_cat]),
1336 TC_FROMSTRING, SA_CENTER);
1337 }
1338 }
1339
1340 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1341 {
1342 switch (widget) {
1344 return GetString(_game_settings_restrict_dropdown[this->filter.mode]);
1345
1347 switch (this->filter.type) {
1352 }
1353
1354 default:
1355 return this->Window::GetWidgetString(widget, stringid);
1356 }
1357 }
1358
1359 DropDownList BuildDropDownList(WidgetID widget) const
1360 {
1361 DropDownList list;
1362 switch (widget) {
1364 for (int mode = 0; mode != RM_END; mode++) {
1365 /* If we are in adv. settings screen for the new game's settings,
1366 * we don't want to allow comparing with new game's settings. */
1367 bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame;
1368
1369 list.push_back(MakeDropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled));
1370 }
1371 break;
1372
1374 list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL));
1375 list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME));
1376 list.push_back(MakeDropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY));
1377 list.push_back(MakeDropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT));
1378 break;
1379 }
1380 return list;
1381 }
1382
1383 void DrawWidget(const Rect &r, WidgetID widget) const override
1384 {
1385 switch (widget) {
1386 case WID_GS_OPTIONSPANEL: {
1388 tr.top += this->warn_lines * SETTING_HEIGHT;
1389 uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines;
1390 int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top,
1391 this->vscroll->GetPosition(), last_row, this->last_clicked);
1393 break;
1394 }
1395
1396 case WID_GS_HELP_TEXT:
1397 if (this->last_clicked != nullptr) {
1398 const IntSettingDesc *sd = this->last_clicked->setting;
1399
1400 Rect tr = r;
1401 std::string str;
1402 switch (sd->GetType()) {
1406 default: NOT_REACHED();
1407 }
1408 DrawString(tr, str);
1410
1411 auto [param1, param2] = sd->GetValueParams(sd->GetDefaultValue());
1414
1415 DrawStringMultiLine(tr, sd->GetHelp(), TC_WHITE);
1416 }
1417 break;
1418
1419 default:
1420 break;
1421 }
1422 }
1423
1429 {
1430 if (this->last_clicked != pe) this->SetDirty();
1431 this->last_clicked = pe;
1432 }
1433
1434 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1435 {
1436 switch (widget) {
1437 case WID_GS_EXPAND_ALL:
1438 this->manually_changed_folding = true;
1440 this->InvalidateData();
1441 break;
1442
1444 this->manually_changed_folding = true;
1446 this->InvalidateData();
1447 break;
1448
1449 case WID_GS_RESET_ALL:
1450 ShowQuery(
1453 this,
1455 );
1456 break;
1457
1459 DropDownList list = this->BuildDropDownList(widget);
1460 if (!list.empty()) {
1461 ShowDropDownList(this, std::move(list), this->filter.mode, widget);
1462 }
1463 break;
1464 }
1465
1466 case WID_GS_TYPE_DROPDOWN: {
1467 DropDownList list = this->BuildDropDownList(widget);
1468 if (!list.empty()) {
1469 ShowDropDownList(this, std::move(list), this->filter.type, widget);
1470 }
1471 break;
1472 }
1473 }
1474
1475 if (widget != WID_GS_OPTIONSPANEL) return;
1476
1478 if (btn == INT32_MAX || btn < this->warn_lines) return;
1479 btn -= this->warn_lines;
1480
1481 uint cur_row = 0;
1483
1484 if (clicked_entry == nullptr) return; // Clicked below the last setting of the page
1485
1486 int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - WidgetDimensions::scaled.frametext.left - (clicked_entry->level + 1) * WidgetDimensions::scaled.hsep_indent; // Shift x coordinate
1487 if (x < 0) return; // Clicked left of the entry
1488
1490 if (clicked_page != nullptr) {
1491 this->SetDisplayedHelpText(nullptr);
1492 clicked_page->folded = !clicked_page->folded; // Flip 'folded'-ness of the sub-page
1493
1494 this->manually_changed_folding = true;
1495
1496 this->InvalidateData();
1497 return;
1498 }
1499
1500 SettingEntry *pe = dynamic_cast<SettingEntry*>(clicked_entry);
1501 assert(pe != nullptr);
1502 const IntSettingDesc *sd = pe->setting;
1503
1504 /* return if action is only active in network, or only settable by server */
1505 if (!sd->IsEditable()) {
1506 this->SetDisplayedHelpText(pe);
1507 return;
1508 }
1509
1510 auto [min_val, max_val] = sd->GetRange();
1511 int32_t value = sd->Read(ResolveObject(settings_ptr, sd));
1512
1513 /* clicked on the icon on the left side. Either scroller, bool on/off or dropdown */
1515 this->SetDisplayedHelpText(pe);
1516
1517 if (this->valuedropdown_entry == pe) {
1518 /* unclick the dropdown */
1520 this->closing_dropdown = false;
1521 this->valuedropdown_entry->SetButtons({});
1522 this->valuedropdown_entry = nullptr;
1523 } else {
1524 if (this->valuedropdown_entry != nullptr) this->valuedropdown_entry->SetButtons({});
1525 this->closing_dropdown = false;
1526
1528 int rel_y = (pt.y - wid->pos_y - WidgetDimensions::scaled.framerect.top) % wid->resize_y;
1529
1530 Rect wi_rect;
1531 wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
1532 wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
1533 wi_rect.top = pt.y - rel_y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2;
1534 wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
1535
1536 /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
1537 if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
1538 this->valuedropdown_entry = pe;
1539 this->valuedropdown_entry->SetButtons(SettingEntryFlag::LeftDepressed);
1540
1541 DropDownList list;
1543 auto [param1, param2] = sd->GetValueParams(i);
1544 list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_STRING1, param1, param2), i));
1545 }
1546
1547 ShowDropDownListAt(this, std::move(list), value, WID_GS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
1548 }
1549 }
1550 this->SetDirty();
1551 } else if (x < SETTING_BUTTON_WIDTH) {
1552 this->SetDisplayedHelpText(pe);
1553 int32_t oldvalue = value;
1554
1555 if (sd->IsBoolSetting()) {
1556 value ^= 1;
1557 } else {
1558 /* Add a dynamic step-size to the scroller. In a maximum of
1559 * 50-steps you should be able to get from min to max,
1560 * unless specified otherwise in the 'interval' variable
1561 * of the current setting. */
1562 uint32_t step = (sd->interval == 0) ? ((max_val - min_val) / 50) : sd->interval;
1563 if (step == 0) step = 1;
1564
1565 /* don't allow too fast scrolling */
1566 if (this->flags.Test(WindowFlag::Timeout) && this->timeout_timer > 1) {
1567 _left_button_clicked = false;
1568 return;
1569 }
1570
1571 /* Increase or decrease the value and clamp it to extremes */
1572 if (x >= SETTING_BUTTON_WIDTH / 2) {
1573 value += step;
1574 if (min_val < 0) {
1575 assert(static_cast<int32_t>(max_val) >= 0);
1576 if (value > static_cast<int32_t>(max_val)) value = static_cast<int32_t>(max_val);
1577 } else {
1578 if (static_cast<uint32_t>(value) > max_val) value = static_cast<int32_t>(max_val);
1579 }
1580 if (value < min_val) value = min_val; // skip between "disabled" and minimum
1581 } else {
1582 value -= step;
1583 if (value < min_val) value = sd->flags.Test(SettingFlag::GuiZeroIsSpecial) ? 0 : min_val;
1584 }
1585
1586 /* Set up scroller timeout for numeric values */
1587 if (value != oldvalue) {
1588 if (this->clicked_entry != nullptr) { // Release previous buttons if any
1589 this->clicked_entry->SetButtons({});
1590 }
1591 this->clicked_entry = pe;
1593 this->SetTimeout();
1594 _left_button_clicked = false;
1595 }
1596 }
1597
1598 if (value != oldvalue) {
1599 SetSettingValue(sd, value);
1600 this->SetDirty();
1601 }
1602 } else {
1603 /* Only open editbox if clicked for the second time, and only for types where it is sensible for. */
1604 if (this->last_clicked == pe && !sd->IsBoolSetting() && !sd->flags.Test(SettingFlag::GuiDropdown)) {
1605 int64_t value64 = value;
1606 /* Show the correct currency-translated value */
1607 if (sd->flags.Test(SettingFlag::GuiCurrency)) value64 *= GetCurrency().rate;
1608
1609 CharSetFilter charset_filter = CS_NUMERAL; //default, only numeric input allowed
1610 if (min_val < 0) charset_filter = CS_NUMERAL_SIGNED; // special case, also allow '-' sign for negative input
1611
1612 this->valuewindow_entry = pe;
1613 /* Limit string length to 14 so that MAX_INT32 * max currency rate doesn't exceed MAX_INT64. */
1615 }
1616 this->SetDisplayedHelpText(pe);
1617 }
1618 }
1619
1620 void OnTimeout() override
1621 {
1622 if (this->clicked_entry != nullptr) { // On timeout, release any depressed buttons
1623 this->clicked_entry->SetButtons({});
1624 this->clicked_entry = nullptr;
1625 this->SetDirty();
1626 }
1627 }
1628
1629 void OnQueryTextFinished(std::optional<std::string> str) override
1630 {
1631 /* The user pressed cancel */
1632 if (!str.has_value()) return;
1633
1634 assert(this->valuewindow_entry != nullptr);
1635 const IntSettingDesc *sd = this->valuewindow_entry->setting;
1636
1637 int32_t value;
1638 if (!str->empty()) {
1639 long long llvalue = atoll(str->c_str());
1640
1641 /* Save the correct currency-translated value */
1642 if (sd->flags.Test(SettingFlag::GuiCurrency)) llvalue /= GetCurrency().rate;
1643
1644 value = ClampTo<int32_t>(llvalue);
1645 } else {
1646 value = sd->GetDefaultValue();
1647 }
1648
1649 SetSettingValue(this->valuewindow_entry->setting, value);
1650 this->SetDirty();
1651 }
1652
1653 void OnDropdownSelect(WidgetID widget, int index) override
1654 {
1655 switch (widget) {
1657 this->filter.mode = (RestrictionMode)index;
1658 if (this->filter.mode == RM_CHANGED_AGAINST_DEFAULT ||
1659 this->filter.mode == RM_CHANGED_AGAINST_NEW) {
1660
1661 if (!this->manually_changed_folding) {
1662 /* Expand all when selecting 'changes'. Update the filter state first, in case it becomes less restrictive in some cases. */
1665 }
1666 } else {
1667 /* Non-'changes' filter. Save as default. */
1669 }
1670 this->InvalidateData();
1671 break;
1672
1674 this->filter.type = (SettingType)index;
1675 this->InvalidateData();
1676 break;
1677
1679 /* Deal with drop down boxes on the panel. */
1680 assert(this->valuedropdown_entry != nullptr);
1681 const IntSettingDesc *sd = this->valuedropdown_entry->setting;
1682 assert(sd->flags.Test(SettingFlag::GuiDropdown));
1683
1684 SetSettingValue(sd, index);
1685 this->SetDirty();
1686 break;
1687 }
1688 }
1689
1690 void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
1691 {
1692 if (widget != WID_GS_SETTING_DROPDOWN) {
1693 /* Normally the default implementation of OnDropdownClose() takes care of
1694 * a few things. We want that behaviour here too, but only for
1695 * "normal" dropdown boxes. The special dropdown boxes added for every
1696 * setting that needs one can't have this call. */
1697 Window::OnDropdownClose(pt, widget, index, instant_close);
1698 } else {
1699 /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
1700 * the same dropdown button was clicked again, and then not open the dropdown again.
1701 * So, we only remember that it was closed, and process it on the next OnPaint, which is
1702 * after OnClick. */
1703 assert(this->valuedropdown_entry != nullptr);
1704 this->closing_dropdown = true;
1705 this->SetDirty();
1706 }
1707 }
1708
1709 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1710 {
1711 if (!gui_scope) return;
1712
1713 /* Update which settings are to be visible. */
1715 this->filter.min_cat = min_level;
1716 this->filter.type_hides = false;
1718
1719 if (this->filter.string.IsEmpty()) {
1720 this->warn_missing = WHR_NONE;
1721 } else if (min_level < this->filter.min_cat) {
1722 this->warn_missing = this->filter.type_hides ? WHR_CATEGORY_TYPE : WHR_CATEGORY;
1723 } else {
1724 this->warn_missing = this->filter.type_hides ? WHR_TYPE : WHR_NONE;
1725 }
1726 this->vscroll->SetCount(GetSettingsTree().Length() + this->warn_lines);
1727
1728 if (this->last_clicked != nullptr && !GetSettingsTree().IsVisible(this->last_clicked)) {
1729 this->SetDisplayedHelpText(nullptr);
1730 }
1731
1732 bool all_folded = true;
1733 bool all_unfolded = true;
1735 this->SetWidgetDisabledState(WID_GS_EXPAND_ALL, all_unfolded);
1737 }
1738
1740 {
1741 if (wid == WID_GS_FILTER) {
1742 this->filter.string.SetFilterTerm(this->filter_editbox.text.GetText());
1743 if (!this->filter.string.IsEmpty() && !this->manually_changed_folding) {
1744 /* User never expanded/collapsed single pages and entered a filter term.
1745 * Expand everything, to save weird expand clicks, */
1747 }
1748 this->InvalidateData();
1749 }
1750 }
1751
1752 void OnResize() override
1753 {
1754 this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical());
1755 }
1756};
1757
1759
1760static constexpr NWidgetPart _nested_settings_selection_widgets[] = {
1762 NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
1763 NWidget(WWT_CAPTION, COLOUR_MAUVE), SetStringTip(STR_CONFIG_SETTING_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1764 NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
1765 EndContainer(),
1766 NWidget(WWT_PANEL, COLOUR_MAUVE),
1769 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GS_RESTRICT_CATEGORY), SetStringTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY),
1770 NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
1771 EndContainer(),
1773 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GS_RESTRICT_TYPE), SetStringTip(STR_CONFIG_SETTING_RESTRICT_TYPE),
1774 NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetToolTip(STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
1775 EndContainer(),
1777 NWidget(WWT_TEXT, INVALID_COLOUR), SetFill(0, 1), SetStringTip(STR_CONFIG_SETTING_FILTER_TITLE),
1778 NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_GS_FILTER), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1779 EndContainer(),
1780 EndContainer(),
1781 EndContainer(),
1785 EndContainer(),
1786 NWidget(WWT_PANEL, COLOUR_MAUVE),
1787 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GS_HELP_TEXT), SetMinimalSize(300, 25), SetFill(1, 1), SetResize(1, 0),
1789 EndContainer(),
1791 NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_EXPAND_ALL), SetStringTip(STR_CONFIG_SETTING_EXPAND_ALL),
1792 NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_COLLAPSE_ALL), SetStringTip(STR_CONFIG_SETTING_COLLAPSE_ALL),
1793 NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_RESET_ALL), SetStringTip(STR_CONFIG_SETTING_RESET_ALL),
1794 NWidget(WWT_PANEL, COLOUR_MAUVE), SetFill(1, 0), SetResize(1, 0),
1795 EndContainer(),
1796 NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
1797 EndContainer(),
1798};
1799
1800static WindowDesc _settings_selection_desc(
1801 WDP_CENTER, "settings", 510, 450,
1803 {},
1804 _nested_settings_selection_widgets
1805);
1806
1809{
1811 new GameSettingsWindow(_settings_selection_desc);
1812}
1813
1814
1824void DrawArrowButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_left, bool clickable_right)
1825{
1826 int colour = GetColourGradient(button_colour, SHADE_DARKER);
1827 Dimension dim = NWidgetScrollbar::GetHorizontalDimension();
1828
1829 Rect lr = {x, y, x + (int)dim.width - 1, y + (int)dim.height - 1};
1830 Rect rr = {x + (int)dim.width, y, x + (int)dim.width * 2 - 1, y + (int)dim.height - 1};
1831
1832 DrawFrameRect(lr, button_colour, (state == 1) ? FrameFlag::Lowered : FrameFlags{});
1833 DrawFrameRect(rr, button_colour, (state == 2) ? FrameFlag::Lowered : FrameFlags{});
1834 DrawSpriteIgnorePadding(SPR_ARROW_LEFT, PAL_NONE, lr, SA_CENTER);
1835 DrawSpriteIgnorePadding(SPR_ARROW_RIGHT, PAL_NONE, rr, SA_CENTER);
1836
1837 /* Grey out the buttons that aren't clickable */
1838 bool rtl = _current_text_dir == TD_RTL;
1839 if (rtl ? !clickable_right : !clickable_left) {
1841 }
1842 if (rtl ? !clickable_left : !clickable_right) {
1844 }
1845}
1846
1855void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
1856{
1857 int colour = GetColourGradient(button_colour, SHADE_DARKER);
1858
1859 Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
1860
1861 DrawFrameRect(r, button_colour, state ? FrameFlag::Lowered : FrameFlags{});
1862 DrawSpriteIgnorePadding(SPR_ARROW_DOWN, PAL_NONE, r, SA_CENTER);
1863
1864 if (!clickable) {
1866 }
1867}
1868
1876void DrawBoolButton(int x, int y, bool state, bool clickable)
1877{
1878 static const Colours _bool_ctabs[2][2] = {{COLOUR_CREAM, COLOUR_RED}, {COLOUR_DARK_GREEN, COLOUR_GREEN}};
1879
1880 Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
1881 DrawFrameRect(r, _bool_ctabs[state][clickable], state ? FrameFlag::Lowered : FrameFlags{});
1882}
1883
1885 WidgetID query_widget{};
1886
1888 {
1889 this->InitNested();
1890
1891 SetButtonState();
1892 }
1893
1894 void SetButtonState()
1895 {
1900 }
1901
1902 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1903 {
1904 switch (widget) {
1909 case WID_CC_YEAR:
1911
1912 case WID_CC_PREVIEW:
1913 return GetString(STR_CURRENCY_PREVIEW, 10000);
1914
1915 default:
1916 return this->Window::GetWidgetString(widget, stringid);
1917 }
1918 }
1919
1921 {
1922 switch (widget) {
1923 /* Set the appropriate width for the up/down buttons. */
1924 case WID_CC_RATE_DOWN:
1925 case WID_CC_RATE_UP:
1926 case WID_CC_YEAR_DOWN:
1927 case WID_CC_YEAR_UP:
1928 size = maxdim(size, {(uint)SETTING_BUTTON_WIDTH / 2, (uint)SETTING_BUTTON_HEIGHT});
1929 break;
1930
1931 /* Set the appropriate width for the edit buttons. */
1933 case WID_CC_PREFIX_EDIT:
1934 case WID_CC_SUFFIX_EDIT:
1935 size = maxdim(size, {(uint)SETTING_BUTTON_WIDTH, (uint)SETTING_BUTTON_HEIGHT});
1936 break;
1937
1938 /* Make sure the window is wide enough for the widest exchange rate */
1939 case WID_CC_RATE:
1941 break;
1942 }
1943 }
1944
1945 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1946 {
1947 int line = 0;
1948 int len = 0;
1949 std::string str;
1951
1952 switch (widget) {
1953 case WID_CC_RATE_DOWN:
1954 if (GetCustomCurrency().rate > 1) GetCustomCurrency().rate--;
1955 if (GetCustomCurrency().rate == 1) this->DisableWidget(WID_CC_RATE_DOWN);
1957 break;
1958
1959 case WID_CC_RATE_UP:
1963 break;
1964
1965 case WID_CC_RATE:
1967 len = 5;
1968 line = WID_CC_RATE;
1969 afilter = CS_NUMERAL;
1970 break;
1971
1973 case WID_CC_SEPARATOR:
1975 len = 7;
1976 line = WID_CC_SEPARATOR;
1977 break;
1978
1979 case WID_CC_PREFIX_EDIT:
1980 case WID_CC_PREFIX:
1981 str = GetCustomCurrency().prefix;
1982 len = 15;
1983 line = WID_CC_PREFIX;
1984 break;
1985
1986 case WID_CC_SUFFIX_EDIT:
1987 case WID_CC_SUFFIX:
1988 str = GetCustomCurrency().suffix;
1989 len = 15;
1990 line = WID_CC_SUFFIX;
1991 break;
1992
1993 case WID_CC_YEAR_DOWN:
1997 break;
1998
1999 case WID_CC_YEAR_UP:
2003 break;
2004
2005 case WID_CC_YEAR:
2006 str = GetString(STR_JUST_INT, GetCustomCurrency().to_euro);
2007 len = 7;
2008 line = WID_CC_YEAR;
2009 afilter = CS_NUMERAL;
2010 break;
2011 }
2012
2013 if (len != 0) {
2014 this->query_widget = line;
2015 ShowQueryString(str, STR_CURRENCY_CHANGE_PARAMETER, len + 1, this, afilter, {});
2016 }
2017
2018 this->SetTimeout();
2019 this->SetDirty();
2020 }
2021
2022 void OnQueryTextFinished(std::optional<std::string> str) override
2023 {
2024 if (!str.has_value()) return;
2025
2026 switch (this->query_widget) {
2027 case WID_CC_RATE:
2028 GetCustomCurrency().rate = Clamp(atoi(str->c_str()), 1, UINT16_MAX);
2029 break;
2030
2031 case WID_CC_SEPARATOR: // Thousands separator
2032 GetCustomCurrency().separator = std::move(*str);
2033 break;
2034
2035 case WID_CC_PREFIX:
2036 GetCustomCurrency().prefix = std::move(*str);
2037 break;
2038
2039 case WID_CC_SUFFIX:
2040 GetCustomCurrency().suffix = std::move(*str);
2041 break;
2042
2043 case WID_CC_YEAR: { // Year to switch to euro
2044 TimerGameCalendar::Year val{atoi(str->c_str())};
2045
2047 break;
2048 }
2049 }
2051 SetButtonState();
2052 }
2053
2054 void OnTimeout() override
2055 {
2056 this->SetDirty();
2057 }
2058};
2059
2060static constexpr NWidgetPart _nested_cust_currency_widgets[] = {
2062 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
2063 NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_CURRENCY_WINDOW, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2064 EndContainer(),
2065 NWidget(WWT_PANEL, COLOUR_GREY),
2070 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_DOWN), SetArrowWidgetTypeTip(AWV_DECREASE, STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP),
2071 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_UP), SetArrowWidgetTypeTip(AWV_INCREASE, STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP),
2072 EndContainer(),
2073 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_RATE), SetToolTip(STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP), SetFill(1, 0),
2074 EndContainer(),
2076 NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SEPARATOR_EDIT), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(0, 1),
2077 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_SEPARATOR), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(1, 0),
2078 EndContainer(),
2080 NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_PREFIX_EDIT), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(0, 1),
2081 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_PREFIX), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(1, 0),
2082 EndContainer(),
2084 NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SUFFIX_EDIT), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(0, 1),
2085 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_SUFFIX), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(1, 0),
2086 EndContainer(),
2089 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_DOWN), SetArrowWidgetTypeTip(AWV_DECREASE, STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
2090 NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_UP), SetArrowWidgetTypeTip(AWV_INCREASE, STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
2091 EndContainer(),
2092 NWidget(WWT_TEXT, INVALID_COLOUR, WID_CC_YEAR), SetToolTip(STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP), SetFill(1, 0),
2093 EndContainer(),
2094 EndContainer(),
2095 NWidget(WWT_LABEL, INVALID_COLOUR, WID_CC_PREVIEW),
2096 SetToolTip(STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP),
2097 EndContainer(),
2098 EndContainer(),
2099};
2100
2101static WindowDesc _cust_currency_desc(
2102 WDP_CENTER, nullptr, 0, 0,
2104 {},
2105 _nested_cust_currency_widgets
2106);
2107
2109static void ShowCustCurrency()
2110{
2112 new CustomCurrencyWindow(_cust_currency_desc);
2113}
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.
void Add(std::unique_ptr< NWidgetBase > &&wid)
Append widget wid to container.
Definition widget.cpp:1280
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:1503
Base class for a resizable nested widget.
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:1729
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.
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:2447
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:2521
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
RectPadding frametext
Padding inside frame with text.
Definition window_gui.h:41
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:29
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:58
int hsep_wide
Wide horizontal spacing.
Definition window_gui.h:62
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:94
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:27
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:407
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
Definition dropdown.cpp:366
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:389
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)
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:923
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:852
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
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 AdjustGUIZoom(bool automatic)
Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested.
Definition gfx.cpp:1764
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:246
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:245
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:379
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:387
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition gfx_type.h:335
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 SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
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:3359
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:945
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1500
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:53
const LanguageMetadata * _current_language
The currently loaded language.
Definition strings.cpp:54
bool ReadLanguagePack(const LanguageMetadata *lang)
Read a particular language.
Definition strings.cpp:2004
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:1300
@ 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:387
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.
@ 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:60
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:58
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.
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.
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.
void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, StringID content_type)
Open the BaseSet version of the textfile window.
int SETTING_HEIGHT
Height of a single setting in the tree view in pixels.
void ShowGameSettings()
Open advanced settings window.
static uint GetCurrentResolutionIndex()
Get index of the current screen resolution.
void DrawBoolButton(int x, int y, bool state, bool clickable)
Draw a toggle button.
static void ShowCustCurrency()
Open custom currency window.
void ShowGameOptions()
Open the game options window.
Dimension _circle_size
Dimension of the circle +/- icon. This is here as not all users are within the class of the settings ...
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_GS_TYPE_DROPDOWN
The drop down box to choose client/game/company/all settings.
@ WID_GS_SETTING_DROPDOWN
Dynamically created dropdown for changing setting value.
@ WID_GS_EXPAND_ALL
Expand all button.
@ WID_GS_OPTIONSPANEL
Panel widget containing the option lists.
@ WID_GS_RESTRICT_CATEGORY
Label upfront to the category drop-down box to restrict the list of settings to show.
@ WID_GS_HELP_TEXT
Information area to display help text of the selected option.
@ WID_GS_RESTRICT_DROPDOWN
The drop down box to restrict the list of settings.
@ WID_GS_RESTRICT_TYPE
Label upfront to the type drop-down box to restrict the list of settings to show.
@ WID_GS_RESET_ALL
Reset all button.
@ WID_GS_SCROLLBAR
Scrollbar.
@ WID_GS_COLLAPSE_ALL
Collapse all button.
@ WID_GS_FILTER
Text filter.
@ WID_GO_BASE_SFX_OPEN_URL
Open base SFX URL.
@ 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_RESOLUTION_DROPDOWN
Dropdown for the resolution.
@ 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_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_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_BASE_GRF_TEXTFILE
Open base GRF readme, changelog (+1) or license (+2).
@ WID_GO_TAB_GENERAL
General tab.
@ WID_GO_BASE_GRF_DROPDOWN
Use to select a base GRF.
@ WID_GO_BASE_MUSIC_VOLUME
Change music volume.
@ 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_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_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_TEXT_MUSIC_VOLUME
Music volume label.
@ WID_GO_BASE_MUSIC_JUKEBOX
Open the jukebox.
@ WID_GO_SOCIAL_PLUGIN_STATE
State of the social plugin.
@ 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_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_VIDEO_ACCEL_BUTTON
Toggle for video acceleration.
@ WID_GO_TAB_SOCIAL
Social tab.
@ 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_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_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, 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:31
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:91
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:277
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.
const char * GetCurrentLanguageIsoCode()
Get the ISO language code of the currently loaded language.
Definition strings.cpp:2249
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:2357
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:426
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
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.
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.
SettingEntryFlags flags
Flags of the setting entry.
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.
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.
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) override
A dropdown option associated to this window has been selected.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
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.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
DropDownList BuildDropDownList(WidgetID widget, int *selected_index) const
Build the dropdown list for a specific widget.
Window to edit settings of the game.
bool manually_changed_folding
Whether the user expanded/collapsed something manually.
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
SettingEntry * valuewindow_entry
If non-nullptr, pointer to setting for which a value-entering window has been opened.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
SettingEntry * clicked_entry
If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button).
void OnTimeout() override
Called when this window's timeout has been reached.
QueryString filter_editbox
Filter editbox;.
SettingEntry * valuedropdown_entry
If non-nullptr, pointer to the value for which a dropdown window is currently opened.
bool closing_dropdown
True, if the dropdown list is currently closing.
void OnInit() override
Notification that the nested widget tree gets initialized.
SettingFilter filter
Filter for the list.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
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.
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 OnResize() override
Called after the window got resized.
SettingEntry * last_clicked
If non-nullptr, pointer to the last clicked setting.
void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
A dropdown window associated to this window has been closed.
WarnHiddenResult warn_missing
Whether and how to warn about missing search results.
void OnDropdownSelect(WidgetID widget, int index) override
A dropdown option associated to this window has been selected.
void OnPaint() override
The window must be repainted.
static GameSettings * settings_ptr
Pointer to the game settings being displayed and modified.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
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.
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.
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.
int Width() const
Get width of Rect.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Standard setting.
void SetButtons(SettingEntryFlags new_val)
Set the button-depressed flags (#SettingsEntryFlag::LeftDepressed and #SettingsEntryFlag::RightDepres...
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.
const char * GetText() const
Get the current text.
Definition textbuf.cpp:286
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:168
Data structure for an opened window.
Definition window_gui.h:274
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:957
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1052
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1738
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition window_gui.h:321
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:744
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3166
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:556
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:504
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:327
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition window.cpp:1040
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition window_gui.h:392
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:516
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1728
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:485
virtual void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close)
A dropdown window associated to this window has been closed.
Definition window.cpp:286
void SetWidgetsLoweredState(bool lowered_stat, Args... widgets)
Sets the lowered/raised status of a list of widgets.
Definition window_gui.h:527
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
void EnableWidget(WidgetID widget_index)
Sets a widget to Enabled.
Definition window_gui.h:401
void SetTimeout()
Set the timeout flag of the window and initiate the timer.
Definition window_gui.h:356
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:973
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:461
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1751
WindowFlags flags
Window flags.
Definition window_gui.h:301
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:313
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
int height
Height of the window (number of pixels down in y direction)
Definition window_gui.h:313
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
@ 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, const std::string &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:296
void SetupWidgetDimensions()
Set up pre-scaled versions of Widget Dimensions.
Definition widget.cpp:79
@ 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:47
@ WWT_EDITBOX
a textbox for typing
Definition widget_type.h:61
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:65
@ 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:51
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:75
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:67
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:59
@ WWT_FRAME
Frame.
Definition widget_type.h:50
@ 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:58
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:55
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:60
@ WWT_TEXT
Pure simple text.
Definition widget_type.h:48
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:70
@ 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.
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:1145
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Definition window.cpp:3342
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1157
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3134
Window functions not directly related to making/drawing windows.
@ 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:146
int WidgetID
Widget ID.
Definition window_type.h:20
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
Definition window_type.h:28
@ WN_GAME_OPTIONS_GAME_SETTINGS
Game settings.
Definition window_type.h:29
@ 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.