OpenTTD Source  14.0-RC3
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"
17 #include "town.h"
18 #include "settings_internal.h"
19 #include "strings_func.h"
20 #include "window_func.h"
21 #include "string_func.h"
22 #include "widgets/dropdown_type.h"
23 #include "widgets/dropdown_func.h"
24 #include "widgets/slider_func.h"
25 #include "highscore.h"
26 #include "base_media_base.h"
27 #include "company_base.h"
28 #include "company_func.h"
29 #include "viewport_func.h"
30 #include "core/geometry_func.hpp"
31 #include "ai/ai.hpp"
32 #include "blitter/factory.hpp"
33 #include "language.h"
34 #include "textfile_gui.h"
35 #include "stringfilter_type.h"
36 #include "querystring_gui.h"
37 #include "fontcache.h"
38 #include "zoom_func.h"
39 #include "rev.h"
40 #include "video/video_driver.hpp"
41 #include "music/music_driver.hpp"
42 #include "gui.h"
43 #include "mixer.h"
44 #include "newgrf_config.h"
45 #include "network/core/config.h"
46 #include "network/network_gui.h"
47 #include "network/network_survey.h"
48 #include "video/video_driver.hpp"
49 #include "social_integration.h"
50 
51 #include "safeguards.h"
52 
53 
54 #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
55 # define HAS_TRUETYPE_FONT
56 #endif
57 
58 static const StringID _autosave_dropdown[] = {
59  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF,
60  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES,
61  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES,
62  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES,
63  STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES,
65 };
66 
68 static const uint32_t _autosave_dropdown_to_minutes[] = {
69  0,
70  10,
71  30,
72  60,
73  120,
74 };
75 
77 
78 static const void *ResolveObject(const GameSettings *settings_ptr, const IntSettingDesc *sd);
79 
85 {
86  auto it = std::find(_resolutions.begin(), _resolutions.end(), Dimension(_screen.width, _screen.height));
87  return std::distance(_resolutions.begin(), it);
88 }
89 
90 static void ShowCustCurrency();
91 
93 template <class TBaseSet>
95  const TBaseSet *baseset;
97 
99  {
100  this->ConstructWindow();
101 
102  auto textfile = this->baseset->GetTextfile(file_type);
103  this->LoadTextfile(textfile.value(), BASESET_DIR);
104  }
105 
106  void SetStringParameters(WidgetID widget) const override
107  {
108  if (widget == WID_TF_CAPTION) {
110  SetDParamStr(1, this->baseset->name);
111  }
112  }
113 };
114 
121 template <class TBaseSet>
122 void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, StringID content_type)
123 {
124  CloseWindowById(WC_TEXTFILE, file_type);
125  new BaseSetTextfileWindow<TBaseSet>(file_type, baseset, content_type);
126 }
127 
128 std::set<int> _refresh_rates = { 30, 60, 75, 90, 100, 120, 144, 240 };
129 
135 {
136  /* Add the refresh rate as selected in the config. */
137  _refresh_rates.insert(_settings_client.gui.refresh_rate);
138 
139  /* Add all the refresh rates of all monitors connected to the machine. */
140  std::vector<int> monitorRates = VideoDriver::GetInstance()->GetListOfMonitorRefreshRates();
141  std::copy(monitorRates.begin(), monitorRates.end(), std::inserter(_refresh_rates, _refresh_rates.end()));
142 }
143 
144 static const std::map<int, StringID> _scale_labels = {
145  { 100, STR_GAME_OPTIONS_GUI_SCALE_1X },
146  { 125, STR_NULL },
147  { 150, STR_NULL },
148  { 175, STR_NULL },
149  { 200, STR_GAME_OPTIONS_GUI_SCALE_2X },
150  { 225, STR_NULL },
151  { 250, STR_NULL },
152  { 275, STR_NULL },
153  { 300, STR_GAME_OPTIONS_GUI_SCALE_3X },
154  { 325, STR_NULL },
155  { 350, STR_NULL },
156  { 375, STR_NULL },
157  { 400, STR_GAME_OPTIONS_GUI_SCALE_4X },
158  { 425, STR_NULL },
159  { 450, STR_NULL },
160  { 475, STR_NULL },
161  { 500, STR_GAME_OPTIONS_GUI_SCALE_5X },
162 };
163 
164 static const std::map<int, StringID> _volume_labels = {
165  { 0, STR_GAME_OPTIONS_VOLUME_0 },
166  { 15, STR_NULL },
167  { 31, STR_GAME_OPTIONS_VOLUME_25 },
168  { 47, STR_NULL },
169  { 63, STR_GAME_OPTIONS_VOLUME_50 },
170  { 79, STR_NULL },
171  { 95, STR_GAME_OPTIONS_VOLUME_75 },
172  { 111, STR_NULL },
173  { 127, STR_GAME_OPTIONS_VOLUME_100 },
174 };
175 
176 static const NWidgetPart _nested_social_plugins_widgets[] = {
178  NWidget(WWT_FRAME, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_TITLE), SetDataTip(STR_JUST_STRING2, STR_NULL),
180  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM, STR_NULL),
181  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_PLATFORM), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_NULL), SetAlignment(SA_RIGHT),
182  EndContainer(),
184  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE, STR_NULL),
185  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_SOCIAL_PLUGIN_STATE), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING1, STR_NULL), SetAlignment(SA_RIGHT),
186  EndContainer(),
187  EndContainer(),
188  EndContainer(),
189 };
190 
191 static const NWidgetPart _nested_social_plugins_none_widgets[] = {
193  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE, STR_NULL),
194  EndContainer(),
195 };
196 
198 public:
200  {
201  this->plugins = SocialIntegration::GetPlugins();
202 
203  if (this->plugins.empty()) {
204  auto widget = MakeNWidgets(std::begin(_nested_social_plugins_none_widgets), std::end(_nested_social_plugins_none_widgets), nullptr);
205  this->Add(std::move(widget));
206  } else {
207  for (size_t i = 0; i < this->plugins.size(); i++) {
208  auto widget = MakeNWidgets(std::begin(_nested_social_plugins_widgets), std::end(_nested_social_plugins_widgets), nullptr);
209  this->Add(std::move(widget));
210  }
211  }
212 
213  this->SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0);
214  }
215 
216  void FillWidgetLookup(WidgetLookup &widget_lookup) override
217  {
218  widget_lookup[WID_GO_SOCIAL_PLUGINS] = this;
219  NWidgetVertical::FillWidgetLookup(widget_lookup);
220  }
221 
222  void SetupSmallestSize(Window *w) override
223  {
224  this->current_index = -1;
226  }
227 
234  template <typename T>
235  std::string &GetWidestPlugin(T SocialIntegrationPlugin::*member) const
236  {
237  std::string *longest = &(this->plugins[0]->*member);
238  int longest_length = 0;
239 
240  for (auto *plugin : this->plugins) {
241  int length = GetStringBoundingBox(plugin->*member).width;
242  if (length > longest_length) {
243  longest_length = length;
244  longest = &(plugin->*member);
245  }
246  }
247 
248  return *longest;
249  }
250 
251  void SetStringParameters(int widget) const
252  {
253  switch (widget) {
255  /* For SetupSmallestSize, use the longest string we have. */
256  if (this->current_index < 0) {
259  break;
260  }
261 
262  if (this->plugins[this->current_index]->name.empty()) {
263  SetDParam(0, STR_JUST_RAW_STRING);
264  SetDParamStr(1, this->plugins[this->current_index]->basepath);
265  } else {
266  SetDParam(0, STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE);
267  SetDParamStr(1, this->plugins[this->current_index]->name);
268  SetDParamStr(2, this->plugins[this->current_index]->version);
269  }
270  break;
271 
273  /* For SetupSmallestSize, use the longest string we have. */
274  if (this->current_index < 0) {
276  break;
277  }
278 
279  SetDParamStr(0, this->plugins[this->current_index]->social_platform);
280  break;
281 
283  static const std::pair<SocialIntegrationPlugin::State, StringID> state_to_string[] = {
284  { SocialIntegrationPlugin::RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_RUNNING },
285  { SocialIntegrationPlugin::FAILED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED },
286  { SocialIntegrationPlugin::PLATFORM_NOT_RUNNING, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_PLATFORM_NOT_RUNNING },
287  { SocialIntegrationPlugin::UNLOADED, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNLOADED },
288  { SocialIntegrationPlugin::DUPLICATE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_DUPLICATE },
289  { SocialIntegrationPlugin::UNSUPPORTED_API, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_UNSUPPORTED_API },
290  { SocialIntegrationPlugin::INVALID_SIGNATURE, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_INVALID_SIGNATURE },
291  };
292 
293  /* For SetupSmallestSize, use the longest string we have. */
294  if (this->current_index < 0) {
296 
297  /* Set the longest plugin when looking for the longest status. */
298  SetDParamStr(0, longest_plugin);
299 
300  StringID longest = STR_NULL;
301  int longest_length = 0;
302  for (auto state : state_to_string) {
303  int length = GetStringBoundingBox(state.second).width;
304  if (length > longest_length) {
305  longest_length = length;
306  longest = state.second;
307  }
308  }
309 
310  SetDParam(0, longest);
311  SetDParamStr(1, longest_plugin);
312  break;
313  }
314 
315  auto plugin = this->plugins[this->current_index];
316 
317  /* Default string, in case no state matches. */
318  SetDParam(0, STR_GAME_OPTIONS_SOCIAL_PLUGIN_STATE_FAILED);
319  SetDParamStr(1, plugin->social_platform);
320 
321  /* Find the string for the state. */
322  for (auto state : state_to_string) {
323  if (plugin->state == state.first) {
324  SetDParam(0, state.second);
325  break;
326  }
327  }
328  }
329  break;
330  }
331  }
332 
333  void Draw(const Window *w) override
334  {
335  this->current_index = 0;
336 
337  for (auto &wid : this->children) {
338  wid->Draw(w);
339  this->current_index++;
340  }
341  }
342 
343 private:
344  int current_index = -1;
345  std::vector<SocialIntegrationPlugin *> plugins;
346 };
347 
349 std::unique_ptr<NWidgetBase> MakeNWidgetSocialPlugins()
350 {
351  return std::make_unique<NWidgetSocialPlugins>();
352 }
353 
355  GameSettings *opt;
356  bool reload;
357  int gui_scale;
358  static inline WidgetID active_tab = WID_GO_TAB_GENERAL;
359 
360  GameOptionsWindow(WindowDesc *desc) : Window(desc)
361  {
362  this->opt = &GetGameSettings();
363  this->reload = false;
364  this->gui_scale = _gui_scale;
365 
367 
369  this->OnInvalidateData(0);
370 
371  this->SetTab(GameOptionsWindow::active_tab);
372 
373  if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) this->GetWidget<NWidgetStacked>(WID_GO_SURVEY_SEL)->SetDisplayedPlane(SZSP_NONE);
374  }
375 
376  void Close([[maybe_unused]] int data = 0) override
377  {
380  if (this->reload) _switch_mode = SM_MENU;
381  this->Window::Close();
382  }
383 
390  DropDownList BuildDropDownList(WidgetID widget, int *selected_index) const
391  {
392  DropDownList list;
393  switch (widget) {
394  case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown
395  *selected_index = this->opt->locale.currency;
396  uint64_t disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies();
397 
398  /* Add non-custom currencies; sorted naturally */
399  for (const CurrencySpec &currency : _currency_specs) {
400  int i = &currency - _currency_specs;
401  if (i == CURRENCY_CUSTOM) continue;
402  if (currency.code.empty()) {
403  list.push_back(std::make_unique<DropDownListStringItem>(currency.name, i, HasBit(disabled, i)));
404  } else {
405  SetDParam(0, currency.name);
406  SetDParamStr(1, currency.code);
407  list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i)));
408  }
409  }
410  std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
411 
412  /* Append custom currency at the end */
413  list.push_back(std::make_unique<DropDownListDividerItem>(-1, false)); // separator line
414  list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)));
415  break;
416  }
417 
418  case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown
419  int index = 0;
420  for (auto &minutes : _autosave_dropdown_to_minutes) {
421  index++;
422  if (_settings_client.gui.autosave_interval <= minutes) break;
423  }
424  *selected_index = index - 1;
425 
426  const StringID *items = _autosave_dropdown;
427  for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) {
428  list.push_back(std::make_unique<DropDownListStringItem>(*items, i, false));
429  }
430  break;
431  }
432 
433  case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown
434  for (uint i = 0; i < _languages.size(); i++) {
435  bool hide_language = IsReleasedVersion() && !_languages[i].IsReasonablyFinished();
436  if (hide_language) continue;
437  bool hide_percentage = IsReleasedVersion() || _languages[i].missing < _settings_client.gui.missing_strings_threshold;
438  if (&_languages[i] == _current_language) {
439  *selected_index = i;
440  SetDParamStr(0, _languages[i].own_name);
441  } else {
442  /* Especially with sprite-fonts, not all localized
443  * names can be rendered. So instead, we use the
444  * international names for anything but the current
445  * selected language. This avoids showing a few ????
446  * entries in the dropdown list. */
447  SetDParamStr(0, _languages[i].name);
448  }
449  SetDParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS);
450  list.push_back(std::make_unique<DropDownListStringItem>(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false));
451  }
452  std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
453  break;
454  }
455 
456  case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown
457  if (_resolutions.empty()) break;
458 
459  *selected_index = GetCurrentResolutionIndex();
460  for (uint i = 0; i < _resolutions.size(); i++) {
463  list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false));
464  }
465  break;
466 
467  case WID_GO_REFRESH_RATE_DROPDOWN: // Setup refresh rate dropdown
468  for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) {
469  auto i = std::distance(_refresh_rates.begin(), it);
470  if (*it == _settings_client.gui.refresh_rate) *selected_index = i;
471  SetDParam(0, *it);
472  list.push_back(std::make_unique<DropDownListStringItem>(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false));
473  }
474  break;
475 
477  list = BuildSetDropDownList<BaseGraphics>(selected_index);
478  break;
479 
481  list = BuildSetDropDownList<BaseSounds>(selected_index);
482  break;
483 
485  list = BuildSetDropDownList<BaseMusic>(selected_index);
486  break;
487  }
488 
489  return list;
490  }
491 
492  void SetStringParameters(WidgetID widget) const override
493  {
494  switch (widget) {
496  const CurrencySpec &currency = _currency_specs[this->opt->locale.currency];
497  if (currency.code.empty()) {
498  SetDParam(0, currency.name);
499  } else {
500  SetDParam(0, STR_GAME_OPTIONS_CURRENCY_CODE);
501  SetDParam(1, currency.name);
502  SetDParamStr(2, currency.code);
503  }
504  break;
505  }
507  int index = 0;
508  for (auto &minutes : _autosave_dropdown_to_minutes) {
509  index++;
510  if (_settings_client.gui.autosave_interval <= minutes) break;
511  }
512  SetDParam(0, _autosave_dropdown[index - 1]);
513  break;
514  }
516  case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->GetListLabel()); break;
517  case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->GetListLabel()); break;
518  case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->GetListLabel()); break;
521  auto current_resolution = GetCurrentResolutionIndex();
522 
523  if (current_resolution == _resolutions.size()) {
524  SetDParam(0, STR_GAME_OPTIONS_RESOLUTION_OTHER);
525  } else {
526  SetDParam(0, STR_GAME_OPTIONS_RESOLUTION_ITEM);
527  SetDParam(1, _resolutions[current_resolution].width);
528  SetDParam(2, _resolutions[current_resolution].height);
529  }
530  break;
531  }
532 
536  const NWidgetSocialPlugins *plugin = this->GetWidget<NWidgetSocialPlugins>(WID_GO_SOCIAL_PLUGINS);
537  assert(plugin != nullptr);
538 
539  plugin->SetStringParameters(widget);
540  break;
541  }
542  }
543  }
544 
545  void DrawWidget(const Rect &r, WidgetID widget) const override
546  {
547  switch (widget) {
550  DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
551  break;
552 
555  DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
556  break;
557 
560  DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
561  break;
562 
563  case WID_GO_GUI_SCALE:
564  DrawSliderWidget(r, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, this->gui_scale, _scale_labels);
565  break;
566 
568  SetDParamStr(0, VideoDriver::GetInstance()->GetInfoString());
569  DrawStringMultiLine(r, STR_GAME_OPTIONS_VIDEO_DRIVER_INFO);
570  break;
571 
573  DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, _volume_labels);
574  break;
575 
577  DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, _volume_labels);
578  break;
579  }
580  }
581 
582  void SetTab(WidgetID widget)
583  {
585  this->LowerWidget(widget);
586  GameOptionsWindow::active_tab = widget;
587 
588  int pane;
589  switch (widget) {
590  case WID_GO_TAB_GENERAL: pane = 0; break;
591  case WID_GO_TAB_GRAPHICS: pane = 1; break;
592  case WID_GO_TAB_SOUND: pane = 2; break;
593  case WID_GO_TAB_SOCIAL: pane = 3; break;
594  default: NOT_REACHED();
595  }
596 
597  this->GetWidget<NWidgetStacked>(WID_GO_TAB_SELECTION)->SetDisplayedPlane(pane);
598  this->SetDirty();
599  }
600 
601  void OnResize() override
602  {
603  bool changed = false;
604 
605  NWidgetResizeBase *wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_GRF_DESCRIPTION);
606  int y = 0;
607  for (int i = 0; i < BaseGraphics::GetNumSets(); i++) {
609  y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x));
610  }
611  changed |= wid->UpdateVerticalSize(y);
612 
613  wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_SFX_DESCRIPTION);
614  y = 0;
615  for (int i = 0; i < BaseSounds::GetNumSets(); i++) {
617  y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x));
618  }
619  changed |= wid->UpdateVerticalSize(y);
620 
621  wid = this->GetWidget<NWidgetResizeBase>(WID_GO_BASE_MUSIC_DESCRIPTION);
622  y = 0;
623  for (int i = 0; i < BaseMusic::GetNumSets(); i++) {
624  SetDParamStr(0, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode()));
625  y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x));
626  }
627  changed |= wid->UpdateVerticalSize(y);
628 
629  wid = this->GetWidget<NWidgetResizeBase>(WID_GO_VIDEO_DRIVER_INFO);
630  SetDParamStr(0, VideoDriver::GetInstance()->GetInfoString());
631  y = GetStringHeight(STR_GAME_OPTIONS_VIDEO_DRIVER_INFO, wid->current_x);
632  changed |= wid->UpdateVerticalSize(y);
633 
634  if (changed) this->ReInit(0, 0, this->flags & WF_CENTERED);
635  }
636 
637  void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
638  {
639  switch (widget) {
642  Dimension d = maxdim(GetStringBoundingBox(STR_GAME_OPTIONS_SFX_VOLUME), GetStringBoundingBox(STR_GAME_OPTIONS_MUSIC_VOLUME));
643  d.width += padding.width;
644  d.height += padding.height;
645  *size = maxdim(*size, d);
646  break;
647  }
648 
657  int selected;
658  size->width = std::max(size->width, GetDropDownListDimension(this->BuildDropDownList(widget, &selected)).width + padding.width);
659  break;
660  }
661  }
662  }
663 
664  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
665  {
666  if (widget >= WID_GO_BASE_GRF_TEXTFILE && widget < WID_GO_BASE_GRF_TEXTFILE + TFT_CONTENT_END) {
667  if (BaseGraphics::GetUsedSet() == nullptr) return;
668 
669  ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_GRF_TEXTFILE), BaseGraphics::GetUsedSet(), STR_CONTENT_TYPE_BASE_GRAPHICS);
670  return;
671  }
672  if (widget >= WID_GO_BASE_SFX_TEXTFILE && widget < WID_GO_BASE_SFX_TEXTFILE + TFT_CONTENT_END) {
673  if (BaseSounds::GetUsedSet() == nullptr) return;
674 
675  ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_SFX_TEXTFILE), BaseSounds::GetUsedSet(), STR_CONTENT_TYPE_BASE_SOUNDS);
676  return;
677  }
678  if (widget >= WID_GO_BASE_MUSIC_TEXTFILE && widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_CONTENT_END) {
679  if (BaseMusic::GetUsedSet() == nullptr) return;
680 
681  ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_MUSIC_TEXTFILE), BaseMusic::GetUsedSet(), STR_CONTENT_TYPE_BASE_MUSIC);
682  return;
683  }
684  switch (widget) {
685  case WID_GO_TAB_GENERAL:
686  case WID_GO_TAB_GRAPHICS:
687  case WID_GO_TAB_SOUND:
688  case WID_GO_TAB_SOCIAL:
689  this->SetTab(widget);
690  break;
691 
694  case PS_ASK:
695  case PS_NO:
697  break;
698 
699  case PS_YES:
701  break;
702  }
703 
706  break;
707 
709  OpenBrowser(NETWORK_SURVEY_DETAILS_LINK);
710  break;
711 
713  ShowSurveyResultTextfileWindow();
714  break;
715 
716  case WID_GO_FULLSCREEN_BUTTON: // Click fullscreen on/off
717  /* try to toggle full-screen on/off */
718  if (!ToggleFullScreen(!_fullscreen)) {
719  ShowErrorMessage(STR_ERROR_FULLSCREEN_FAILED, INVALID_STRING_ID, WL_ERROR);
720  }
723  break;
724 
727  ShowErrorMessage(STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART, INVALID_STRING_ID, WL_INFO);
730 #ifndef __APPLE__
734 #endif
735  break;
736 
738  if (!_video_hw_accel) break;
739 
742 
747  break;
748 
751 
753  this->SetDirty();
754 
756  ReInitAllWindows(true);
757  break;
758  }
759 
760 #ifdef HAS_TRUETYPE_FONT
762  _fcsettings.prefer_sprite = !_fcsettings.prefer_sprite;
763 
766  this->SetDirty();
767 
768  InitFontCache(false);
769  InitFontCache(true);
770  ClearFontCache();
774  ReInitAllWindows(true);
775  break;
776 
777  case WID_GO_GUI_FONT_AA:
778  _fcsettings.global_aa = !_fcsettings.global_aa;
779 
782 
783  ClearFontCache();
784  break;
785 #endif /* HAS_TRUETYPE_FONT */
786 
787  case WID_GO_GUI_SCALE:
788  if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, this->gui_scale)) {
789  if (!_ctrl_pressed) this->gui_scale = ((this->gui_scale + 12) / 25) * 25;
790  this->SetWidgetDirty(widget);
791  }
792 
793  if (click_count > 0) this->mouse_capture_widget = widget;
794  break;
795 
797  {
798  if (_gui_scale_cfg == -1) {
801  } else {
802  _gui_scale_cfg = -1;
804  if (AdjustGUIZoom(false)) ReInitAllWindows(true);
805  this->gui_scale = _gui_scale;
806  }
807  this->SetWidgetDirty(widget);
808  break;
809  }
810 
812  auto *used_set = BaseGraphics::GetUsedSet();
813  if (used_set == nullptr || !used_set->IsConfigurable()) break;
814  GRFConfig &extra_cfg = used_set->GetOrCreateExtraConfig();
815  if (extra_cfg.num_params == 0) extra_cfg.SetParameterDefaults();
816  OpenGRFParameterWindow(true, &extra_cfg, _game_mode == GM_MENU);
817  if (_game_mode == GM_MENU) this->reload = true;
818  break;
819  }
820 
824  if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) {
825  if (widget == WID_GO_BASE_MUSIC_VOLUME) {
827  } else {
828  SetEffectVolume(vol);
829  }
830  this->SetWidgetDirty(widget);
832  }
833 
834  if (click_count > 0) this->mouse_capture_widget = widget;
835  break;
836  }
837 
839  ShowMusicWindow();
840  break;
841  }
842 
844  if (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->url.empty()) return;
845  OpenBrowser(BaseGraphics::GetUsedSet()->url);
846  break;
847 
849  if (BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->url.empty()) return;
850  OpenBrowser(BaseSounds::GetUsedSet()->url);
851  break;
852 
854  if (BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->url.empty()) return;
855  OpenBrowser(BaseMusic::GetUsedSet()->url);
856  break;
857 
866  int selected;
867  DropDownList list = this->BuildDropDownList(widget, &selected);
868  if (!list.empty()) {
869  ShowDropDownList(this, std::move(list), selected, widget);
870  } else {
871  if (widget == WID_GO_RESOLUTION_DROPDOWN) ShowErrorMessage(STR_ERROR_RESOLUTION_LIST_FAILED, INVALID_STRING_ID, WL_ERROR);
872  }
873  break;
874  }
875  }
876  }
877 
878  void OnMouseLoop() override
879  {
880  if (_left_button_down || this->gui_scale == _gui_scale) return;
881 
882  _gui_scale_cfg = this->gui_scale;
883 
884  if (AdjustGUIZoom(false)) {
885  ReInitAllWindows(true);
887  this->SetDirty();
888  }
889  }
890 
891  void OnDropdownSelect(WidgetID widget, int index) override
892  {
893  switch (widget) {
894  case WID_GO_CURRENCY_DROPDOWN: // Currency
895  if (index == CURRENCY_CUSTOM) ShowCustCurrency();
896  this->opt->locale.currency = index;
897  ReInitAllWindows(false);
898  break;
899 
900  case WID_GO_AUTOSAVE_DROPDOWN: // Autosave options
903  this->SetDirty();
904  break;
905 
906  case WID_GO_LANG_DROPDOWN: // Change interface language
907  ReadLanguagePack(&_languages[index]);
910  ClearAllCachedNames();
912  CheckBlitter();
913  ReInitAllWindows(false);
914  break;
915 
916  case WID_GO_RESOLUTION_DROPDOWN: // Change resolution
917  if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) {
918  this->SetDirty();
919  }
920  break;
921 
923  _settings_client.gui.refresh_rate = *std::next(_refresh_rates.begin(), index);
924  if (_settings_client.gui.refresh_rate > 60) {
925  /* Show warning to the user that this refresh rate might not be suitable on
926  * larger maps with many NewGRFs and vehicles. */
927  ShowErrorMessage(STR_GAME_OPTIONS_REFRESH_RATE_WARNING, INVALID_STRING_ID, WL_INFO);
928  }
929  break;
930  }
931 
933  if (_game_mode == GM_MENU) {
935  auto set = BaseGraphics::GetSet(index);
937  this->reload = true;
938  this->InvalidateData();
939  }
940  break;
941 
943  if (_game_mode == GM_MENU) {
944  auto set = BaseSounds::GetSet(index);
945  BaseSounds::ini_set = set->name;
946  BaseSounds::SetSet(set);
947  this->reload = true;
948  this->InvalidateData();
949  }
950  break;
951 
953  ChangeMusicSet(index);
954  break;
955  }
956  }
957 
963  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
964  {
965  if (!gui_scope) return;
970 
971 #ifndef __APPLE__
974 #endif
975 
978 #ifdef HAS_TRUETYPE_FONT
982 #endif /* HAS_TRUETYPE_FONT */
983 
984  this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
985  this->SetWidgetDisabledState(WID_GO_BASE_SFX_DROPDOWN, _game_mode != GM_MENU);
986 
988 
992 
993  for (TextfileType tft = TFT_CONTENT_BEGIN; tft < TFT_CONTENT_END; tft++) {
997  }
998  }
999 };
1000 
1001 static constexpr NWidgetPart _nested_game_options_widgets[] = {
1003  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1004  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1005  EndContainer(),
1006  NWidget(WWT_PANEL, COLOUR_GREY),
1008  NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GENERAL), SetMinimalTextLines(2, 0), SetDataTip(STR_GAME_OPTIONS_TAB_GENERAL, STR_GAME_OPTIONS_TAB_GENERAL_TT), SetFill(1, 0),
1009  NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_GRAPHICS), SetMinimalTextLines(2, 0), SetDataTip(STR_GAME_OPTIONS_TAB_GRAPHICS, STR_GAME_OPTIONS_TAB_GRAPHICS_TT), SetFill(1, 0),
1010  NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOUND), SetMinimalTextLines(2, 0), SetDataTip(STR_GAME_OPTIONS_TAB_SOUND, STR_GAME_OPTIONS_TAB_SOUND_TT), SetFill(1, 0),
1011  NWidget(WWT_TEXTBTN, COLOUR_YELLOW, WID_GO_TAB_SOCIAL), SetMinimalTextLines(2, 0), SetDataTip(STR_GAME_OPTIONS_TAB_SOCIAL, STR_GAME_OPTIONS_TAB_SOCIAL_TT), SetFill(1, 0),
1012  EndContainer(),
1013  EndContainer(),
1014  NWidget(WWT_PANEL, COLOUR_GREY),
1015  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_TAB_SELECTION),
1016  /* General tab */
1018  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_LANGUAGE, STR_NULL),
1019  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0),
1020  EndContainer(),
1021 
1022  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME, STR_NULL),
1023  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0),
1024  EndContainer(),
1025 
1026  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL),
1027  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING2, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0),
1028  EndContainer(),
1029 
1030  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GO_SURVEY_SEL),
1031  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1033  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY, STR_NULL),
1034  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PARTICIPATE_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP),
1035  EndContainer(),
1037  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_PREVIEW_BUTTON), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP),
1038  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_SURVEY_LINK_BUTTON), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK, STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP),
1039  EndContainer(),
1040  EndContainer(),
1041  EndContainer(),
1042  EndContainer(),
1043 
1044  /* Graphics tab */
1046  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME, STR_NULL),
1048  NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_GUI_SCALE), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(0, 0), SetDataTip(0x0, STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP),
1050  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO, STR_NULL),
1051  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_AUTO), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP),
1052  EndContainer(),
1054  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS, STR_NULL),
1055  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP),
1056  EndContainer(),
1057 #ifdef HAS_TRUETYPE_FONT
1059  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE, STR_NULL),
1060  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP),
1061  EndContainer(),
1063  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_AA, STR_NULL),
1064  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP),
1065  EndContainer(),
1066 #endif /* HAS_TRUETYPE_FONT */
1067  EndContainer(),
1068  EndContainer(),
1069 
1070  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GRAPHICS, STR_NULL),
1073  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL),
1074  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING2, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP),
1075  EndContainer(),
1077  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_REFRESH_RATE, STR_NULL),
1078  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_REFRESH_RATE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP),
1079  EndContainer(),
1081  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_FULLSCREEN, STR_NULL),
1082  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_FULLSCREEN_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP),
1083  EndContainer(),
1085  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_ACCELERATION, STR_NULL),
1086  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_ACCEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP),
1087  EndContainer(),
1088 #ifndef __APPLE__
1090  NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_VIDEO_VSYNC, STR_NULL),
1091  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_VIDEO_VSYNC_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP),
1092  EndContainer(),
1093 #endif
1095  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_VIDEO_DRIVER_INFO), SetMinimalTextLines(1, 0), SetFill(1, 0),
1096  EndContainer(),
1097  EndContainer(),
1098  EndContainer(),
1099 
1100  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0), SetFill(1, 0),
1102  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), SetFill(1, 0),
1103  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_GRF_PARAMETERS), SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL),
1104  EndContainer(),
1105  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(200, 0), SetDataTip(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), SetDataTip(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), SetDataTip(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), SetDataTip(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), SetDataTip(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), SetDataTip(STR_GAME_OPTIONS_VOLUME, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
1123  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_TEXT_SFX_VOLUME), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_SFX_VOLUME, STR_NULL),
1124  NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_BASE_SFX_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
1125  EndContainer(),
1127  NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_TEXT_MUSIC_VOLUME), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_MUSIC_VOLUME, STR_NULL),
1128  NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_BASE_MUSIC_VOLUME), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
1129  EndContainer(),
1130  EndContainer(),
1131 
1132  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1133  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), SetFill(1, 0),
1134  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_NULL, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0),
1137  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1138  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1139  EndContainer(),
1141  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1142  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_SFX_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1143  EndContainer(),
1144  EndContainer(),
1145  EndContainer(),
1146 
1147  NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
1148  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), SetFill(1, 0),
1150  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_NULL, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0),
1151  NWidget(NWID_VERTICAL), SetPIPRatio(0, 0, 1),
1152  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW),
1153  EndContainer(),
1154  EndContainer(),
1157  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP),
1158  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_TEXTFILE_VIEW_README_TOOLTIP),
1159  EndContainer(),
1161  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_TEXTFILE_VIEW_CHANGELOG_TOOLTIP),
1162  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_TEXTFILE_VIEW_LICENCE_TOOLTIP),
1163  EndContainer(),
1164  EndContainer(),
1165  EndContainer(),
1166  EndContainer(),
1167 
1168  /* Social tab */
1171  EndContainer(),
1172  EndContainer(),
1173  EndContainer(),
1174 };
1175 
1176 static WindowDesc _game_options_desc(__FILE__, __LINE__,
1177  WDP_CENTER, nullptr, 0, 0,
1179  0,
1180  std::begin(_nested_game_options_widgets), std::end(_nested_game_options_widgets)
1181 );
1182 
1185 {
1187  new GameOptionsWindow(&_game_options_desc);
1188 }
1189 
1190 static int SETTING_HEIGHT = 11;
1191 
1200 
1202  SEF_FILTERED = 0x08,
1203 };
1204 
1213 };
1215 
1216 
1220  bool type_hides;
1223 };
1224 
1227  byte flags;
1228  byte level;
1229 
1230  BaseSettingEntry() : flags(0), level(0) {}
1231  virtual ~BaseSettingEntry() = default;
1232 
1233  virtual void Init(byte level = 0);
1234  virtual void FoldAll() {}
1235  virtual void UnFoldAll() {}
1236  virtual void ResetAll() = 0;
1237 
1242  void SetLastField(bool last_field) { if (last_field) SETBITS(this->flags, SEF_LAST_FIELD); else CLRBITS(this->flags, SEF_LAST_FIELD); }
1243 
1244  virtual uint Length() const = 0;
1245  virtual void GetFoldingState([[maybe_unused]] bool &all_folded, [[maybe_unused]] bool &all_unfolded) const {}
1246  virtual bool IsVisible(const BaseSettingEntry *item) const;
1247  virtual BaseSettingEntry *FindEntry(uint row, uint *cur_row);
1248  virtual uint GetMaxHelpHeight([[maybe_unused]] int maxw) { return 0; }
1249 
1254  bool IsFiltered() const { return (this->flags & SEF_FILTERED) != 0; }
1255 
1256  virtual bool UpdateFilterState(SettingFilter &filter, bool force_visible) = 0;
1257 
1258  virtual 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;
1259 
1260 protected:
1261  virtual void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const = 0;
1262 };
1263 
1266  const char *name;
1268 
1269  SettingEntry(const char *name);
1270 
1271  void Init(byte level = 0) override;
1272  void ResetAll() override;
1273  uint Length() const override;
1274  uint GetMaxHelpHeight(int maxw) override;
1275  bool UpdateFilterState(SettingFilter &filter, bool force_visible) override;
1276 
1277  void SetButtons(byte new_val);
1278 
1279 protected:
1280  void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const override;
1281 
1282 private:
1284 };
1285 
1288  typedef std::vector<BaseSettingEntry*> EntryVector;
1289  EntryVector entries;
1290 
1291  template<typename T>
1292  T *Add(T *item)
1293  {
1294  this->entries.push_back(item);
1295  return item;
1296  }
1297 
1298  void Init(byte level = 0);
1299  void ResetAll();
1300  void FoldAll();
1301  void UnFoldAll();
1302 
1303  uint Length() const;
1304  void GetFoldingState(bool &all_folded, bool &all_unfolded) const;
1305  bool IsVisible(const BaseSettingEntry *item) const;
1306  BaseSettingEntry *FindEntry(uint row, uint *cur_row);
1307  uint GetMaxHelpHeight(int maxw);
1308 
1309  bool UpdateFilterState(SettingFilter &filter, bool force_visible);
1310 
1311  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;
1312 };
1313 
1317  bool folded;
1318 
1320 
1321  void Init(byte level = 0) override;
1322  void ResetAll() override;
1323  void FoldAll() override;
1324  void UnFoldAll() override;
1325 
1326  uint Length() const override;
1327  void GetFoldingState(bool &all_folded, bool &all_unfolded) const override;
1328  bool IsVisible(const BaseSettingEntry *item) const override;
1329  BaseSettingEntry *FindEntry(uint row, uint *cur_row) override;
1330  uint GetMaxHelpHeight(int maxw) override { return SettingsContainer::GetMaxHelpHeight(maxw); }
1331 
1332  bool UpdateFilterState(SettingFilter &filter, bool force_visible) override;
1333 
1334  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 override;
1335 
1336 protected:
1337  void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const override;
1338 };
1339 
1340 /* == BaseSettingEntry methods == */
1341 
1346 void BaseSettingEntry::Init(byte level)
1347 {
1348  this->level = level;
1349 }
1350 
1358 {
1359  if (this->IsFiltered()) return false;
1360  return this == item;
1361 }
1362 
1369 BaseSettingEntry *BaseSettingEntry::FindEntry(uint row_num, uint *cur_row)
1370 {
1371  if (this->IsFiltered()) return nullptr;
1372  if (row_num == *cur_row) return this;
1373  (*cur_row)++;
1374  return nullptr;
1375 }
1376 
1406 uint BaseSettingEntry::Draw(GameSettings *settings_ptr, int left, int right, int y, uint first_row, uint max_row, BaseSettingEntry *selected, uint cur_row, uint parent_last) const
1407 {
1408  if (this->IsFiltered()) return cur_row;
1409  if (cur_row >= max_row) return cur_row;
1410 
1411  bool rtl = _current_text_dir == TD_RTL;
1412  int offset = (rtl ? -(int)_circle_size.width : (int)_circle_size.width) / 2;
1414 
1415  int x = rtl ? right : left;
1416  if (cur_row >= first_row) {
1417  int colour = _colour_gradient[COLOUR_ORANGE][4];
1418  y += (cur_row - first_row) * SETTING_HEIGHT; // Compute correct y start position
1419 
1420  /* Draw vertical for parent nesting levels */
1421  for (uint lvl = 0; lvl < this->level; lvl++) {
1422  if (!HasBit(parent_last, lvl)) GfxDrawLine(x + offset, y, x + offset, y + SETTING_HEIGHT - 1, colour);
1423  x += level_width;
1424  }
1425  /* draw own |- prefix */
1426  int halfway_y = y + SETTING_HEIGHT / 2;
1427  int bottom_y = (flags & SEF_LAST_FIELD) ? halfway_y : y + SETTING_HEIGHT - 1;
1428  GfxDrawLine(x + offset, y, x + offset, bottom_y, colour);
1429  /* Small horizontal line from the last vertical line */
1430  GfxDrawLine(x + offset, halfway_y, x + level_width - (rtl ? -WidgetDimensions::scaled.hsep_normal : WidgetDimensions::scaled.hsep_normal), halfway_y, colour);
1431  x += level_width;
1432 
1433  this->DrawSetting(settings_ptr, rtl ? left : x, rtl ? x : right, y, this == selected);
1434  }
1435  cur_row++;
1436 
1437  return cur_row;
1438 }
1439 
1440 /* == SettingEntry methods == */
1441 
1447 {
1448  this->name = name;
1449  this->setting = nullptr;
1450 }
1451 
1456 void SettingEntry::Init(byte level)
1457 {
1459  this->setting = GetSettingFromName(this->name)->AsIntSetting();
1460 }
1461 
1462 /* Sets the given setting entry to its default value */
1463 void SettingEntry::ResetAll()
1464 {
1465  SetSettingValue(this->setting, this->setting->def);
1466 }
1467 
1473 void SettingEntry::SetButtons(byte new_val)
1474 {
1475  assert((new_val & ~SEF_BUTTONS_MASK) == 0); // Should not touch any flags outside the buttons
1476  this->flags = (this->flags & ~SEF_BUTTONS_MASK) | new_val;
1477 }
1478 
1481 {
1482  return this->IsFiltered() ? 0 : 1;
1483 }
1484 
1491 {
1492  return GetStringHeight(this->setting->GetHelp(), maxw);
1493 }
1494 
1501 {
1502  /* There shall not be any restriction, i.e. all settings shall be visible. */
1503  if (mode == RM_ALL) return true;
1504 
1505  const IntSettingDesc *sd = this->setting;
1506 
1507  if (mode == RM_BASIC) return (this->setting->cat & SC_BASIC_LIST) != 0;
1508  if (mode == RM_ADVANCED) return (this->setting->cat & SC_ADVANCED_LIST) != 0;
1509 
1510  /* Read the current value. */
1511  const void *object = ResolveObject(&GetGameSettings(), sd);
1512  int64_t current_value = sd->Read(object);
1513  int64_t filter_value;
1514 
1515  if (mode == RM_CHANGED_AGAINST_DEFAULT) {
1516  /* This entry shall only be visible, if the value deviates from its default value. */
1517 
1518  /* Read the default value. */
1519  filter_value = sd->def;
1520  } else {
1521  assert(mode == RM_CHANGED_AGAINST_NEW);
1522  /* This entry shall only be visible, if the value deviates from
1523  * its value is used when starting a new game. */
1524 
1525  /* Make sure we're not comparing the new game settings against itself. */
1526  assert(&GetGameSettings() != &_settings_newgame);
1527 
1528  /* Read the new game's value. */
1529  filter_value = sd->Read(ResolveObject(&_settings_newgame, sd));
1530  }
1531 
1532  return current_value != filter_value;
1533 }
1534 
1541 bool SettingEntry::UpdateFilterState(SettingFilter &filter, bool force_visible)
1542 {
1543  CLRBITS(this->flags, SEF_FILTERED);
1544 
1545  bool visible = true;
1546 
1547  const IntSettingDesc *sd = this->setting;
1548  if (!force_visible && !filter.string.IsEmpty()) {
1549  /* Process the search text filter for this item. */
1550  filter.string.ResetState();
1551 
1552  SetDParam(0, STR_EMPTY);
1553  filter.string.AddLine(sd->GetTitle());
1554  filter.string.AddLine(sd->GetHelp());
1555 
1556  visible = filter.string.GetState();
1557  }
1558 
1559  if (visible) {
1560  if (filter.type != ST_ALL && sd->GetType() != filter.type) {
1561  filter.type_hides = true;
1562  visible = false;
1563  }
1564  if (!this->IsVisibleByRestrictionMode(filter.mode)) {
1565  while (filter.min_cat < RM_ALL && (filter.min_cat == filter.mode || !this->IsVisibleByRestrictionMode(filter.min_cat))) filter.min_cat++;
1566  visible = false;
1567  }
1568  }
1569 
1570  if (!visible) SETBITS(this->flags, SEF_FILTERED);
1571  return visible;
1572 }
1573 
1574 static const void *ResolveObject(const GameSettings *settings_ptr, const IntSettingDesc *sd)
1575 {
1576  if ((sd->flags & SF_PER_COMPANY) != 0) {
1577  if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) {
1578  return &Company::Get(_local_company)->settings;
1579  }
1580  return &_settings_client.company;
1581  }
1582  return settings_ptr;
1583 }
1584 
1593 void SettingEntry::DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const
1594 {
1595  const IntSettingDesc *sd = this->setting;
1596  int state = this->flags & SEF_BUTTONS_MASK;
1597 
1598  bool rtl = _current_text_dir == TD_RTL;
1599  uint buttons_left = rtl ? right + 1 - SETTING_BUTTON_WIDTH : left;
1600  uint text_left = left + (rtl ? 0 : SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide);
1601  uint text_right = right - (rtl ? SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide : 0);
1602  uint button_y = y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2;
1603 
1604  /* We do not allow changes of some items when we are a client in a networkgame */
1605  bool editable = sd->IsEditable();
1606 
1607  SetDParam(0, STR_CONFIG_SETTING_VALUE);
1608  int32_t value = sd->Read(ResolveObject(settings_ptr, sd));
1609  if (sd->IsBoolSetting()) {
1610  /* Draw checkbox for boolean-value either on/off */
1611  DrawBoolButton(buttons_left, button_y, value != 0, editable);
1612  } else if ((sd->flags & SF_GUI_DROPDOWN) != 0) {
1613  /* Draw [v] button for settings of an enum-type */
1614  DrawDropDownButton(buttons_left, button_y, COLOUR_YELLOW, state != 0, editable);
1615  } else {
1616  /* Draw [<][>] boxes for settings of an integer-type */
1617  DrawArrowButtons(buttons_left, button_y, COLOUR_YELLOW, state,
1618  editable && value != (sd->flags & SF_GUI_0_IS_SPECIAL ? 0 : sd->min), editable && (uint32_t)value != sd->max);
1619  }
1620  sd->SetValueDParams(1, value);
1621  DrawString(text_left, text_right, y + (SETTING_HEIGHT - GetCharacterHeight(FS_NORMAL)) / 2, sd->GetTitle(), highlight ? TC_WHITE : TC_LIGHT_BLUE);
1622 }
1623 
1624 /* == SettingsContainer methods == */
1625 
1630 void SettingsContainer::Init(byte level)
1631 {
1632  for (auto &it : this->entries) {
1633  it->Init(level);
1634  }
1635 }
1636 
1639 {
1640  for (auto settings_entry : this->entries) {
1641  settings_entry->ResetAll();
1642  }
1643 }
1644 
1647 {
1648  for (auto &it : this->entries) {
1649  it->FoldAll();
1650  }
1651 }
1652 
1655 {
1656  for (auto &it : this->entries) {
1657  it->UnFoldAll();
1658  }
1659 }
1660 
1666 void SettingsContainer::GetFoldingState(bool &all_folded, bool &all_unfolded) const
1667 {
1668  for (auto &it : this->entries) {
1669  it->GetFoldingState(all_folded, all_unfolded);
1670  }
1671 }
1672 
1679 bool SettingsContainer::UpdateFilterState(SettingFilter &filter, bool force_visible)
1680 {
1681  bool visible = false;
1682  bool first_visible = true;
1683  for (EntryVector::reverse_iterator it = this->entries.rbegin(); it != this->entries.rend(); ++it) {
1684  visible |= (*it)->UpdateFilterState(filter, force_visible);
1685  (*it)->SetLastField(first_visible);
1686  if (visible && first_visible) first_visible = false;
1687  }
1688  return visible;
1689 }
1690 
1691 
1699 {
1700  for (const auto &it : this->entries) {
1701  if (it->IsVisible(item)) return true;
1702  }
1703  return false;
1704 }
1705 
1708 {
1709  uint length = 0;
1710  for (const auto &it : this->entries) {
1711  length += it->Length();
1712  }
1713  return length;
1714 }
1715 
1722 BaseSettingEntry *SettingsContainer::FindEntry(uint row_num, uint *cur_row)
1723 {
1724  BaseSettingEntry *pe = nullptr;
1725  for (const auto &it : this->entries) {
1726  pe = it->FindEntry(row_num, cur_row);
1727  if (pe != nullptr) {
1728  break;
1729  }
1730  }
1731  return pe;
1732 }
1733 
1740 {
1741  uint biggest = 0;
1742  for (const auto &it : this->entries) {
1743  biggest = std::max(biggest, it->GetMaxHelpHeight(maxw));
1744  }
1745  return biggest;
1746 }
1747 
1748 
1763 uint SettingsContainer::Draw(GameSettings *settings_ptr, int left, int right, int y, uint first_row, uint max_row, BaseSettingEntry *selected, uint cur_row, uint parent_last) const
1764 {
1765  for (const auto &it : this->entries) {
1766  cur_row = it->Draw(settings_ptr, left, right, y, first_row, max_row, selected, cur_row, parent_last);
1767  if (cur_row >= max_row) break;
1768  }
1769  return cur_row;
1770 }
1771 
1772 /* == SettingsPage methods == */
1773 
1779 {
1780  this->title = title;
1781  this->folded = true;
1782 }
1783 
1788 void SettingsPage::Init(byte level)
1789 {
1792 }
1793 
1796 {
1797  for (auto settings_entry : this->entries) {
1798  settings_entry->ResetAll();
1799  }
1800 }
1801 
1804 {
1805  if (this->IsFiltered()) return;
1806  this->folded = true;
1807 
1809 }
1810 
1813 {
1814  if (this->IsFiltered()) return;
1815  this->folded = false;
1816 
1818 }
1819 
1825 void SettingsPage::GetFoldingState(bool &all_folded, bool &all_unfolded) const
1826 {
1827  if (this->IsFiltered()) return;
1828 
1829  if (this->folded) {
1830  all_unfolded = false;
1831  } else {
1832  all_folded = false;
1833  }
1834 
1835  SettingsContainer::GetFoldingState(all_folded, all_unfolded);
1836 }
1837 
1844 bool SettingsPage::UpdateFilterState(SettingFilter &filter, bool force_visible)
1845 {
1846  if (!force_visible && !filter.string.IsEmpty()) {
1847  filter.string.ResetState();
1848  filter.string.AddLine(this->title);
1849  force_visible = filter.string.GetState();
1850  }
1851 
1852  bool visible = SettingsContainer::UpdateFilterState(filter, force_visible);
1853  if (visible) {
1854  CLRBITS(this->flags, SEF_FILTERED);
1855  } else {
1856  SETBITS(this->flags, SEF_FILTERED);
1857  }
1858  return visible;
1859 }
1860 
1868 {
1869  if (this->IsFiltered()) return false;
1870  if (this == item) return true;
1871  if (this->folded) return false;
1872 
1873  return SettingsContainer::IsVisible(item);
1874 }
1875 
1878 {
1879  if (this->IsFiltered()) return 0;
1880  if (this->folded) return 1; // Only displaying the title
1881 
1882  return 1 + SettingsContainer::Length();
1883 }
1884 
1891 BaseSettingEntry *SettingsPage::FindEntry(uint row_num, uint *cur_row)
1892 {
1893  if (this->IsFiltered()) return nullptr;
1894  if (row_num == *cur_row) return this;
1895  (*cur_row)++;
1896  if (this->folded) return nullptr;
1897 
1898  return SettingsContainer::FindEntry(row_num, cur_row);
1899 }
1900 
1915 uint SettingsPage::Draw(GameSettings *settings_ptr, int left, int right, int y, uint first_row, uint max_row, BaseSettingEntry *selected, uint cur_row, uint parent_last) const
1916 {
1917  if (this->IsFiltered()) return cur_row;
1918  if (cur_row >= max_row) return cur_row;
1919 
1920  cur_row = BaseSettingEntry::Draw(settings_ptr, left, right, y, first_row, max_row, selected, cur_row, parent_last);
1921 
1922  if (!this->folded) {
1923  if (this->flags & SEF_LAST_FIELD) {
1924  assert(this->level < 8 * sizeof(parent_last));
1925  SetBit(parent_last, this->level); // Add own last-field state
1926  }
1927 
1928  cur_row = SettingsContainer::Draw(settings_ptr, left, right, y, first_row, max_row, selected, cur_row, parent_last);
1929  }
1930 
1931  return cur_row;
1932 }
1933 
1940 void SettingsPage::DrawSetting(GameSettings *, int left, int right, int y, bool) const
1941 {
1942  bool rtl = _current_text_dir == TD_RTL;
1943  DrawSprite((this->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED), PAL_NONE, rtl ? right - _circle_size.width : left, y + (SETTING_HEIGHT - _circle_size.height) / 2);
1944  DrawString(rtl ? left : left + _circle_size.width + WidgetDimensions::scaled.hsep_normal, rtl ? right - _circle_size.width - WidgetDimensions::scaled.hsep_normal : right, y + (SETTING_HEIGHT - GetCharacterHeight(FS_NORMAL)) / 2, this->title, TC_ORANGE);
1945 }
1946 
1949 {
1950  static SettingsContainer *main = nullptr;
1951 
1952  if (main == nullptr)
1953  {
1954  /* Build up the dynamic settings-array only once per OpenTTD session */
1955  main = new SettingsContainer();
1956 
1957  SettingsPage *localisation = main->Add(new SettingsPage(STR_CONFIG_SETTING_LOCALISATION));
1958  {
1959  localisation->Add(new SettingEntry("locale.units_velocity"));
1960  localisation->Add(new SettingEntry("locale.units_velocity_nautical"));
1961  localisation->Add(new SettingEntry("locale.units_power"));
1962  localisation->Add(new SettingEntry("locale.units_weight"));
1963  localisation->Add(new SettingEntry("locale.units_volume"));
1964  localisation->Add(new SettingEntry("locale.units_force"));
1965  localisation->Add(new SettingEntry("locale.units_height"));
1966  localisation->Add(new SettingEntry("gui.date_format_in_default_names"));
1967  }
1968 
1969  SettingsPage *graphics = main->Add(new SettingsPage(STR_CONFIG_SETTING_GRAPHICS));
1970  {
1971  graphics->Add(new SettingEntry("gui.zoom_min"));
1972  graphics->Add(new SettingEntry("gui.zoom_max"));
1973  graphics->Add(new SettingEntry("gui.sprite_zoom_min"));
1974  graphics->Add(new SettingEntry("gui.smallmap_land_colour"));
1975  graphics->Add(new SettingEntry("gui.linkgraph_colours"));
1976  graphics->Add(new SettingEntry("gui.graph_line_thickness"));
1977  }
1978 
1979  SettingsPage *sound = main->Add(new SettingsPage(STR_CONFIG_SETTING_SOUND));
1980  {
1981  sound->Add(new SettingEntry("sound.click_beep"));
1982  sound->Add(new SettingEntry("sound.confirm"));
1983  sound->Add(new SettingEntry("sound.news_ticker"));
1984  sound->Add(new SettingEntry("sound.news_full"));
1985  sound->Add(new SettingEntry("sound.new_year"));
1986  sound->Add(new SettingEntry("sound.disaster"));
1987  sound->Add(new SettingEntry("sound.vehicle"));
1988  sound->Add(new SettingEntry("sound.ambient"));
1989  }
1990 
1991  SettingsPage *interface = main->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE));
1992  {
1993  SettingsPage *general = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_GENERAL));
1994  {
1995  general->Add(new SettingEntry("gui.osk_activation"));
1996  general->Add(new SettingEntry("gui.hover_delay_ms"));
1997  general->Add(new SettingEntry("gui.errmsg_duration"));
1998  general->Add(new SettingEntry("gui.window_snap_radius"));
1999  general->Add(new SettingEntry("gui.window_soft_limit"));
2000  general->Add(new SettingEntry("gui.right_click_wnd_close"));
2001  }
2002 
2003  SettingsPage *viewports = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_VIEWPORTS));
2004  {
2005  viewports->Add(new SettingEntry("gui.auto_scrolling"));
2006  viewports->Add(new SettingEntry("gui.scroll_mode"));
2007  viewports->Add(new SettingEntry("gui.smooth_scroll"));
2008  /* While the horizontal scrollwheel scrolling is written as general code, only
2009  * the cocoa (OSX) driver generates input for it.
2010  * Since it's also able to completely disable the scrollwheel will we display it on all platforms anyway */
2011  viewports->Add(new SettingEntry("gui.scrollwheel_scrolling"));
2012  viewports->Add(new SettingEntry("gui.scrollwheel_multiplier"));
2013 #ifdef __APPLE__
2014  /* We might need to emulate a right mouse button on mac */
2015  viewports->Add(new SettingEntry("gui.right_mouse_btn_emulation"));
2016 #endif
2017  viewports->Add(new SettingEntry("gui.population_in_label"));
2018  viewports->Add(new SettingEntry("gui.liveries"));
2019  viewports->Add(new SettingEntry("construction.train_signal_side"));
2020  viewports->Add(new SettingEntry("gui.measure_tooltip"));
2021  viewports->Add(new SettingEntry("gui.loading_indicators"));
2022  viewports->Add(new SettingEntry("gui.show_track_reservation"));
2023  }
2024 
2025  SettingsPage *construction = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION));
2026  {
2027  construction->Add(new SettingEntry("gui.link_terraform_toolbar"));
2028  construction->Add(new SettingEntry("gui.persistent_buildingtools"));
2029  construction->Add(new SettingEntry("gui.default_rail_type"));
2030  construction->Add(new SettingEntry("gui.semaphore_build_before"));
2031  construction->Add(new SettingEntry("gui.signal_gui_mode"));
2032  construction->Add(new SettingEntry("gui.cycle_signal_types"));
2033  construction->Add(new SettingEntry("gui.drag_signals_fixed_distance"));
2034  construction->Add(new SettingEntry("gui.auto_remove_signals"));
2035  }
2036 
2037  interface->Add(new SettingEntry("gui.toolbar_pos"));
2038  interface->Add(new SettingEntry("gui.statusbar_pos"));
2039  interface->Add(new SettingEntry("gui.prefer_teamchat"));
2040  interface->Add(new SettingEntry("gui.advanced_vehicle_list"));
2041  interface->Add(new SettingEntry("gui.timetable_mode"));
2042  interface->Add(new SettingEntry("gui.timetable_arrival_departure"));
2043  interface->Add(new SettingEntry("gui.show_newgrf_name"));
2044  interface->Add(new SettingEntry("gui.show_cargo_in_vehicle_lists"));
2045  }
2046 
2047  SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS));
2048  {
2049  advisors->Add(new SettingEntry("gui.coloured_news_year"));
2050  advisors->Add(new SettingEntry("news_display.general"));
2051  advisors->Add(new SettingEntry("news_display.new_vehicles"));
2052  advisors->Add(new SettingEntry("news_display.accident"));
2053  advisors->Add(new SettingEntry("news_display.accident_other"));
2054  advisors->Add(new SettingEntry("news_display.company_info"));
2055  advisors->Add(new SettingEntry("news_display.acceptance"));
2056  advisors->Add(new SettingEntry("news_display.arrival_player"));
2057  advisors->Add(new SettingEntry("news_display.arrival_other"));
2058  advisors->Add(new SettingEntry("news_display.advice"));
2059  advisors->Add(new SettingEntry("gui.order_review_system"));
2060  advisors->Add(new SettingEntry("gui.vehicle_income_warn"));
2061  advisors->Add(new SettingEntry("gui.lost_vehicle_warn"));
2062  advisors->Add(new SettingEntry("gui.show_finances"));
2063  advisors->Add(new SettingEntry("news_display.economy"));
2064  advisors->Add(new SettingEntry("news_display.subsidies"));
2065  advisors->Add(new SettingEntry("news_display.open"));
2066  advisors->Add(new SettingEntry("news_display.close"));
2067  advisors->Add(new SettingEntry("news_display.production_player"));
2068  advisors->Add(new SettingEntry("news_display.production_other"));
2069  advisors->Add(new SettingEntry("news_display.production_nobody"));
2070  }
2071 
2072  SettingsPage *company = main->Add(new SettingsPage(STR_CONFIG_SETTING_COMPANY));
2073  {
2074  company->Add(new SettingEntry("gui.starting_colour"));
2075  company->Add(new SettingEntry("gui.starting_colour_secondary"));
2076  company->Add(new SettingEntry("company.engine_renew"));
2077  company->Add(new SettingEntry("company.engine_renew_months"));
2078  company->Add(new SettingEntry("company.engine_renew_money"));
2079  company->Add(new SettingEntry("vehicle.servint_ispercent"));
2080  company->Add(new SettingEntry("vehicle.servint_trains"));
2081  company->Add(new SettingEntry("vehicle.servint_roadveh"));
2082  company->Add(new SettingEntry("vehicle.servint_ships"));
2083  company->Add(new SettingEntry("vehicle.servint_aircraft"));
2084  }
2085 
2086  SettingsPage *accounting = main->Add(new SettingsPage(STR_CONFIG_SETTING_ACCOUNTING));
2087  {
2088  accounting->Add(new SettingEntry("difficulty.infinite_money"));
2089  accounting->Add(new SettingEntry("economy.inflation"));
2090  accounting->Add(new SettingEntry("difficulty.initial_interest"));
2091  accounting->Add(new SettingEntry("difficulty.max_loan"));
2092  accounting->Add(new SettingEntry("difficulty.subsidy_multiplier"));
2093  accounting->Add(new SettingEntry("difficulty.subsidy_duration"));
2094  accounting->Add(new SettingEntry("economy.feeder_payment_share"));
2095  accounting->Add(new SettingEntry("economy.infrastructure_maintenance"));
2096  accounting->Add(new SettingEntry("difficulty.vehicle_costs"));
2097  accounting->Add(new SettingEntry("difficulty.construction_cost"));
2098  }
2099 
2100  SettingsPage *vehicles = main->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES));
2101  {
2102  SettingsPage *physics = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_PHYSICS));
2103  {
2104  physics->Add(new SettingEntry("vehicle.train_acceleration_model"));
2105  physics->Add(new SettingEntry("vehicle.train_slope_steepness"));
2106  physics->Add(new SettingEntry("vehicle.wagon_speed_limits"));
2107  physics->Add(new SettingEntry("vehicle.freight_trains"));
2108  physics->Add(new SettingEntry("vehicle.roadveh_acceleration_model"));
2109  physics->Add(new SettingEntry("vehicle.roadveh_slope_steepness"));
2110  physics->Add(new SettingEntry("vehicle.smoke_amount"));
2111  physics->Add(new SettingEntry("vehicle.plane_speed"));
2112  }
2113 
2114  SettingsPage *routing = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_ROUTING));
2115  {
2116  routing->Add(new SettingEntry("vehicle.road_side"));
2117  routing->Add(new SettingEntry("pf.pathfinder_for_trains"));
2118  routing->Add(new SettingEntry("difficulty.line_reverse_mode"));
2119  routing->Add(new SettingEntry("pf.reverse_at_signals"));
2120  routing->Add(new SettingEntry("pf.forbid_90_deg"));
2121  routing->Add(new SettingEntry("pf.pathfinder_for_roadvehs"));
2122  routing->Add(new SettingEntry("pf.pathfinder_for_ships"));
2123  }
2124 
2125  SettingsPage *orders = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_ORDERS));
2126  {
2127  orders->Add(new SettingEntry("gui.new_nonstop"));
2128  orders->Add(new SettingEntry("gui.quick_goto"));
2129  orders->Add(new SettingEntry("gui.stop_location"));
2130  }
2131  }
2132 
2133  SettingsPage *limitations = main->Add(new SettingsPage(STR_CONFIG_SETTING_LIMITATIONS));
2134  {
2135  limitations->Add(new SettingEntry("construction.command_pause_level"));
2136  limitations->Add(new SettingEntry("construction.autoslope"));
2137  limitations->Add(new SettingEntry("construction.extra_dynamite"));
2138  limitations->Add(new SettingEntry("construction.map_height_limit"));
2139  limitations->Add(new SettingEntry("construction.max_bridge_length"));
2140  limitations->Add(new SettingEntry("construction.max_bridge_height"));
2141  limitations->Add(new SettingEntry("construction.max_tunnel_length"));
2142  limitations->Add(new SettingEntry("station.never_expire_airports"));
2143  limitations->Add(new SettingEntry("vehicle.never_expire_vehicles"));
2144  limitations->Add(new SettingEntry("vehicle.max_trains"));
2145  limitations->Add(new SettingEntry("vehicle.max_roadveh"));
2146  limitations->Add(new SettingEntry("vehicle.max_aircraft"));
2147  limitations->Add(new SettingEntry("vehicle.max_ships"));
2148  limitations->Add(new SettingEntry("vehicle.max_train_length"));
2149  limitations->Add(new SettingEntry("station.station_spread"));
2150  limitations->Add(new SettingEntry("station.distant_join_stations"));
2151  limitations->Add(new SettingEntry("station.modified_catchment"));
2152  limitations->Add(new SettingEntry("construction.road_stop_on_town_road"));
2153  limitations->Add(new SettingEntry("construction.road_stop_on_competitor_road"));
2154  limitations->Add(new SettingEntry("construction.crossing_with_competitor"));
2155  limitations->Add(new SettingEntry("vehicle.disable_elrails"));
2156  limitations->Add(new SettingEntry("order.station_length_loading_penalty"));
2157  }
2158 
2159  SettingsPage *disasters = main->Add(new SettingsPage(STR_CONFIG_SETTING_ACCIDENTS));
2160  {
2161  disasters->Add(new SettingEntry("difficulty.disasters"));
2162  disasters->Add(new SettingEntry("difficulty.economy"));
2163  disasters->Add(new SettingEntry("vehicle.plane_crashes"));
2164  disasters->Add(new SettingEntry("difficulty.vehicle_breakdowns"));
2165  disasters->Add(new SettingEntry("order.no_servicing_if_no_breakdowns"));
2166  disasters->Add(new SettingEntry("order.serviceathelipad"));
2167  }
2168 
2169  SettingsPage *genworld = main->Add(new SettingsPage(STR_CONFIG_SETTING_GENWORLD));
2170  {
2171  genworld->Add(new SettingEntry("game_creation.landscape"));
2172  genworld->Add(new SettingEntry("game_creation.land_generator"));
2173  genworld->Add(new SettingEntry("difficulty.terrain_type"));
2174  genworld->Add(new SettingEntry("game_creation.tgen_smoothness"));
2175  genworld->Add(new SettingEntry("game_creation.variety"));
2176  genworld->Add(new SettingEntry("game_creation.snow_coverage"));
2177  genworld->Add(new SettingEntry("game_creation.snow_line_height"));
2178  genworld->Add(new SettingEntry("game_creation.desert_coverage"));
2179  genworld->Add(new SettingEntry("game_creation.amount_of_rivers"));
2180  }
2181 
2182  SettingsPage *environment = main->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT));
2183  {
2184  SettingsPage *time = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TIME));
2185  {
2186  time->Add(new SettingEntry("economy.timekeeping_units"));
2187  time->Add(new SettingEntry("economy.minutes_per_calendar_year"));
2188  time->Add(new SettingEntry("game_creation.ending_year"));
2189  time->Add(new SettingEntry("gui.pause_on_newgame"));
2190  time->Add(new SettingEntry("gui.fast_forward_speed_limit"));
2191  }
2192 
2193  SettingsPage *authorities = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES));
2194  {
2195  authorities->Add(new SettingEntry("difficulty.town_council_tolerance"));
2196  authorities->Add(new SettingEntry("economy.bribe"));
2197  authorities->Add(new SettingEntry("economy.exclusive_rights"));
2198  authorities->Add(new SettingEntry("economy.fund_roads"));
2199  authorities->Add(new SettingEntry("economy.fund_buildings"));
2200  authorities->Add(new SettingEntry("economy.station_noise_level"));
2201  }
2202 
2203  SettingsPage *towns = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TOWNS));
2204  {
2205  towns->Add(new SettingEntry("economy.town_cargo_scale"));
2206  towns->Add(new SettingEntry("economy.town_growth_rate"));
2207  towns->Add(new SettingEntry("economy.allow_town_roads"));
2208  towns->Add(new SettingEntry("economy.allow_town_level_crossings"));
2209  towns->Add(new SettingEntry("economy.found_town"));
2210  towns->Add(new SettingEntry("economy.town_layout"));
2211  towns->Add(new SettingEntry("economy.larger_towns"));
2212  towns->Add(new SettingEntry("economy.initial_city_size"));
2213  towns->Add(new SettingEntry("economy.town_cargogen_mode"));
2214  }
2215 
2216  SettingsPage *industries = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES));
2217  {
2218  industries->Add(new SettingEntry("economy.industry_cargo_scale"));
2219  industries->Add(new SettingEntry("difficulty.industry_density"));
2220  industries->Add(new SettingEntry("construction.raw_industry_construction"));
2221  industries->Add(new SettingEntry("construction.industry_platform"));
2222  industries->Add(new SettingEntry("economy.multiple_industry_per_town"));
2223  industries->Add(new SettingEntry("game_creation.oil_refinery_limit"));
2224  industries->Add(new SettingEntry("economy.type"));
2225  industries->Add(new SettingEntry("station.serve_neutral_industries"));
2226  }
2227 
2228  SettingsPage *cdist = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST));
2229  {
2230  cdist->Add(new SettingEntry("linkgraph.recalc_time"));
2231  cdist->Add(new SettingEntry("linkgraph.recalc_interval"));
2232  cdist->Add(new SettingEntry("linkgraph.distribution_pax"));
2233  cdist->Add(new SettingEntry("linkgraph.distribution_mail"));
2234  cdist->Add(new SettingEntry("linkgraph.distribution_armoured"));
2235  cdist->Add(new SettingEntry("linkgraph.distribution_default"));
2236  cdist->Add(new SettingEntry("linkgraph.accuracy"));
2237  cdist->Add(new SettingEntry("linkgraph.demand_distance"));
2238  cdist->Add(new SettingEntry("linkgraph.demand_size"));
2239  cdist->Add(new SettingEntry("linkgraph.short_path_saturation"));
2240  }
2241 
2242  SettingsPage *trees = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TREES));
2243  {
2244  trees->Add(new SettingEntry("game_creation.tree_placer"));
2245  trees->Add(new SettingEntry("construction.extra_tree_placement"));
2246  }
2247  }
2248 
2249  SettingsPage *ai = main->Add(new SettingsPage(STR_CONFIG_SETTING_AI));
2250  {
2251  SettingsPage *npc = ai->Add(new SettingsPage(STR_CONFIG_SETTING_AI_NPC));
2252  {
2253  npc->Add(new SettingEntry("script.script_max_opcode_till_suspend"));
2254  npc->Add(new SettingEntry("script.script_max_memory_megabytes"));
2255  npc->Add(new SettingEntry("difficulty.competitor_speed"));
2256  npc->Add(new SettingEntry("ai.ai_in_multiplayer"));
2257  npc->Add(new SettingEntry("ai.ai_disable_veh_train"));
2258  npc->Add(new SettingEntry("ai.ai_disable_veh_roadveh"));
2259  npc->Add(new SettingEntry("ai.ai_disable_veh_aircraft"));
2260  npc->Add(new SettingEntry("ai.ai_disable_veh_ship"));
2261  }
2262 
2263  ai->Add(new SettingEntry("economy.give_money"));
2264  }
2265 
2266  SettingsPage *network = main->Add(new SettingsPage(STR_CONFIG_SETTING_NETWORK));
2267  {
2268  network->Add(new SettingEntry("network.use_relay_service"));
2269  }
2270 
2271  main->Init();
2272  }
2273  return *main;
2274 }
2275 
2276 static const StringID _game_settings_restrict_dropdown[] = {
2277  STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC
2278  STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED
2279  STR_CONFIG_SETTING_RESTRICT_ALL, // RM_ALL
2280  STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT, // RM_CHANGED_AGAINST_DEFAULT
2281  STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW, // RM_CHANGED_AGAINST_NEW
2282 };
2283 static_assert(lengthof(_game_settings_restrict_dropdown) == RM_END);
2284 
2291 };
2292 
2298 static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
2299 {
2300  if (confirmed) {
2303  w->InvalidateData();
2304  }
2305 }
2306 
2310 
2316 
2322 
2323  Scrollbar *vscroll;
2324 
2326  {
2327  this->warn_missing = WHR_NONE;
2328  this->warn_lines = 0;
2330  this->filter.min_cat = RM_ALL;
2331  this->filter.type = ST_ALL;
2332  this->filter.type_hides = false;
2333  this->settings_ptr = &GetGameSettings();
2334 
2335  GetSettingsTree().FoldAll(); // Close all sub-pages
2336 
2337  this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened
2338  this->clicked_entry = nullptr; // No numeric setting buttons are depressed
2339  this->last_clicked = nullptr;
2340  this->valuedropdown_entry = nullptr;
2341  this->closing_dropdown = false;
2342  this->manually_changed_folding = false;
2343 
2344  this->CreateNestedTree();
2345  this->vscroll = this->GetScrollbar(WID_GS_SCROLLBAR);
2347 
2348  this->querystrings[WID_GS_FILTER] = &this->filter_editbox;
2349  this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
2351 
2352  this->InvalidateData();
2353  }
2354 
2355  void OnInit() override
2356  {
2357  _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED));
2358  }
2359 
2360  void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
2361  {
2362  switch (widget) {
2363  case WID_GS_OPTIONSPANEL:
2365  resize->width = 1;
2366 
2367  size->height = 5 * resize->height + WidgetDimensions::scaled.framerect.Vertical();
2368  break;
2369 
2370  case WID_GS_HELP_TEXT: {
2371  static const StringID setting_types[] = {
2372  STR_CONFIG_SETTING_TYPE_CLIENT,
2373  STR_CONFIG_SETTING_TYPE_COMPANY_MENU, STR_CONFIG_SETTING_TYPE_COMPANY_INGAME,
2374  STR_CONFIG_SETTING_TYPE_GAME_MENU, STR_CONFIG_SETTING_TYPE_GAME_INGAME,
2375  };
2376  for (uint i = 0; i < lengthof(setting_types); i++) {
2377  SetDParam(0, setting_types[i]);
2378  size->width = std::max(size->width, GetStringBoundingBox(STR_CONFIG_SETTING_TYPE).width + padding.width);
2379  }
2381  std::max(size->height, GetSettingsTree().GetMaxHelpHeight(size->width));
2382  break;
2383  }
2384 
2386  case WID_GS_RESTRICT_TYPE:
2387  size->width = std::max(GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_CATEGORY).width, GetStringBoundingBox(STR_CONFIG_SETTING_RESTRICT_TYPE).width);
2388  break;
2389 
2390  default:
2391  break;
2392  }
2393  }
2394 
2395  void OnPaint() override
2396  {
2397  if (this->closing_dropdown) {
2398  this->closing_dropdown = false;
2399  assert(this->valuedropdown_entry != nullptr);
2400  this->valuedropdown_entry->SetButtons(0);
2401  this->valuedropdown_entry = nullptr;
2402  }
2403 
2404  /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */
2405  const Rect panel = this->GetWidget<NWidgetBase>(WID_GS_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext);
2406  StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing;
2407  int new_warn_lines;
2408  if (this->warn_missing == WHR_NONE) {
2409  new_warn_lines = 0;
2410  } else {
2411  SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]);
2412  new_warn_lines = GetStringLineCount(warn_str, panel.Width());
2413  }
2414  if (this->warn_lines != new_warn_lines) {
2415  this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines);
2416  this->warn_lines = new_warn_lines;
2417  }
2418 
2419  this->DrawWidgets();
2420 
2421  /* Draw the 'some search results are hidden' notice. */
2422  if (this->warn_missing != WHR_NONE) {
2423  SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]);
2424  DrawStringMultiLine(panel.WithHeight(this->warn_lines * GetCharacterHeight(FS_NORMAL)), warn_str, TC_FROMSTRING, SA_CENTER);
2425  }
2426  }
2427 
2428  void SetStringParameters(WidgetID widget) const override
2429  {
2430  switch (widget) {
2432  SetDParam(0, _game_settings_restrict_dropdown[this->filter.mode]);
2433  break;
2434 
2435  case WID_GS_TYPE_DROPDOWN:
2436  switch (this->filter.type) {
2437  case ST_GAME: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME); break;
2438  case ST_COMPANY: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME); break;
2439  case ST_CLIENT: SetDParam(0, STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT); break;
2440  default: SetDParam(0, STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL); break;
2441  }
2442  break;
2443  }
2444  }
2445 
2446  DropDownList BuildDropDownList(WidgetID widget) const
2447  {
2448  DropDownList list;
2449  switch (widget) {
2451  for (int mode = 0; mode != RM_END; mode++) {
2452  /* If we are in adv. settings screen for the new game's settings,
2453  * we don't want to allow comparing with new game's settings. */
2454  bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame;
2455 
2456  list.push_back(std::make_unique<DropDownListStringItem>(_game_settings_restrict_dropdown[mode], mode, disabled));
2457  }
2458  break;
2459 
2460  case WID_GS_TYPE_DROPDOWN:
2461  list.push_back(std::make_unique<DropDownListStringItem>(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false));
2462  list.push_back(std::make_unique<DropDownListStringItem>(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false));
2463  list.push_back(std::make_unique<DropDownListStringItem>(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false));
2464  list.push_back(std::make_unique<DropDownListStringItem>(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false));
2465  break;
2466  }
2467  return list;
2468  }
2469 
2470  void DrawWidget(const Rect &r, WidgetID widget) const override
2471  {
2472  switch (widget) {
2473  case WID_GS_OPTIONSPANEL: {
2474  Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
2475  tr.top += this->warn_lines * SETTING_HEIGHT;
2476  uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines;
2477  int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top,
2478  this->vscroll->GetPosition(), last_row, this->last_clicked);
2479  if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE);
2480  break;
2481  }
2482 
2483  case WID_GS_HELP_TEXT:
2484  if (this->last_clicked != nullptr) {
2485  const IntSettingDesc *sd = this->last_clicked->setting;
2486 
2487  Rect tr = r;
2488  switch (sd->GetType()) {
2489  case ST_COMPANY: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME); break;
2490  case ST_CLIENT: SetDParam(0, STR_CONFIG_SETTING_TYPE_CLIENT); break;
2491  case ST_GAME: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME); break;
2492  default: NOT_REACHED();
2493  }
2494  DrawString(tr, STR_CONFIG_SETTING_TYPE);
2495  tr.top += GetCharacterHeight(FS_NORMAL);
2496 
2497  sd->SetValueDParams(0, sd->def);
2498  DrawString(tr, STR_CONFIG_SETTING_DEFAULT_VALUE);
2500 
2501  DrawStringMultiLine(tr, sd->GetHelp(), TC_WHITE);
2502  }
2503  break;
2504 
2505  default:
2506  break;
2507  }
2508  }
2509 
2515  {
2516  if (this->last_clicked != pe) this->SetDirty();
2517  this->last_clicked = pe;
2518  }
2519 
2520  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
2521  {
2522  switch (widget) {
2523  case WID_GS_EXPAND_ALL:
2524  this->manually_changed_folding = true;
2526  this->InvalidateData();
2527  break;
2528 
2529  case WID_GS_COLLAPSE_ALL:
2530  this->manually_changed_folding = true;
2532  this->InvalidateData();
2533  break;
2534 
2535  case WID_GS_RESET_ALL:
2536  ShowQuery(
2537  STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION,
2538  STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT,
2539  this,
2541  );
2542  break;
2543 
2544  case WID_GS_RESTRICT_DROPDOWN: {
2545  DropDownList list = this->BuildDropDownList(widget);
2546  if (!list.empty()) {
2547  ShowDropDownList(this, std::move(list), this->filter.mode, widget);
2548  }
2549  break;
2550  }
2551 
2552  case WID_GS_TYPE_DROPDOWN: {
2553  DropDownList list = this->BuildDropDownList(widget);
2554  if (!list.empty()) {
2555  ShowDropDownList(this, std::move(list), this->filter.type, widget);
2556  }
2557  break;
2558  }
2559  }
2560 
2561  if (widget != WID_GS_OPTIONSPANEL) return;
2562 
2563  uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.top);
2564  if (btn == INT_MAX || (int)btn < this->warn_lines) return;
2565  btn -= this->warn_lines;
2566 
2567  uint cur_row = 0;
2569 
2570  if (clicked_entry == nullptr) return; // Clicked below the last setting of the page
2571 
2572  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
2573  if (x < 0) return; // Clicked left of the entry
2574 
2575  SettingsPage *clicked_page = dynamic_cast<SettingsPage*>(clicked_entry);
2576  if (clicked_page != nullptr) {
2577  this->SetDisplayedHelpText(nullptr);
2578  clicked_page->folded = !clicked_page->folded; // Flip 'folded'-ness of the sub-page
2579 
2580  this->manually_changed_folding = true;
2581 
2582  this->InvalidateData();
2583  return;
2584  }
2585 
2586  SettingEntry *pe = dynamic_cast<SettingEntry*>(clicked_entry);
2587  assert(pe != nullptr);
2588  const IntSettingDesc *sd = pe->setting;
2589 
2590  /* return if action is only active in network, or only settable by server */
2591  if (!sd->IsEditable()) {
2592  this->SetDisplayedHelpText(pe);
2593  return;
2594  }
2595 
2596  int32_t value = sd->Read(ResolveObject(settings_ptr, sd));
2597 
2598  /* clicked on the icon on the left side. Either scroller, bool on/off or dropdown */
2599  if (x < SETTING_BUTTON_WIDTH && (sd->flags & SF_GUI_DROPDOWN)) {
2600  this->SetDisplayedHelpText(pe);
2601 
2602  if (this->valuedropdown_entry == pe) {
2603  /* unclick the dropdown */
2605  this->closing_dropdown = false;
2606  this->valuedropdown_entry->SetButtons(0);
2607  this->valuedropdown_entry = nullptr;
2608  } else {
2609  if (this->valuedropdown_entry != nullptr) this->valuedropdown_entry->SetButtons(0);
2610  this->closing_dropdown = false;
2611 
2612  const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_GS_OPTIONSPANEL);
2613  int rel_y = (pt.y - wid->pos_y - WidgetDimensions::scaled.framerect.top) % wid->resize_y;
2614 
2615  Rect wi_rect;
2616  wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
2617  wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
2618  wi_rect.top = pt.y - rel_y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2;
2619  wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
2620 
2621  /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
2622  if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
2623  this->valuedropdown_entry = pe;
2624  this->valuedropdown_entry->SetButtons(SEF_LEFT_DEPRESSED);
2625 
2626  DropDownList list;
2627  for (int i = sd->min; i <= (int)sd->max; i++) {
2628  sd->SetValueDParams(0, i);
2629  list.push_back(std::make_unique<DropDownListStringItem>(STR_JUST_STRING2, i, false));
2630  }
2631 
2632  ShowDropDownListAt(this, std::move(list), value, WID_GS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);
2633  }
2634  }
2635  this->SetDirty();
2636  } else if (x < SETTING_BUTTON_WIDTH) {
2637  this->SetDisplayedHelpText(pe);
2638  int32_t oldvalue = value;
2639 
2640  if (sd->IsBoolSetting()) {
2641  value ^= 1;
2642  } else {
2643  /* Add a dynamic step-size to the scroller. In a maximum of
2644  * 50-steps you should be able to get from min to max,
2645  * unless specified otherwise in the 'interval' variable
2646  * of the current setting. */
2647  uint32_t step = (sd->interval == 0) ? ((sd->max - sd->min) / 50) : sd->interval;
2648  if (step == 0) step = 1;
2649 
2650  /* don't allow too fast scrolling */
2651  if ((this->flags & WF_TIMEOUT) && this->timeout_timer > 1) {
2652  _left_button_clicked = false;
2653  return;
2654  }
2655 
2656  /* Increase or decrease the value and clamp it to extremes */
2657  if (x >= SETTING_BUTTON_WIDTH / 2) {
2658  value += step;
2659  if (sd->min < 0) {
2660  assert((int32_t)sd->max >= 0);
2661  if (value > (int32_t)sd->max) value = (int32_t)sd->max;
2662  } else {
2663  if ((uint32_t)value > sd->max) value = (int32_t)sd->max;
2664  }
2665  if (value < sd->min) value = sd->min; // skip between "disabled" and minimum
2666  } else {
2667  value -= step;
2668  if (value < sd->min) value = (sd->flags & SF_GUI_0_IS_SPECIAL) ? 0 : sd->min;
2669  }
2670 
2671  /* Set up scroller timeout for numeric values */
2672  if (value != oldvalue) {
2673  if (this->clicked_entry != nullptr) { // Release previous buttons if any
2674  this->clicked_entry->SetButtons(0);
2675  }
2676  this->clicked_entry = pe;
2677  this->clicked_entry->SetButtons((x >= SETTING_BUTTON_WIDTH / 2) != (_current_text_dir == TD_RTL) ? SEF_RIGHT_DEPRESSED : SEF_LEFT_DEPRESSED);
2678  this->SetTimeout();
2679  _left_button_clicked = false;
2680  }
2681  }
2682 
2683  if (value != oldvalue) {
2684  SetSettingValue(sd, value);
2685  this->SetDirty();
2686  }
2687  } else {
2688  /* Only open editbox if clicked for the second time, and only for types where it is sensible for. */
2689  if (this->last_clicked == pe && !sd->IsBoolSetting() && !(sd->flags & SF_GUI_DROPDOWN)) {
2690  int64_t value64 = value;
2691  /* Show the correct currency-translated value */
2692  if (sd->flags & SF_GUI_CURRENCY) value64 *= _currency->rate;
2693 
2694  CharSetFilter charset_filter = CS_NUMERAL; //default, only numeric input allowed
2695  if (sd->min < 0) charset_filter = CS_NUMERAL_SIGNED; // special case, also allow '-' sign for negative input
2696 
2697  this->valuewindow_entry = pe;
2698  SetDParam(0, value64);
2699  /* Limit string length to 14 so that MAX_INT32 * max currency rate doesn't exceed MAX_INT64. */
2700  ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 15, this, charset_filter, QSF_ENABLE_DEFAULT);
2701  }
2702  this->SetDisplayedHelpText(pe);
2703  }
2704  }
2705 
2706  void OnTimeout() override
2707  {
2708  if (this->clicked_entry != nullptr) { // On timeout, release any depressed buttons
2709  this->clicked_entry->SetButtons(0);
2710  this->clicked_entry = nullptr;
2711  this->SetDirty();
2712  }
2713  }
2714 
2715  void OnQueryTextFinished(char *str) override
2716  {
2717  /* The user pressed cancel */
2718  if (str == nullptr) return;
2719 
2720  assert(this->valuewindow_entry != nullptr);
2721  const IntSettingDesc *sd = this->valuewindow_entry->setting;
2722 
2723  int32_t value;
2724  if (!StrEmpty(str)) {
2725  long long llvalue = atoll(str);
2726 
2727  /* Save the correct currency-translated value */
2728  if (sd->flags & SF_GUI_CURRENCY) llvalue /= _currency->rate;
2729 
2730  value = ClampTo<int32_t>(llvalue);
2731  } else {
2732  value = sd->def;
2733  }
2734 
2735  SetSettingValue(this->valuewindow_entry->setting, value);
2736  this->SetDirty();
2737  }
2738 
2739  void OnDropdownSelect(WidgetID widget, int index) override
2740  {
2741  switch (widget) {
2743  this->filter.mode = (RestrictionMode)index;
2744  if (this->filter.mode == RM_CHANGED_AGAINST_DEFAULT ||
2745  this->filter.mode == RM_CHANGED_AGAINST_NEW) {
2746 
2747  if (!this->manually_changed_folding) {
2748  /* Expand all when selecting 'changes'. Update the filter state first, in case it becomes less restrictive in some cases. */
2749  GetSettingsTree().UpdateFilterState(this->filter, false);
2751  }
2752  } else {
2753  /* Non-'changes' filter. Save as default. */
2755  }
2756  this->InvalidateData();
2757  break;
2758 
2759  case WID_GS_TYPE_DROPDOWN:
2760  this->filter.type = (SettingType)index;
2761  this->InvalidateData();
2762  break;
2763 
2765  /* Deal with drop down boxes on the panel. */
2766  assert(this->valuedropdown_entry != nullptr);
2767  const IntSettingDesc *sd = this->valuedropdown_entry->setting;
2768  assert(sd->flags & SF_GUI_DROPDOWN);
2769 
2770  SetSettingValue(sd, index);
2771  this->SetDirty();
2772  break;
2773  }
2774  }
2775 
2776  void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
2777  {
2778  if (widget != WID_GS_SETTING_DROPDOWN) {
2779  /* Normally the default implementation of OnDropdownClose() takes care of
2780  * a few things. We want that behaviour here too, but only for
2781  * "normal" dropdown boxes. The special dropdown boxes added for every
2782  * setting that needs one can't have this call. */
2783  Window::OnDropdownClose(pt, widget, index, instant_close);
2784  } else {
2785  /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
2786  * the same dropdown button was clicked again, and then not open the dropdown again.
2787  * So, we only remember that it was closed, and process it on the next OnPaint, which is
2788  * after OnClick. */
2789  assert(this->valuedropdown_entry != nullptr);
2790  this->closing_dropdown = true;
2791  this->SetDirty();
2792  }
2793  }
2794 
2795  void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
2796  {
2797  if (!gui_scope) return;
2798 
2799  /* Update which settings are to be visible. */
2800  RestrictionMode min_level = (this->filter.mode <= RM_ALL) ? this->filter.mode : RM_BASIC;
2801  this->filter.min_cat = min_level;
2802  this->filter.type_hides = false;
2803  GetSettingsTree().UpdateFilterState(this->filter, false);
2804 
2805  if (this->filter.string.IsEmpty()) {
2806  this->warn_missing = WHR_NONE;
2807  } else if (min_level < this->filter.min_cat) {
2808  this->warn_missing = this->filter.type_hides ? WHR_CATEGORY_TYPE : WHR_CATEGORY;
2809  } else {
2810  this->warn_missing = this->filter.type_hides ? WHR_TYPE : WHR_NONE;
2811  }
2812  this->vscroll->SetCount(GetSettingsTree().Length() + this->warn_lines);
2813 
2814  if (this->last_clicked != nullptr && !GetSettingsTree().IsVisible(this->last_clicked)) {
2815  this->SetDisplayedHelpText(nullptr);
2816  }
2817 
2818  bool all_folded = true;
2819  bool all_unfolded = true;
2820  GetSettingsTree().GetFoldingState(all_folded, all_unfolded);
2821  this->SetWidgetDisabledState(WID_GS_EXPAND_ALL, all_unfolded);
2822  this->SetWidgetDisabledState(WID_GS_COLLAPSE_ALL, all_folded);
2823  }
2824 
2825  void OnEditboxChanged(WidgetID wid) override
2826  {
2827  if (wid == WID_GS_FILTER) {
2828  this->filter.string.SetFilterTerm(this->filter_editbox.text.buf);
2829  if (!this->filter.string.IsEmpty() && !this->manually_changed_folding) {
2830  /* User never expanded/collapsed single pages and entered a filter term.
2831  * Expand everything, to save weird expand clicks, */
2833  }
2834  this->InvalidateData();
2835  }
2836  }
2837 
2838  void OnResize() override
2839  {
2840  this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical());
2841  }
2842 };
2843 
2845 
2846 static constexpr NWidgetPart _nested_settings_selection_widgets[] = {
2848  NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
2849  NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_CONFIG_SETTING_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2850  NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
2851  EndContainer(),
2852  NWidget(WWT_PANEL, COLOUR_MAUVE),
2855  NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_CATEGORY), SetDataTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY, STR_NULL),
2856  NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
2857  EndContainer(),
2859  NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL),
2860  NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0),
2861  EndContainer(),
2863  NWidget(WWT_TEXT, COLOUR_MAUVE), SetFill(0, 1), SetDataTip(STR_CONFIG_SETTING_FILTER_TITLE, STR_NULL),
2864  NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_GS_FILTER), SetMinimalSize(50, 12), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
2865  EndContainer(),
2866  EndContainer(),
2867  EndContainer(),
2870  NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_GS_SCROLLBAR),
2871  EndContainer(),
2872  NWidget(WWT_PANEL, COLOUR_MAUVE),
2873  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GS_HELP_TEXT), SetMinimalSize(300, 25), SetFill(1, 1), SetResize(1, 0),
2875  EndContainer(),
2877  NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_EXPAND_ALL), SetDataTip(STR_CONFIG_SETTING_EXPAND_ALL, STR_NULL),
2878  NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_COLLAPSE_ALL), SetDataTip(STR_CONFIG_SETTING_COLLAPSE_ALL, STR_NULL),
2879  NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_RESET_ALL), SetDataTip(STR_CONFIG_SETTING_RESET_ALL, STR_NULL),
2880  NWidget(WWT_PANEL, COLOUR_MAUVE), SetFill(1, 0), SetResize(1, 0),
2881  EndContainer(),
2882  NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
2883  EndContainer(),
2884 };
2885 
2886 static WindowDesc _settings_selection_desc(__FILE__, __LINE__,
2887  WDP_CENTER, "settings", 510, 450,
2889  0,
2890  std::begin(_nested_settings_selection_widgets), std::end(_nested_settings_selection_widgets)
2891 );
2892 
2895 {
2897  new GameSettingsWindow(&_settings_selection_desc);
2898 }
2899 
2900 
2910 void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clickable_left, bool clickable_right)
2911 {
2912  int colour = _colour_gradient[button_colour][2];
2913  Dimension dim = NWidgetScrollbar::GetHorizontalDimension();
2914 
2915  Rect lr = {x, y, x + (int)dim.width - 1, y + (int)dim.height - 1};
2916  Rect rr = {x + (int)dim.width, y, x + (int)dim.width * 2 - 1, y + (int)dim.height - 1};
2917 
2918  DrawFrameRect(lr, button_colour, (state == 1) ? FR_LOWERED : FR_NONE);
2919  DrawFrameRect(rr, button_colour, (state == 2) ? FR_LOWERED : FR_NONE);
2920  DrawSpriteIgnorePadding(SPR_ARROW_LEFT, PAL_NONE, lr, SA_CENTER);
2921  DrawSpriteIgnorePadding(SPR_ARROW_RIGHT, PAL_NONE, rr, SA_CENTER);
2922 
2923  /* Grey out the buttons that aren't clickable */
2924  bool rtl = _current_text_dir == TD_RTL;
2925  if (rtl ? !clickable_right : !clickable_left) {
2927  }
2928  if (rtl ? !clickable_left : !clickable_right) {
2930  }
2931 }
2932 
2941 void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
2942 {
2943  int colour = _colour_gradient[button_colour][2];
2944 
2945  Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
2946 
2947  DrawFrameRect(r, button_colour, state ? FR_LOWERED : FR_NONE);
2948  DrawSpriteIgnorePadding(SPR_ARROW_DOWN, PAL_NONE, r, SA_CENTER);
2949 
2950  if (!clickable) {
2952  }
2953 }
2954 
2962 void DrawBoolButton(int x, int y, bool state, bool clickable)
2963 {
2964  static const Colours _bool_ctabs[2][2] = {{COLOUR_CREAM, COLOUR_RED}, {COLOUR_DARK_GREEN, COLOUR_GREEN}};
2965 
2966  Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1};
2967  DrawFrameRect(r, _bool_ctabs[state][clickable], state ? FR_LOWERED : FR_NONE);
2968 }
2969 
2971  int query_widget;
2972 
2973  CustomCurrencyWindow(WindowDesc *desc) : Window(desc)
2974  {
2975  this->InitNested();
2976 
2977  SetButtonState();
2978  }
2979 
2980  void SetButtonState()
2981  {
2982  this->SetWidgetDisabledState(WID_CC_RATE_DOWN, _custom_currency.rate == 1);
2983  this->SetWidgetDisabledState(WID_CC_RATE_UP, _custom_currency.rate == UINT16_MAX);
2984  this->SetWidgetDisabledState(WID_CC_YEAR_DOWN, _custom_currency.to_euro == CF_NOEURO);
2985  this->SetWidgetDisabledState(WID_CC_YEAR_UP, _custom_currency.to_euro == CalendarTime::MAX_YEAR);
2986  }
2987 
2988  void SetStringParameters(WidgetID widget) const override
2989  {
2990  switch (widget) {
2991  case WID_CC_RATE: SetDParam(0, 1); SetDParam(1, 1); break;
2992  case WID_CC_SEPARATOR: SetDParamStr(0, _custom_currency.separator); break;
2993  case WID_CC_PREFIX: SetDParamStr(0, _custom_currency.prefix); break;
2994  case WID_CC_SUFFIX: SetDParamStr(0, _custom_currency.suffix); break;
2995  case WID_CC_YEAR:
2996  SetDParam(0, (_custom_currency.to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER);
2997  SetDParam(1, _custom_currency.to_euro);
2998  break;
2999 
3000  case WID_CC_PREVIEW:
3001  SetDParam(0, 10000);
3002  break;
3003  }
3004  }
3005 
3006  void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
3007  {
3008  switch (widget) {
3009  /* Set the appropriate width for the up/down buttons. */
3010  case WID_CC_RATE_DOWN:
3011  case WID_CC_RATE_UP:
3012  case WID_CC_YEAR_DOWN:
3013  case WID_CC_YEAR_UP:
3014  *size = maxdim(*size, {(uint)SETTING_BUTTON_WIDTH / 2, (uint)SETTING_BUTTON_HEIGHT});
3015  break;
3016 
3017  /* Set the appropriate width for the edit buttons. */
3018  case WID_CC_SEPARATOR_EDIT:
3019  case WID_CC_PREFIX_EDIT:
3020  case WID_CC_SUFFIX_EDIT:
3021  *size = maxdim(*size, {(uint)SETTING_BUTTON_WIDTH, (uint)SETTING_BUTTON_HEIGHT});
3022  break;
3023 
3024  /* Make sure the window is wide enough for the widest exchange rate */
3025  case WID_CC_RATE:
3026  SetDParam(0, 1);
3027  SetDParam(1, INT32_MAX);
3028  *size = GetStringBoundingBox(STR_CURRENCY_EXCHANGE_RATE);
3029  break;
3030  }
3031  }
3032 
3033  void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
3034  {
3035  int line = 0;
3036  int len = 0;
3037  StringID str = 0;
3038  CharSetFilter afilter = CS_ALPHANUMERAL;
3039 
3040  switch (widget) {
3041  case WID_CC_RATE_DOWN:
3042  if (_custom_currency.rate > 1) _custom_currency.rate--;
3043  if (_custom_currency.rate == 1) this->DisableWidget(WID_CC_RATE_DOWN);
3045  break;
3046 
3047  case WID_CC_RATE_UP:
3048  if (_custom_currency.rate < UINT16_MAX) _custom_currency.rate++;
3049  if (_custom_currency.rate == UINT16_MAX) this->DisableWidget(WID_CC_RATE_UP);
3051  break;
3052 
3053  case WID_CC_RATE:
3054  SetDParam(0, _custom_currency.rate);
3055  str = STR_JUST_INT;
3056  len = 5;
3057  line = WID_CC_RATE;
3058  afilter = CS_NUMERAL;
3059  break;
3060 
3061  case WID_CC_SEPARATOR_EDIT:
3062  case WID_CC_SEPARATOR:
3063  SetDParamStr(0, _custom_currency.separator);
3064  str = STR_JUST_RAW_STRING;
3065  len = 7;
3066  line = WID_CC_SEPARATOR;
3067  break;
3068 
3069  case WID_CC_PREFIX_EDIT:
3070  case WID_CC_PREFIX:
3071  SetDParamStr(0, _custom_currency.prefix);
3072  str = STR_JUST_RAW_STRING;
3073  len = 15;
3074  line = WID_CC_PREFIX;
3075  break;
3076 
3077  case WID_CC_SUFFIX_EDIT:
3078  case WID_CC_SUFFIX:
3079  SetDParamStr(0, _custom_currency.suffix);
3080  str = STR_JUST_RAW_STRING;
3081  len = 15;
3082  line = WID_CC_SUFFIX;
3083  break;
3084 
3085  case WID_CC_YEAR_DOWN:
3086  _custom_currency.to_euro = (_custom_currency.to_euro <= MIN_EURO_YEAR) ? CF_NOEURO : _custom_currency.to_euro - 1;
3087  if (_custom_currency.to_euro == CF_NOEURO) this->DisableWidget(WID_CC_YEAR_DOWN);
3089  break;
3090 
3091  case WID_CC_YEAR_UP:
3092  _custom_currency.to_euro = Clamp(_custom_currency.to_euro + 1, MIN_EURO_YEAR, CalendarTime::MAX_YEAR);
3093  if (_custom_currency.to_euro == CalendarTime::MAX_YEAR) this->DisableWidget(WID_CC_YEAR_UP);
3095  break;
3096 
3097  case WID_CC_YEAR:
3098  SetDParam(0, _custom_currency.to_euro);
3099  str = STR_JUST_INT;
3100  len = 7;
3101  line = WID_CC_YEAR;
3102  afilter = CS_NUMERAL;
3103  break;
3104  }
3105 
3106  if (len != 0) {
3107  this->query_widget = line;
3108  ShowQueryString(str, STR_CURRENCY_CHANGE_PARAMETER, len + 1, this, afilter, QSF_NONE);
3109  }
3110 
3111  this->SetTimeout();
3112  this->SetDirty();
3113  }
3114 
3115  void OnQueryTextFinished(char *str) override
3116  {
3117  if (str == nullptr) return;
3118 
3119  switch (this->query_widget) {
3120  case WID_CC_RATE:
3121  _custom_currency.rate = Clamp(atoi(str), 1, UINT16_MAX);
3122  break;
3123 
3124  case WID_CC_SEPARATOR: // Thousands separator
3125  _custom_currency.separator = str;
3126  break;
3127 
3128  case WID_CC_PREFIX:
3129  _custom_currency.prefix = str;
3130  break;
3131 
3132  case WID_CC_SUFFIX:
3133  _custom_currency.suffix = str;
3134  break;
3135 
3136  case WID_CC_YEAR: { // Year to switch to euro
3137  TimerGameCalendar::Year val = atoi(str);
3138 
3139  _custom_currency.to_euro = (val < MIN_EURO_YEAR ? CF_NOEURO : std::min(val, CalendarTime::MAX_YEAR));
3140  break;
3141  }
3142  }
3144  SetButtonState();
3145  }
3146 
3147  void OnTimeout() override
3148  {
3149  this->SetDirty();
3150  }
3151 };
3152 
3153 static constexpr NWidgetPart _nested_cust_currency_widgets[] = {
3155  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
3156  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CURRENCY_WINDOW, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
3157  EndContainer(),
3158  NWidget(WWT_PANEL, COLOUR_GREY),
3163  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_DOWN), SetDataTip(AWV_DECREASE, STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP),
3164  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_RATE_UP), SetDataTip(AWV_INCREASE, STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP),
3165  EndContainer(),
3166  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_RATE), SetDataTip(STR_CURRENCY_EXCHANGE_RATE, STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP), SetFill(1, 0),
3167  EndContainer(),
3169  NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SEPARATOR_EDIT), SetDataTip(0x0, STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(0, 1),
3170  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_SEPARATOR), SetDataTip(STR_CURRENCY_SEPARATOR, STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP), SetFill(1, 0),
3171  EndContainer(),
3173  NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_PREFIX_EDIT), SetDataTip(0x0, STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(0, 1),
3174  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_PREFIX), SetDataTip(STR_CURRENCY_PREFIX, STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP), SetFill(1, 0),
3175  EndContainer(),
3177  NWidget(WWT_PUSHBTN, COLOUR_DARK_BLUE, WID_CC_SUFFIX_EDIT), SetDataTip(0x0, STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(0, 1),
3178  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_SUFFIX), SetDataTip(STR_CURRENCY_SUFFIX, STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP), SetFill(1, 0),
3179  EndContainer(),
3182  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_DOWN), SetDataTip(AWV_DECREASE, STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
3183  NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_CC_YEAR_UP), SetDataTip(AWV_INCREASE, STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP),
3184  EndContainer(),
3185  NWidget(WWT_TEXT, COLOUR_BLUE, WID_CC_YEAR), SetDataTip(STR_JUST_STRING1, STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP), SetFill(1, 0),
3186  EndContainer(),
3187  EndContainer(),
3188  NWidget(WWT_LABEL, COLOUR_BLUE, WID_CC_PREVIEW),
3189  SetDataTip(STR_CURRENCY_PREVIEW, STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP),
3190  EndContainer(),
3191  EndContainer(),
3192 };
3193 
3194 static WindowDesc _cust_currency_desc(__FILE__, __LINE__,
3195  WDP_CENTER, nullptr, 0, 0,
3197  0,
3198  std::begin(_nested_cust_currency_widgets), std::end(_nested_cust_currency_widgets)
3199 );
3200 
3202 static void ShowCustCurrency()
3203 {
3205  new CustomCurrencyWindow(&_cust_currency_desc);
3206 }
SZSP_NONE
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
Definition: widget_type.h:469
WID_CC_YEAR_DOWN
@ WID_CC_YEAR_DOWN
Down button.
Definition: settings_widget.h:91
Window::timeout_timer
uint8_t timeout_timer
Timer value of the WF_TIMEOUT for flags.
Definition: window_gui.h:300
WC_CUSTOM_CURRENCY
@ WC_CUSTOM_CURRENCY
Custom currency; Window numbers:
Definition: window_type.h:625
NWidgetResizeBase
Base class for a resizable nested widget.
Definition: widget_type.h:291
SEF_RIGHT_DEPRESSED
@ SEF_RIGHT_DEPRESSED
Of a numeric setting entry, the right button is depressed.
Definition: settings_gui.cpp:1198
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition: widget_type.h:1143
_autosave_dropdown_to_minutes
static const uint32_t _autosave_dropdown_to_minutes[]
Available settings for autosave intervals.
Definition: settings_gui.cpp:68
WID_CC_PREVIEW
@ WID_CC_PREVIEW
Preview.
Definition: settings_widget.h:94
NWidgetContainer::children
std::vector< std::unique_ptr< NWidgetBase > > children
Child widgets in contaier.
Definition: widget_type.h:462
Window::SetTimeout
void SetTimeout()
Set the timeout flag of the window and initiate the timer.
Definition: window_gui.h:355
CustomCurrencyWindow::OnTimeout
void OnTimeout() override
Called when this window's timeout has been reached.
Definition: settings_gui.cpp:3147
CloseWindowByClass
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition: window.cpp:1153
SetSettingValue
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.
Definition: settings.cpp:1753
social_integration.h
WID_GO_FULLSCREEN_BUTTON
@ WID_GO_FULLSCREEN_BUTTON
Toggle fullscreen.
Definition: settings_widget.h:25
factory.hpp
SocialIntegrationPlugin::FAILED
@ FAILED
The plugin failed to initialize.
Definition: social_integration.h:18
WID_GS_TYPE_DROPDOWN
@ WID_GS_TYPE_DROPDOWN
The drop down box to choose client/game/company/all settings.
Definition: settings_widget.h:75
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
SocialIntegrationPlugin::name
std::string name
Name of the plugin.
Definition: social_integration.h:29
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
SEF_LEFT_DEPRESSED
@ SEF_LEFT_DEPRESSED
Of a numeric setting entry, the left button is depressed.
Definition: settings_gui.cpp:1197
querystring_gui.h
GetCurrentLanguageIsoCode
const char * GetCurrentLanguageIsoCode()
Get the ISO language code of the currently loaded language.
Definition: strings.cpp:2160
SEF_BUTTONS_MASK
@ SEF_BUTTONS_MASK
Bit-mask for button flags.
Definition: settings_gui.cpp:1199
ShowQuery
void ShowQuery(StringID caption, StringID 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...
Definition: misc_gui.cpp:1231
WID_TF_CAPTION
@ WID_TF_CAPTION
The caption of the window.
Definition: misc_widget.h:51
WID_GO_BASE_SFX_OPEN_URL
@ WID_GO_BASE_SFX_OPEN_URL
Open base SFX URL.
Definition: settings_widget.h:39
WID_GS_COLLAPSE_ALL
@ WID_GS_COLLAPSE_ALL
Collapse all button.
Definition: settings_widget.h:70
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition: geometry_type.hpp:30
command_func.h
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition: window_gui.h:68
BaseSetTextfileWindow::baseset
const TBaseSet * baseset
View the textfile of this BaseSet.
Definition: settings_gui.cpp:95
WID_GO_CURRENCY_DROPDOWN
@ WID_GO_CURRENCY_DROPDOWN
Currency dropdown.
Definition: settings_widget.h:20
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
Definition: error_gui.cpp:367
DropDownString< DropDownListItem >::NatSortFunc
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
Definition: dropdown_type.h:126
BaseSetTextfileWindow::content_type
StringID content_type
STR_CONTENT_TYPE_xxx for title.
Definition: settings_gui.cpp:96
dropdown_func.h
Rect::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition: geometry_type.hpp:98
GetSettingFromName
static const SettingDesc * GetSettingFromName(const std::string_view name, const SettingTable &settings)
Given a name of setting, return a setting description from the table.
Definition: settings.cpp:1625
GameSettingsWindow
Window to edit settings of the game.
Definition: settings_gui.cpp:2308
StringFilter::IsEmpty
bool IsEmpty() const
Check whether any filter words were entered.
Definition: stringfilter_type.h:60
BaseMedia< GraphicsSet >::SetSet
static bool SetSet(const GraphicsSet *set)
Set the set to be used.
Definition: base_media_func.h:241
_left_button_down
bool _left_button_down
Is left mouse button pressed?
Definition: gfx.cpp:40
SettingsPage::GetFoldingState
void GetFoldingState(bool &all_folded, bool &all_unfolded) const override
Recursively accumulate the folding state of the (filtered) tree.
Definition: settings_gui.cpp:1825
WID_CC_RATE_UP
@ WID_CC_RATE_UP
Up button.
Definition: settings_widget.h:83
company_base.h
SettingsPage::Length
uint Length() const override
Return number of rows needed to display the (filtered) entry.
Definition: settings_gui.cpp:1877
WID_GS_FILTER
@ WID_GS_FILTER
Text filter.
Definition: settings_widget.h:65
GameSettingsWindow::settings_ptr
static GameSettings * settings_ptr
Pointer to the game settings being displayed and modified.
Definition: settings_gui.cpp:2309
Window::OnDropdownClose
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:288
IntSettingDesc::cat
SettingCategory cat
assigned categories of the setting
Definition: settings_internal.h:218
StringFilter::SetFilterTerm
void SetFilterTerm(const char *str)
Set the term to filter on.
Definition: stringfilter.cpp:28
GameSettingsWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition: settings_gui.cpp:2355
GameSettingsWindow::OnInvalidateData
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Definition: settings_gui.cpp:2795
WID_GO_SOCIAL_PLUGIN_PLATFORM
@ WID_GO_SOCIAL_PLUGIN_PLATFORM
Platform of the social plugin.
Definition: settings_widget.h:59
WID_GO_GUI_SCALE
@ WID_GO_GUI_SCALE
GUI Scale slider.
Definition: settings_widget.h:26
NWidgetContainer::Add
void Add(std::unique_ptr< NWidgetBase > &&wid)
Append widget wid to container.
Definition: widget.cpp:1161
SettingFilter::type
SettingType type
Filter based on type.
Definition: settings_gui.cpp:1222
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:63
Window::SetWidgetDirty
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:552
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:116
currency.h
NWidgetPIPContainer::SetPIP
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:1335
MusicDriver::SetVolume
virtual void SetVolume(byte vol)=0
Set the volume, if possible.
SetAlignment
constexpr NWidgetPart SetAlignment(StringAlignment align)
Widget part function for setting the alignment of text/images.
Definition: widget_type.h:1132
WID_GO_LANG_DROPDOWN
@ WID_GO_LANG_DROPDOWN
Language dropdown.
Definition: settings_widget.h:23
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
ST_GAME
@ ST_GAME
Game setting.
Definition: settings_internal.h:61
SettingEntry::setting
const IntSettingDesc * setting
Setting description of the setting.
Definition: settings_gui.cpp:1267
WWT_LABEL
@ WWT_LABEL
Centered label.
Definition: widget_type.h:59
CloseWindowById
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:1141
DropDownList
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Definition: dropdown_type.h:210
SettingDesc::GetType
SettingType GetType() const
Return the type of the setting.
Definition: settings.cpp:916
WWT_DEFSIZEBOX
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition: widget_type.h:67
VideoDriver::ToggleVsync
virtual void ToggleVsync([[maybe_unused]] bool vsync)
Change the vsync setting.
Definition: video_driver.hpp:73
WID_GO_SURVEY_SEL
@ WID_GO_SURVEY_SEL
Selection to hide survey if no JSON library is compiled in.
Definition: settings_widget.h:53
SettingDesc::IsEditable
bool IsEditable(bool do_command=false) const
Check whether the setting is editable in the current gamemode.
Definition: settings.cpp:899
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition: widget_type.h:77
SettingsContainer::GetMaxHelpHeight
uint GetMaxHelpHeight(int maxw)
Get the biggest height of the help texts, if the width is at least maxw.
Definition: settings_gui.cpp:1739
WID_CC_RATE_DOWN
@ WID_CC_RATE_DOWN
Down button.
Definition: settings_widget.h:82
GameSettingsWindow::filter_editbox
QueryString filter_editbox
Filter editbox;.
Definition: settings_gui.cpp:2318
ST_CLIENT
@ ST_CLIENT
Client setting.
Definition: settings_internal.h:63
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition: geometry_func.cpp:22
WID_GS_EXPAND_ALL
@ WID_GS_EXPAND_ALL
Expand all button.
Definition: settings_widget.h:69
Window::Close
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition: window.cpp:1048
BaseSettingEntry::SetLastField
void SetLastField(bool last_field)
Set whether this is the last visible entry of the parent node.
Definition: settings_gui.cpp:1242
Window::EnableWidget
void EnableWidget(WidgetID widget_index)
Sets a widget to Enabled.
Definition: window_gui.h:400
WID_GS_RESTRICT_DROPDOWN
@ WID_GS_RESTRICT_DROPDOWN
The drop down box to restrict the list of settings.
Definition: settings_widget.h:74
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition: widget_type.h:1153
BaseSetTextfileWindow
Window for displaying the textfile of a BaseSet.
Definition: settings_gui.cpp:94
WID_GO_SOCIAL_PLUGIN_TITLE
@ WID_GO_SOCIAL_PLUGIN_TITLE
Title of the frame of the social plugin.
Definition: settings_widget.h:58
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:37
FILLRECT_CHECKER
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition: gfx_type.h:294
WID_GO_SURVEY_PREVIEW_BUTTON
@ WID_GO_SURVEY_PREVIEW_BUTTON
Button to open a preview window with the survey results.
Definition: settings_widget.h:56
WID_GS_SCROLLBAR
@ WID_GS_SCROLLBAR
Scrollbar.
Definition: settings_widget.h:67
SettingFilter::string
StringFilter string
Filter string.
Definition: settings_gui.cpp:1218
GameOptionsWindow
Definition: settings_gui.cpp:354
zoom_func.h
Scrollbar::SetCapacityFromWidget
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:2341
ST_COMPANY
@ ST_COMPANY
Company setting.
Definition: settings_internal.h:62
WID_GO_BASE_MUSIC_VOLUME
@ WID_GO_BASE_MUSIC_VOLUME
Change music volume.
Definition: settings_widget.h:44
base_media_base.h
NWidgetResizeBase::UpdateVerticalSize
bool UpdateVerticalSize(uint min_y)
Set absolute (post-scaling) minimal size of the widget.
Definition: widget.cpp:1056
SettingsContainer::entries
EntryVector entries
Settings on this page.
Definition: settings_gui.cpp:1289
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:54
GameSettingsWindow::last_clicked
SettingEntry * last_clicked
If non-nullptr, pointer to the last clicked setting.
Definition: settings_gui.cpp:2313
WWT_EMPTY
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition: widget_type.h:50
SettingsPage::FindEntry
BaseSettingEntry * FindEntry(uint row, uint *cur_row) override
Find setting entry at row row_num.
Definition: settings_gui.cpp:1891
WID_GO_BASE_GRF_TEXTFILE
@ WID_GO_BASE_GRF_TEXTFILE
Open base GRF readme, changelog (+1) or license (+2).
Definition: settings_widget.h:34
WidgetDimensions::hsep_wide
int hsep_wide
Wide horizontal spacing.
Definition: window_gui.h:64
town.h
RectPadding::Vertical
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Definition: geometry_type.hpp:69
WWT_PUSHARROWBTN
@ WWT_PUSHARROWBTN
Normal push-button (no toggle button) with arrow caption.
Definition: widget_type.h:112
StrongType::Typedef
Templated helper to make a type-safe 'typedef' representing a single POD value.
Definition: strong_typedef_type.hpp:150
StringFilter::AddLine
void AddLine(const char *str)
Pass another text line from the current item to the filter.
Definition: stringfilter.cpp:114
network_gui.h
FR_LOWERED
@ FR_LOWERED
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
Definition: window_gui.h:28
settings_internal.h
SettingDesc::flags
SettingFlag flags
Handles how a setting would show up in the GUI (text/currency, etc.).
Definition: settings_internal.h:76
SA_RIGHT
@ SA_RIGHT
Right align the text (must be a single bit).
Definition: gfx_type.h:340
SEF_FILTERED
@ SEF_FILTERED
Entry is hidden by the string filter.
Definition: settings_gui.cpp:1202
NWidgetFunction
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
Definition: widget_type.h:1281
WC_MUSIC_WINDOW
@ WC_MUSIC_WINDOW
Music window; Window numbers:
Definition: window_type.h:602
newgrf_config.h
SettingEntry::IsVisibleByRestrictionMode
bool IsVisibleByRestrictionMode(RestrictionMode mode) const
Checks whether an entry shall be made visible based on the restriction mode.
Definition: settings_gui.cpp:1500
SettingsPage::SettingsPage
SettingsPage(StringID title)
Constructor for a sub-page in the 'advanced settings' window.
Definition: settings_gui.cpp:1778
WID_GO_VIDEO_DRIVER_INFO
@ WID_GO_VIDEO_DRIVER_INFO
Label showing details about the current video driver.
Definition: settings_widget.h:52
BaseSettingEntry::Init
virtual void Init(byte level=0)
Initialization of a setting entry.
Definition: settings_gui.cpp:1346
Scrollbar
Scrollbar data structure.
Definition: widget_type.h:680
Window::GetScrollbar
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:315
WID_GO_GUI_FONT_SPRITE
@ WID_GO_GUI_FONT_SPRITE
Toggle whether to prefer the sprite font over TTF fonts.
Definition: settings_widget.h:29
SettingsPage
Data structure describing one page of settings in the settings window.
Definition: settings_gui.cpp:1315
StrEmpty
bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:56
TextfileWindow::file_type
TextfileType file_type
Type of textfile to view.
Definition: textfile_gui.h:22
TFT_CHANGELOG
@ TFT_CHANGELOG
Content changelog.
Definition: textfile_type.h:18
SettingsContainer::UpdateFilterState
bool UpdateFilterState(SettingFilter &filter, bool force_visible)
Update the filter state.
Definition: settings_gui.cpp:1679
Rect::WithHeight
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Definition: geometry_type.hpp:211
Window::Window
Window(WindowDesc *desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1757
CustomCurrencyWindow
Definition: settings_gui.cpp:2970
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:1040
textfile_gui.h
SettingEntry::Init
void Init(byte level=0) override
Initialization of a setting entry.
Definition: settings_gui.cpp:1456
Scrollbar::GetPosition
uint16_t GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:722
QueryString
Data stored about a string that can be modified in the GUI.
Definition: querystring_gui.h:20
WC_GRF_PARAMETERS
@ WC_GRF_PARAMETERS
NewGRF parameters; Window numbers:
Definition: window_type.h:181
NWidgetSocialPlugins::SetupSmallestSize
void SetupSmallestSize(Window *w) override
Definition: settings_gui.cpp:222
WID_GO_BASE_MUSIC_DESCRIPTION
@ WID_GO_BASE_MUSIC_DESCRIPTION
Description of selected base music set.
Definition: settings_widget.h:48
WID_GO_TAB_SELECTION
@ WID_GO_TAB_SELECTION
Background of the tab selection.
Definition: settings_widget.h:19
SETBITS
#define SETBITS(x, y)
Sets several bits in a variable.
Definition: bitmath_func.hpp:136
GameSettingsWindow::OnTimeout
void OnTimeout() override
Called when this window's timeout has been reached.
Definition: settings_gui.cpp:2706
_colour_gradient
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Definition: palette.cpp:26
_gui_scale
int _gui_scale
GUI scale, 100 is 100%.
Definition: gfx.cpp:62
GetStringLineCount
int GetStringLineCount(StringID str, int maxw)
Calculates number of lines of string.
Definition: gfx.cpp:725
textbuf_gui.h
Textbuf::buf
char *const buf
buffer in which text is saved
Definition: textbuf_type.h:32
Scrollbar::GetCount
uint16_t GetCount() const
Gets the number of elements in the list.
Definition: widget_type.h:704
MakeNWidgetSocialPlugins
std::unique_ptr< NWidgetBase > MakeNWidgetSocialPlugins()
Construct nested container widget for managing the list of social plugins.
Definition: settings_gui.cpp:349
ai.hpp
WN_GAME_OPTIONS_GAME_OPTIONS
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
Definition: window_type.h:26
SettingsPage::FoldAll
void FoldAll() override
Recursively close all (filtered) folds of sub-pages.
Definition: settings_gui.cpp:1803
WID_GO_BASE_GRF_OPEN_URL
@ WID_GO_BASE_GRF_OPEN_URL
Open base GRF URL.
Definition: settings_widget.h:33
WindowDesc
High level window description.
Definition: window_gui.h:153
GameSettingsWindow::warn_missing
WarnHiddenResult warn_missing
Whether and how to warn about missing search results.
Definition: settings_gui.cpp:2320
WidgetID
int WidgetID
Widget ID.
Definition: window_type.h:18
AdjustGUIZoom
bool AdjustGUIZoom(bool automatic)
Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested.
Definition: gfx.cpp:1810
BaseSettingEntry::level
byte level
Nesting level of this setting entry.
Definition: settings_gui.cpp:1228
WID_GO_BASE_SFX_DESCRIPTION
@ WID_GO_BASE_SFX_DESCRIPTION
Description of selected base SFX.
Definition: settings_widget.h:41
SocialIntegrationPlugin::INVALID_SIGNATURE
@ INVALID_SIGNATURE
The signature of the plugin is invalid.
Definition: social_integration.h:23
SettingType
SettingType
Type of settings for filtering.
Definition: settings_internal.h:60
DECLARE_POSTFIX_INCREMENT
#define DECLARE_POSTFIX_INCREMENT(enum_type)
Some enums need to have allowed incrementing (i.e.
Definition: enum_type.hpp:14
_gui_scale_cfg
int _gui_scale_cfg
GUI scale in config.
Definition: gfx.cpp:63
GUISettings::refresh_rate
uint16_t refresh_rate
How often we refresh the screen (time between draw-ticks).
Definition: settings_type.h:201
SettingEntry::DrawSetting
void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const override
Function to draw setting value (button + text + current value)
Definition: settings_gui.cpp:1593
SettingsPage::title
StringID title
Title of the sub-page.
Definition: settings_gui.cpp:1316
SettingFilter::min_cat
RestrictionMode min_cat
Minimum category needed to display all filtered strings (RM_BASIC, RM_ADVANCED, or RM_ALL).
Definition: settings_gui.cpp:1219
NC_EQUALSIZE
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:510
SF_GUI_CURRENCY
@ SF_GUI_CURRENCY
The number represents money, so when reading value multiply by exchange rate.
Definition: settings_internal.h:20
SetPadding
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.
Definition: widget_type.h:1190
WID_GO_AUTOSAVE_DROPDOWN
@ WID_GO_AUTOSAVE_DROPDOWN
Dropdown to say how often to autosave.
Definition: settings_widget.h:22
WID_GS_OPTIONSPANEL
@ WID_GS_OPTIONSPANEL
Panel widget containing the option lists.
Definition: settings_widget.h:66
SettingsPage::UpdateFilterState
bool UpdateFilterState(SettingFilter &filter, bool force_visible) override
Update the filter state.
Definition: settings_gui.cpp:1844
WC_QUERY_STRING
@ WC_QUERY_STRING
Query string window; Window numbers:
Definition: window_type.h:123
SocialIntegrationPlugin::UNLOADED
@ UNLOADED
The plugin is unloaded upon request.
Definition: social_integration.h:20
SF_GUI_0_IS_SPECIAL
@ SF_GUI_0_IS_SPECIAL
A value of zero is possible and has a custom string (the one after "strval").
Definition: settings_internal.h:18
SetResize
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition: widget_type.h:1088
DrawDropDownButton
void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable)
Draw a dropdown button.
Definition: settings_gui.cpp:2941
MIN_EURO_YEAR
static constexpr TimerGameCalendar::Year MIN_EURO_YEAR
The earliest year custom currencies may switch to the Euro.
Definition: currency.h:19
SocialIntegrationPlugin
Definition: social_integration.h:13
WWT_PUSHBTN
@ WWT_PUSHBTN
Normal push-button (no toggle button) with custom drawing.
Definition: widget_type.h:109
SettingsPage::ResetAll
void ResetAll() override
Resets all settings to their default values.
Definition: settings_gui.cpp:1795
Window::resize
ResizeInfo resize
Resize information.
Definition: window_gui.h:308
GameSettingsWindow::warn_lines
int warn_lines
Number of lines used for warning about missing search results.
Definition: settings_gui.cpp:2321
ResetAllSettingsConfirmationCallback
static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed)
Callback function for the reset all settings button.
Definition: settings_gui.cpp:2298
VideoDriver::GetListOfMonitorRefreshRates
virtual std::vector< int > GetListOfMonitorRefreshRates()
Get a list of refresh rates of each available monitor.
Definition: video_driver.hpp:162
WID_GO_BASE_MUSIC_DROPDOWN
@ WID_GO_BASE_MUSIC_DROPDOWN
Use to select a base music set.
Definition: settings_widget.h:42
SETTING_HEIGHT
static int SETTING_HEIGHT
Height of a single setting in the tree view in pixels.
Definition: settings_gui.cpp:1190
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:147
MusicDriver::GetInstance
static MusicDriver * GetInstance()
Get the currently active instance of the music driver.
Definition: music_driver.hpp:46
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition: gfx_type.h:203
RestrictionMode
RestrictionMode
How the list of advanced settings is filtered.
Definition: settings_gui.cpp:1206
SettingEntry::UpdateFilterState
bool UpdateFilterState(SettingFilter &filter, bool force_visible) override
Update the filter state.
Definition: settings_gui.cpp:1541
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1747
SetScrollbar
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1246
WWT_EDITBOX
@ WWT_EDITBOX
a textbox for typing
Definition: widget_type.h:73
GameSettingsWindow::valuewindow_entry
SettingEntry * valuewindow_entry
If non-nullptr, pointer to setting for which a value-entering window has been opened.
Definition: settings_gui.cpp:2311
ReInitAllWindows
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Definition: window.cpp:3320
WHR_TYPE
@ WHR_TYPE
Type setting filtered matches away.
Definition: settings_gui.cpp:2289
Window::height
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:306
WF_CENTERED
@ WF_CENTERED
Window is centered and shall stay centered after ReInit.
Definition: window_gui.h:232
IntSettingDesc
Base integer type, including boolean, settings.
Definition: settings_internal.h:148
WID_GO_TAB_GRAPHICS
@ WID_GO_TAB_GRAPHICS
Graphics tab.
Definition: settings_widget.h:16
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:941
GRFConfig::SetParameterDefaults
void SetParameterDefaults()
Set the default value for all parameters as specified by action14.
Definition: newgrf_config.cpp:123
highscore.h
GetTextfile
std::optional< std::string > GetTextfile(TextfileType type, Subdirectory dir, const std::string &filename)
Search a textfile file next to the given content.
Definition: textfile_gui.cpp:865
FS_SMALL
@ FS_SMALL
Index of the small font in the font tables.
Definition: gfx_type.h:204
SettingsContainer::ResetAll
void ResetAll()
Resets all settings to their default values.
Definition: settings_gui.cpp:1638
SettingsPage::Init
void Init(byte level=0) override
Initialization of an entire setting page.
Definition: settings_gui.cpp:1788
WID_GS_RESTRICT_CATEGORY
@ WID_GS_RESTRICT_CATEGORY
Label upfront to the category drop-down box to restrict the list of settings to show.
Definition: settings_widget.h:72
GUISettings::missing_strings_threshold
byte missing_strings_threshold
the number of missing strings before showing the warning
Definition: settings_type.h:193
BaseSettingEntry
Data structure describing a single setting in a tab.
Definition: settings_gui.cpp:1226
NWidgetContainer::FillWidgetLookup
void FillWidgetLookup(WidgetLookup &widget_lookup) override
Definition: widget.cpp:1168
GameOptionsWindow::OnInvalidateData
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Definition: settings_gui.cpp:963
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:110
InitFontCache
void InitFontCache(bool monospace)
(Re)initialize the font cache related things, i.e.
Definition: fontcache.cpp:197
WID_GO_SOCIAL_PLUGINS
@ WID_GO_SOCIAL_PLUGINS
Main widget handling the social plugins.
Definition: settings_widget.h:57
IntSettingDesc::def
int32_t def
default value given when none is present
Definition: settings_internal.h:211
NWidgetBase
Baseclass for nested widgets.
Definition: widget_type.h:135
NWidgetSocialPlugins::FillWidgetLookup
void FillWidgetLookup(WidgetLookup &widget_lookup) override
Definition: settings_gui.cpp:216
RM_END
@ RM_END
End for iteration.
Definition: settings_gui.cpp:1212
FontCacheSettings::prefer_sprite
bool prefer_sprite
Whether to prefer the built-in sprite font over resizable fonts.
Definition: fontcache.h:221
WID_GO_TEXT_MUSIC_VOLUME
@ WID_GO_TEXT_MUSIC_VOLUME
Music volume label.
Definition: settings_widget.h:43
ShowDropDownListAt
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:351
SettingFilter::mode
RestrictionMode mode
Filter based on category.
Definition: settings_gui.cpp:1221
WID_GO_TAB_GENERAL
@ WID_GO_TAB_GENERAL
General tab.
Definition: settings_widget.h:15
Scrollbar::GetCapacity
uint16_t GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:713
SettingsPage::IsVisible
bool IsVisible(const BaseSettingEntry *item) const override
Check whether an entry is visible and not folded or filtered away.
Definition: settings_gui.cpp:1867
dropdown_type.h
SocialIntegrationPlugin::DUPLICATE
@ DUPLICATE
Another plugin of the same Social Platform is already loaded.
Definition: social_integration.h:21
WID_CC_YEAR
@ WID_CC_YEAR
Year of introduction.
Definition: settings_widget.h:93
Window::ReInit
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition: window.cpp:953
WID_GO_BASE_SFX_VOLUME
@ WID_GO_BASE_SFX_VOLUME
Change sound effects volume.
Definition: settings_widget.h:38
GameSettingsWindow::OnDropdownClose
void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
A dropdown window associated to this window has been closed.
Definition: settings_gui.cpp:2776
IntSettingDesc::min
int32_t min
minimum values
Definition: settings_internal.h:212
SettingEntry::name
const char * name
Name of the setting.
Definition: settings_gui.cpp:1266
TextfileWindow::LoadTextfile
virtual void LoadTextfile(const std::string &textfile, Subdirectory dir)
Loads the textfile text from file and setup lines.
Definition: textfile_gui.cpp:765
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition: error.h:24
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
Definition: widget_type.h:1260
WID_GO_SOCIAL_PLUGIN_STATE
@ WID_GO_SOCIAL_PLUGIN_STATE
State of the social plugin.
Definition: settings_widget.h:60
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:50
_current_language
const LanguageMetadata * _current_language
The currently loaded language.
Definition: strings.cpp:54
DrawSliderWidget
void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map< int, StringID > &labels)
Draw a slider widget with knob at given value.
Definition: slider.cpp:30
CurrencySpec::code
std::string code
3 letter untranslated code to identify the currency.
Definition: currency.h:80
SEF_LAST_FIELD
@ SEF_LAST_FIELD
This entry is the last one in a (sub-)page.
Definition: settings_gui.cpp:1201
WID_GO_TEXT_SFX_VOLUME
@ WID_GO_TEXT_SFX_VOLUME
Sound effects volume label.
Definition: settings_widget.h:37
GetMaskOfAllowedCurrencies
uint64_t GetMaskOfAllowedCurrencies()
get a mask of the allowed currencies depending on the year
Definition: currency.cpp:124
safeguards.h
ShowQueryString
void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition: misc_gui.cpp:1087
RM_ALL
@ RM_ALL
List all settings regardless of the default/newgame/... values.
Definition: settings_gui.cpp:1209
Window::LowerWidget
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition: window_gui.h:460
music_driver.hpp
Window::flags
WindowFlags flags
Window flags.
Definition: window_gui.h:294
_resolutions
std::vector< Dimension > _resolutions
List of resolutions.
Definition: driver.cpp:31
WF_TIMEOUT
@ WF_TIMEOUT
Window timeout counter.
Definition: window_gui.h:222
NWidgetVertical::SetupSmallestSize
void SetupSmallestSize(Window *w) override
Definition: widget.cpp:1556
GetStringHeight
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition: gfx.cpp:701
WID_GO_VIDEO_ACCEL_BUTTON
@ WID_GO_VIDEO_ACCEL_BUTTON
Toggle for video acceleration.
Definition: settings_widget.h:49
GameSettings
All settings together for the game.
Definition: settings_type.h:616
NETWORK_SURVEY_DETAILS_LINK
static const std::string NETWORK_SURVEY_DETAILS_LINK
Link with more details & privacy statement of the survey.
Definition: config.h:30
SettingsPage::folded
bool folded
Sub-page is folded (not visible except for its title)
Definition: settings_gui.cpp:1317
ChangeAutosaveFrequency
void ChangeAutosaveFrequency(bool reset)
Reset the interval of the autosave.
Definition: openttd.cpp:1539
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:1003
GameOptionsWindow::OnMouseLoop
void OnMouseLoop() override
Called for every mouse loop run, which is at least once per (game) tick.
Definition: settings_gui.cpp:878
GameSettingsWindow::valuedropdown_entry
SettingEntry * valuedropdown_entry
If non-nullptr, pointer to the value for which a dropdown window is currently opened.
Definition: settings_gui.cpp:2314
SettingsContainer::Init
void Init(byte level=0)
Initialization of an entire setting page.
Definition: settings_gui.cpp:1630
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:21
NWidgetSocialPlugins
Definition: settings_gui.cpp:197
error.h
WID_GO_BASE_GRF_DESCRIPTION
@ WID_GO_BASE_GRF_DESCRIPTION
Description of selected base GRF.
Definition: settings_widget.h:35
CheckBlitter
void CheckBlitter()
Check whether we still use the right blitter, or use another (better) one.
Definition: gfxinit.cpp:317
TimerGameConst< struct Calendar >::MAX_YEAR
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,...
Definition: timer_game_common.h:173
RM_BASIC
@ RM_BASIC
Display settings associated to the "basic" list.
Definition: settings_gui.cpp:1207
WWT_FRAME
@ WWT_FRAME
Frame.
Definition: widget_type.h:62
language.h
AddCustomRefreshRates
static void AddCustomRefreshRates()
Add the refresh rate from the config and the refresh rates from all the monitors to our list of refre...
Definition: settings_gui.cpp:134
WHR_CATEGORY
@ WHR_CATEGORY
Category setting filtered matches away.
Definition: settings_gui.cpp:2288
WID_CC_SUFFIX
@ WID_CC_SUFFIX
Current suffix.
Definition: settings_widget.h:90
SETTING_BUTTON_WIDTH
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
Definition: settings_gui.h:17
stdafx.h
DrawArrowButtons
void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clickable_left, bool clickable_right)
Draw [<][>] boxes.
Definition: settings_gui.cpp:2910
SettingFilter::type_hides
bool type_hides
Whether the type hides filtered strings.
Definition: settings_gui.cpp:1220
Window::SetFocusedWidget
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition: window.cpp:487
WID_GS_SETTING_DROPDOWN
@ WID_GS_SETTING_DROPDOWN
Dynamically created dropdown for changing setting value.
Definition: settings_widget.h:77
GfxFillRect
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:113
ShowCustCurrency
static void ShowCustCurrency()
Open custom currency window.
Definition: settings_gui.cpp:3202
WID_GO_BASE_GRF_PARAMETERS
@ WID_GO_BASE_GRF_PARAMETERS
Base GRF parameters.
Definition: settings_widget.h:32
IntSettingDesc::GetHelp
StringID GetHelp() const
Get the help text of the setting.
Definition: settings.cpp:466
TFT_README
@ TFT_README
Content readme.
Definition: textfile_type.h:17
LanguagePackHeader::own_name
char own_name[32]
the localized name of this language
Definition: language.h:30
SettingsContainer::Draw
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.
Definition: settings_gui.cpp:1763
CurrencySpec
Specification of a currency.
Definition: currency.h:74
WarnHiddenResult
WarnHiddenResult
Warnings about hidden search results.
Definition: settings_gui.cpp:2286
Window::InvalidateData
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition: window.cpp:3144
VideoDriver::GetInstance
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Definition: video_driver.hpp:200
CS_ALPHANUMERAL
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Definition: string_type.h:25
viewport_func.h
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:45
WHR_CATEGORY_TYPE
@ WHR_CATEGORY_TYPE
Both category and type settings filtered matches away.
Definition: settings_gui.cpp:2290
Window::SetWidgetLoweredState
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition: window_gui.h:441
SocialIntegrationPlugin::RUNNING
@ RUNNING
The plugin is successfully loaded and running.
Definition: social_integration.h:16
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition: widget_type.h:79
ShowBaseSetTextfileWindow
void ShowBaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, StringID content_type)
Open the BaseSet version of the textfile window.
Definition: settings_gui.cpp:122
WID_CC_RATE
@ WID_CC_RATE
Rate of currency.
Definition: settings_widget.h:84
WID_GO_RESOLUTION_DROPDOWN
@ WID_GO_RESOLUTION_DROPDOWN
Dropdown for the resolution.
Definition: settings_widget.h:24
Scrollbar::GetScrolledRowFromWidget
int 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:2267
WidgetDimensions::unscaled
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition: window_gui.h:67
Window::SetWidgetDisabledState
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:381
MakeNWidgets
std::unique_ptr< NWidgetBase > MakeNWidgets(const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, std::unique_ptr< NWidgetBase > &&container)
Construct a nested widget tree from an array of parts.
Definition: widget.cpp:3144
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:937
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition: widget_type.h:71
WWT_RESIZEBOX
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:70
BaseMedia< GraphicsSet >::GetNumSets
static int GetNumSets()
Count the number of available graphics sets.
Definition: base_media_func.h:348
string_func.h
SettingEntry::SetButtons
void SetButtons(byte new_val)
Set the button-depressed flags (SEF_LEFT_DEPRESSED and SEF_RIGHT_DEPRESSED) to a specified value.
Definition: settings_gui.cpp:1473
NWidgetSocialPlugins::GetWidestPlugin
std::string & GetWidestPlugin(T SocialIntegrationPlugin::*member) const
Find of all the plugins the one where the member is the widest (in pixels).
Definition: settings_gui.cpp:235
TFT_LICENSE
@ TFT_LICENSE
Content license.
Definition: textfile_type.h:19
_switch_mode
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:48
GameSettingsWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition: settings_gui.cpp:2838
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:111
WID_GO_VIDEO_VSYNC_BUTTON
@ WID_GO_VIDEO_VSYNC_BUTTON
Toggle for video vsync.
Definition: settings_widget.h:50
WID_GO_SURVEY_PARTICIPATE_BUTTON
@ WID_GO_SURVEY_PARTICIPATE_BUTTON
Toggle for participating in the automated survey.
Definition: settings_widget.h:54
Window::querystrings
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition: window_gui.h:314
QueryString::cancel_button
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
Definition: querystring_gui.h:28
DrawStringMultiLine
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:771
rev.h
WID_GO_GUI_FONT_AA
@ WID_GO_GUI_FONT_AA
Toggle whether to anti-alias fonts.
Definition: settings_widget.h:30
WC_GAME_OPTIONS
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition: window_type.h:619
SocialIntegrationPlugin::version
std::string version
Version of the plugin.
Definition: social_integration.h:30
Window::CreateNestedTree
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1724
strings_func.h
WID_GO_BASE_SFX_DROPDOWN
@ WID_GO_BASE_SFX_DROPDOWN
Use to select a base SFX.
Definition: settings_widget.h:36
NWID_VSCROLLBAR
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition: widget_type.h:86
IntSettingDesc::GetTitle
StringID GetTitle() const
Get the title of the setting.
Definition: settings.cpp:457
main
int CDECL main(int argc, char *argv[])
And the main program (what else?)
Definition: settingsgen.cpp:433
WID_GS_RESTRICT_TYPE
@ WID_GS_RESTRICT_TYPE
Label upfront to the type drop-down box to restrict the list of settings to show.
Definition: settings_widget.h:73
IntSettingDesc::interval
int32_t interval
the interval to use between settings in the 'settings' window. If interval is '0' the interval is dyn...
Definition: settings_internal.h:214
LocaleSettings::currency
byte currency
currency we currently use
Definition: settings_type.h:260
WidgetLookup
std::map< WidgetID, class NWidgetBase * > WidgetLookup
Lookup between widget IDs and NWidget objects.
Definition: widget_type.h:127
BaseSettingEntry::FindEntry
virtual BaseSettingEntry * FindEntry(uint row, uint *cur_row)
Find setting entry at row row_num.
Definition: settings_gui.cpp:1369
SettingsContainer::UnFoldAll
void UnFoldAll()
Recursively open all folds of sub-pages.
Definition: settings_gui.cpp:1654
Window::DisableWidget
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
Definition: window_gui.h:391
Window::CloseChildWindows
void CloseChildWindows(WindowClass wc=WC_INVALID) const
Close all children a window might have in a head-recursive manner.
Definition: window.cpp:1036
WWT_TEXT
@ WWT_TEXT
Pure simple text.
Definition: widget_type.h:60
SetPIP
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
Definition: widget_type.h:1222
WidgetDimensions::hsep_indent
int hsep_indent
Width of identation for tree layouts.
Definition: window_gui.h:65
SettingsContainer::IsVisible
bool IsVisible(const BaseSettingEntry *item) const
Check whether an entry is visible and not folded or filtered away.
Definition: settings_gui.cpp:1698
SettingsContainer::Length
uint Length() const
Return number of rows needed to display the whole page.
Definition: settings_gui.cpp:1707
video_driver.hpp
SetDParam
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings.cpp:104
RM_CHANGED_AGAINST_DEFAULT
@ RM_CHANGED_AGAINST_DEFAULT
Show only settings which are different compared to default values.
Definition: settings_gui.cpp:1210
SC_BASIC_LIST
@ SC_BASIC_LIST
Settings displayed in the list of basic settings.
Definition: settings_internal.h:45
GUISettings::autosave_interval
uint32_t autosave_interval
how often should we do autosaves?
Definition: settings_type.h:160
geometry_func.hpp
WID_GO_BASE_MUSIC_JUKEBOX
@ WID_GO_BASE_MUSIC_JUKEBOX
Open the jukebox.
Definition: settings_widget.h:45
ClickSliderWidget
bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value)
Handle click on a slider widget to change the value.
Definition: slider.cpp:80
IntSettingDesc::max
uint32_t max
maximum values
Definition: settings_internal.h:213
GameSettingsWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition: settings_gui.cpp:2395
UpdateAllVirtCoords
void UpdateAllVirtCoords()
Update the viewport coordinates of all signs.
Definition: afterload.cpp:222
StringFilter::ResetState
void ResetState()
Reset the matching state to process a new item.
Definition: stringfilter.cpp:98
IntSettingDesc::Read
int32_t Read(const void *object) const
Read the integer from the the actual setting.
Definition: settings.cpp:577
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition: widget_type.h:52
_video_hw_accel
bool _video_hw_accel
Whether to consider hardware accelerated video drivers on startup.
Definition: video_driver.cpp:25
WidgetDimensions::vsep_normal
int vsep_normal
Normal vertical spacing.
Definition: window_gui.h:60
NWidgetBase::resize_y
uint resize_y
Vertical resize step (0 means not resizable).
Definition: widget_type.h:226
WID_GS_RESET_ALL
@ WID_GS_RESET_ALL
Reset all button.
Definition: settings_widget.h:71
Scrollbar::SetCount
void SetCount(size_t num)
Sets the number of elements in the list.
Definition: widget_type.h:762
IntSettingDesc::IsBoolSetting
virtual bool IsBoolSetting() const
Check whether this setting is a boolean type setting.
Definition: settings_internal.h:233
NWidgetVertical
Vertical container.
Definition: widget_type.h:567
SettingsContainer::FindEntry
BaseSettingEntry * FindEntry(uint row, uint *cur_row)
Find the setting entry at row number row_num.
Definition: settings_gui.cpp:1722
Window::mouse_capture_widget
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:320
StringFilter::GetState
bool GetState() const
Get the matching state of the current item.
Definition: stringfilter_type.h:71
WID_CC_SUFFIX_EDIT
@ WID_CC_SUFFIX_EDIT
Suffix edit button.
Definition: settings_widget.h:89
WID_GO_TAB_SOCIAL
@ WID_GO_TAB_SOCIAL
Social tab.
Definition: settings_widget.h:18
SetDParamStr
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:352
SettingsPage::Draw
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 override
Draw a row in the settings panel.
Definition: settings_gui.cpp:1915
WID_CC_SEPARATOR_EDIT
@ WID_CC_SEPARATOR_EDIT
Separator edit button.
Definition: settings_widget.h:85
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1734
IntSettingDesc::SetValueDParams
void SetValueDParams(uint first_param, int32_t value) const
Set the DParams for drawing the value of the setting.
Definition: settings.cpp:476
WID_GO_GUI_SCALE_BEVEL_BUTTON
@ WID_GO_GUI_SCALE_BEVEL_BUTTON
Toggle for chunky bevels.
Definition: settings_widget.h:28
ShowDropDownList
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:369
company_func.h
WL_ERROR
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition: error.h:26
SocialIntegrationPlugin::UNSUPPORTED_API
@ UNSUPPORTED_API
The plugin does not support the current API version.
Definition: social_integration.h:22
SM_MENU
@ SM_MENU
Switch to game intro menu.
Definition: openttd.h:33
WID_GO_GUI_SCALE_AUTO
@ WID_GO_GUI_SCALE_AUTO
Autodetect GUI scale button.
Definition: settings_widget.h:27
GetCurrentResolutionIndex
static uint GetCurrentResolutionIndex()
Get index of the current screen resolution.
Definition: settings_gui.cpp:84
QueryString::ACTION_CLEAR
static const int ACTION_CLEAR
Clear editbox.
Definition: querystring_gui.h:24
CS_NUMERAL_SIGNED
@ CS_NUMERAL_SIGNED
Only numbers and '-' for negative values.
Definition: string_type.h:28
Window::SetWidgetsLoweredState
void SetWidgetsLoweredState(bool lowered_stat, Args... widgets)
Sets the lowered/raised status of a list of widgets.
Definition: window_gui.h:526
WID_GO_BASE_MUSIC_TEXTFILE
@ WID_GO_BASE_MUSIC_TEXTFILE
Open base music readme, changelog (+1) or license (+2).
Definition: settings_widget.h:47
SettingsPage::UnFoldAll
void UnFoldAll() override
Recursively open all (filtered) folds of sub-pages.
Definition: settings_gui.cpp:1812
DrawFrameRect
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition: widget.cpp:281
NWidgetSocialPlugins::Draw
void Draw(const Window *w) override
Definition: settings_gui.cpp:333
CF_NOEURO
static constexpr TimerGameCalendar::Year CF_NOEURO
Currency never switches to the Euro (as far as known).
Definition: currency.h:17
network.h
SettingsContainer::FoldAll
void FoldAll()
Recursively close all folds of sub-pages.
Definition: settings_gui.cpp:1646
SettingsPage::DrawSetting
void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const override
Function to draw setting value (button + text + current value)
Definition: settings_gui.cpp:1940
_video_vsync
bool _video_vsync
Whether we should use vsync (only if active video driver supports HW acceleration).
Definition: video_driver.cpp:26
window_func.h
CheckForMissingGlyphs
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:2271
SA_CENTER
@ SA_CENTER
Center both horizontally and vertically.
Definition: gfx_type.h:348
SocialIntegrationPlugin::PLATFORM_NOT_RUNNING
@ PLATFORM_NOT_RUNNING
The plugin failed to initialize because the Social Platform is not running.
Definition: social_integration.h:19
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition: fontcache.cpp:78
GameSettingsWindow::filter
SettingFilter filter
Filter for the list.
Definition: settings_gui.cpp:2317
BaseMedia< GraphicsSet >::GetSet
static const GraphicsSet * GetSet(int index)
Get the name of the graphics set at the specified index.
Definition: base_media_func.h:379
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: stdafx.h:300
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:305
MusicSettings::effect_vol
byte effect_vol
The requested effects volume.
Definition: settings_type.h:251
stringfilter_type.h
WID_CC_PREFIX
@ WID_CC_PREFIX
Current prefix.
Definition: settings_widget.h:88
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition: widget_type.h:1099
MarkWholeScreenDirty
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition: gfx.cpp:1548
SetPIPRatio
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.
Definition: widget_type.h:1234
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:636
GRFConfig::num_params
uint8_t num_params
Number of used parameters.
Definition: newgrf_config.h:168
GameSettings::locale
LocaleSettings locale
settings related to used currency/unit system in the current game
Definition: settings_type.h:630
SocialIntegrationPlugin::social_platform
std::string social_platform
Social platform this plugin is for.
Definition: social_integration.h:28
NWidgetBase::pos_y
int pos_y
Vertical position of top-left corner of the widget in the window.
Definition: widget_type.h:237
config.h
BaseSettingEntry::IsVisible
virtual bool IsVisible(const BaseSettingEntry *item) const
Check whether an entry is visible and not folded or filtered away.
Definition: settings_gui.cpp:1357
DrawString
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:654
SettingEntry::SettingEntry
SettingEntry(const char *name)
Constructor for a single setting in the 'advanced settings' window.
Definition: settings_gui.cpp:1446
SettingFilter
Filter for settings list.
Definition: settings_gui.cpp:1217
fontcache.h
RM_CHANGED_AGAINST_NEW
@ RM_CHANGED_AGAINST_NEW
Show only settings which are different compared to the user's new game setting values.
Definition: settings_gui.cpp:1211
TextfileWindow
Window for displaying a textfile.
Definition: textfile_gui.h:21
WidgetDimensions::bevel
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition: window_gui.h:40
GetSettingsTree
static SettingsContainer & GetSettingsTree()
Construct settings tree.
Definition: settings_gui.cpp:1948
gui.h
ST_ALL
@ ST_ALL
Used in setting filter to match all types.
Definition: settings_internal.h:65
GetGameSettings
GameSettings & GetGameSettings()
Get the settings-object applicable for the current situation: the newgame settings when we're in the ...
Definition: settings_type.h:659
WID_GS_HELP_TEXT
@ WID_GS_HELP_TEXT
Information area to display help text of the selected option.
Definition: settings_widget.h:68
ClientSettings::company
CompanySettings company
default values for per-company settings
Definition: settings_type.h:637
WidgetDimensions::frametext
RectPadding frametext
Padding inside frame with text.
Definition: window_gui.h:43
SettingsContainer
Containers for BaseSettingEntry.
Definition: settings_gui.cpp:1287
GameSettingsWindow::closing_dropdown
bool closing_dropdown
True, if the dropdown list is currently closing.
Definition: settings_gui.cpp:2315
BaseSettingEntry::flags
byte flags
Flags of the setting entry.
Definition: settings_gui.cpp:1227
Window
Data structure for an opened window.
Definition: window_gui.h:267
TextfileType
TextfileType
Additional text files accompanying Tar archives.
Definition: textfile_type.h:14
BaseSounds::ini_set
static std::string ini_set
The set as saved in the config file.
Definition: base_media_base.h:301
SC_ADVANCED_LIST
@ SC_ADVANCED_LIST
Settings displayed in the list of advanced settings.
Definition: settings_internal.h:46
GameOptionsWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition: settings_gui.cpp:601
SettingEntry
Standard setting.
Definition: settings_gui.cpp:1265
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:328
BaseMedia< GraphicsSet >::GetUsedSet
static const GraphicsSet * GetUsedSet()
Return the used set.
Definition: base_media_func.h:394
Window::DrawWidgets
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:731
SF_GUI_DROPDOWN
@ SF_GUI_DROPDOWN
The value represents a limited number of string-options (internally integer) presented as dropdown.
Definition: settings_internal.h:19
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:79
network_survey.h
ShowGameSettings
void ShowGameSettings()
Open advanced settings window.
Definition: settings_gui.cpp:2894
GetDropDownListDimension
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
Definition: dropdown.cpp:328
WID_CC_PREFIX_EDIT
@ WID_CC_PREFIX_EDIT
Prefix edit button.
Definition: settings_widget.h:87
DrawBoolButton
void DrawBoolButton(int x, int y, bool state, bool clickable)
Draw a toggle button.
Definition: settings_gui.cpp:2962
SetDataTip
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1164
settings_gui.h
SetMinimalTextLines
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition: widget_type.h:1111
Rect::Width
int Width() const
Get width of Rect.
Definition: geometry_type.hpp:85
NWID_SELECTION
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition: widget_type.h:82
GUISettings::scale_bevels
bool scale_bevels
bevels are scaled with GUI scale.
Definition: settings_type.h:223
SF_PER_COMPANY
@ SF_PER_COMPANY
This setting can be different for each company (saved in company struct).
Definition: settings_internal.h:26
_languages
LanguageList _languages
The actual list of language meta data.
Definition: strings.cpp:53
GameOptionsWindow::BuildDropDownList
DropDownList BuildDropDownList(WidgetID widget, int *selected_index) const
Build the dropdown list for a specific widget.
Definition: settings_gui.cpp:390
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:75
GameSettingsWindow::manually_changed_folding
bool manually_changed_folding
Whether the user expanded/collapsed something manually.
Definition: settings_gui.cpp:2319
FontCacheSettings::global_aa
bool global_aa
Whether to anti alias all font sizes.
Definition: fontcache.h:222
WID_CC_YEAR_UP
@ WID_CC_YEAR_UP
Up button.
Definition: settings_widget.h:92
WC_DROPDOWN_MENU
@ WC_DROPDOWN_MENU
Drop down menu; Window numbers:
Definition: window_type.h:156
BaseSettingEntry::Draw
virtual 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.
Definition: settings_gui.cpp:1406
GameSettingsWindow::SetDisplayedHelpText
void SetDisplayedHelpText(SettingEntry *pe)
Set the entry that should have its help text displayed, and mark the window dirty so it gets repainte...
Definition: settings_gui.cpp:2514
WID_GO_BASE_GRF_DROPDOWN
@ WID_GO_BASE_GRF_DROPDOWN
Use to select a base GRF.
Definition: settings_widget.h:31
SettingEntry::Length
uint Length() const override
Return number of rows needed to display the (filtered) entry.
Definition: settings_gui.cpp:1480
AWV_INCREASE
@ AWV_INCREASE
Arrow to the right or in case of RTL to the left.
Definition: widget_type.h:34
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3112
WID_GO_BASE_SFX_TEXTFILE
@ WID_GO_BASE_SFX_TEXTFILE
Open base SFX readme, changelog (+1) or license (+2).
Definition: settings_widget.h:40
QSF_ENABLE_DEFAULT
@ QSF_ENABLE_DEFAULT
enable the 'Default' button ("\0" is returned)
Definition: textbuf_gui.h:21
ClientSettings::music
MusicSettings music
settings related to music/sound
Definition: settings_type.h:639
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition: bitmath_func.hpp:166
NWidgetBase::current_x
uint current_x
Current horizontal size (after resizing).
Definition: widget_type.h:233
WC_TEXTFILE
@ WC_TEXTFILE
textfile; Window numbers:
Definition: window_type.h:187
WHR_NONE
@ WHR_NONE
Nothing was filtering matches away.
Definition: settings_gui.cpp:2287
WidgetDimensions::framerect
RectPadding framerect
Standard padding inside many panels.
Definition: window_gui.h:42
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition: window_gui.h:63
SettingsContainer::GetFoldingState
void GetFoldingState(bool &all_folded, bool &all_unfolded) const
Recursively accumulate the folding state of the tree.
Definition: settings_gui.cpp:1666
WDP_CENTER
@ WDP_CENTER
Center the window.
Definition: window_gui.h:142
ChangeMusicSet
void ChangeMusicSet(int index)
Change the configured music set and reset playback.
Definition: music_gui.cpp:463
SETTING_BUTTON_HEIGHT
#define SETTING_BUTTON_HEIGHT
Height of setting buttons.
Definition: settings_gui.h:19
GameSettingsWindow::clicked_entry
SettingEntry * clicked_entry
If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button).
Definition: settings_gui.cpp:2312
ReadLanguagePack
bool ReadLanguagePack(const LanguageMetadata *lang)
Read a particular language.
Definition: strings.cpp:1910
MusicSettings::music_vol
byte music_vol
The requested music volume.
Definition: settings_type.h:250
_left_button_clicked
bool _left_button_clicked
Is left mouse button clicked?
Definition: gfx.cpp:41
WID_GO_TAB_SOUND
@ WID_GO_TAB_SOUND
Sound tab.
Definition: settings_widget.h:17
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition: strings_type.h:24
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:56
_circle_size
static Dimension _circle_size
Dimension of the circle +/- icon. This is here as not all users are within the class of the settings ...
Definition: settings_gui.cpp:76
CS_NUMERAL
@ CS_NUMERAL
Only numeric ones.
Definition: string_type.h:26
CharSetFilter
CharSetFilter
Valid filter types for IsValidChar.
Definition: string_type.h:24
SetupWidgetDimensions
void SetupWidgetDimensions()
Set up pre-scaled versions of Widget Dimensions.
Definition: widget.cpp:66
SocialIntegration::GetPlugins
static std::vector< SocialIntegrationPlugin * > GetPlugins()
Get the list of loaded social integration plugins.
Definition: social_integration.cpp:149
_currency_specs
CurrencySpec _currency_specs[CURRENCY_END]
Array of currencies used by the system.
Definition: currency.cpp:76
WID_GO_BASE_MUSIC_OPEN_URL
@ WID_GO_BASE_MUSIC_OPEN_URL
Open base music URL.
Definition: settings_widget.h:46
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:848
StringFilter
String filter and state.
Definition: stringfilter_type.h:30
WID_CC_SEPARATOR
@ WID_CC_SEPARATOR
Current separator.
Definition: settings_widget.h:86
CURRENCY_CUSTOM
@ CURRENCY_CUSTOM
Custom currency.
Definition: currency.h:58
_settings_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition: settings.cpp:56
WWT_TEXTBTN
@ WWT_TEXTBTN
(Toggle) Button with text
Definition: widget_type.h:57
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:17
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:635
mixer.h
AWV_DECREASE
@ AWV_DECREASE
Arrow to the left or in case of RTL to the right.
Definition: widget_type.h:33
WWT_DROPDOWN
@ WWT_DROPDOWN
Drop down list.
Definition: widget_type.h:72
SettingDesc::AsIntSetting
const struct IntSettingDesc * AsIntSetting() const
Get the setting description of this setting as an integer setting.
Definition: settings.cpp:926
WID_GO_SURVEY_LINK_BUTTON
@ WID_GO_SURVEY_LINK_BUTTON
Button to open browser to go to the survey website.
Definition: settings_widget.h:55
SettingEntry::GetMaxHelpHeight
uint GetMaxHelpHeight(int maxw) override
Get the biggest height of the help text(s), if the width is at least maxw.
Definition: settings_gui.cpp:1490
BaseSettingEntry::IsFiltered
bool IsFiltered() const
Check whether an entry is hidden due to filters.
Definition: settings_gui.cpp:1254
NetworkSettings::participate_survey
ParticipateSurvey participate_survey
Participate in the automated survey.
Definition: settings_type.h:334
RM_ADVANCED
@ RM_ADVANCED
Display settings associated to the "advanced" list.
Definition: settings_gui.cpp:1208
WN_GAME_OPTIONS_GAME_SETTINGS
@ WN_GAME_OPTIONS_GAME_SETTINGS
Game settings.
Definition: window_type.h:27
ShowGameOptions
void ShowGameOptions()
Open the game options window.
Definition: settings_gui.cpp:1184
SettingEntryFlags
SettingEntryFlags
Flags for SettingEntry.
Definition: settings_gui.cpp:1196
WID_GO_REFRESH_RATE_DROPDOWN
@ WID_GO_REFRESH_RATE_DROPDOWN
Dropdown for all available refresh rates.
Definition: settings_widget.h:51
GUISettings::settings_restriction_mode
uint8_t settings_restriction_mode
selected restriction mode in adv. settings GUI.
Definition: settings_type.h:219
HasBit
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103